From 9884c9dd9bcec7008676f0590050b194dcff5d6d Mon Sep 17 00:00:00 2001 From: fffe Date: Fri, 3 Jul 2026 04:52:26 -0700 Subject: [PATCH] Add support for posix_spawn_file_actions_addclosefrom_np by @fffe --- configure.ac | 1 + scripts/checks.m4 | 18 ++++++++++++++++++ src/rpc/exec_file.cc | 25 ++++++++++++++++--------- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 100e2bea..4419c083 100644 --- a/configure.ac +++ b/configure.ac @@ -73,6 +73,7 @@ CFLAGS="$CFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS $ZLIB_CFLAGS $DEPENDENCIES_CFLAGS CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS $ZLIB_CFLAGS $DEPENDENCIES_CFLAGS" TORRENT_CHECK_CACHELINE +TORRENT_CHECK_POSIX_SPAWN_ADDCLOSEFROM_NP AC_CONFIG_FILES([ Makefile diff --git a/scripts/checks.m4 b/scripts/checks.m4 index c3ff3af7..c46f72ac 100644 --- a/scripts/checks.m4 +++ b/scripts/checks.m4 @@ -298,6 +298,24 @@ AC_DEFUN([TORRENT_DISABLE_PTHREAD_SETNAME_NP], [ ]) +AC_DEFUN([TORRENT_CHECK_POSIX_SPAWN_ADDCLOSEFROM_NP], [ + AC_MSG_CHECKING(for posix_spawn_file_actions_addclosefrom_np) + + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #define _GNU_SOURCE + #include + ]], [[ + posix_spawn_file_actions_t actions; + posix_spawn_file_actions_addclosefrom_np(&actions, 3); + ]])],[ + AC_DEFINE(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP, 1, [Define if posix_spawn_file_actions_addclosefrom_np is available.]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + ]) +]) + + AC_DEFUN([TORRENT_WITH_SYSTEMD], [ AC_ARG_WITH(systemd, AS_HELP_STRING([--with-systemd],[enable systemd socket activation support [[default=no]]]), diff --git a/src/rpc/exec_file.cc b/src/rpc/exec_file.cc index f6fce9da..1a4e053e 100644 --- a/src/rpc/exec_file.cc +++ b/src/rpc/exec_file.cc @@ -43,6 +43,22 @@ ExecFile::execute(const char* file, char* const* argv, int flags) { if (posix_spawn_file_actions_init(&actions) != 0) throw torrent::internal_error("ExecFile::execute(...) posix_spawn_file_actions_init failed."); + posix_spawnattr_t attr; + posix_spawnattr_init(&attr); + + short spawn_flags = 0; + + // Try to avoid leaking open fds to the spawned process. Prefer POSIX_SPAWN_CLOEXEC_DEFAULT + // (macOS-only) or posix_spawn_file_actions_addclosefrom_np (glibc >= 2.34, FreeBSD >= 13.1). + // + // Other platforms like musl libc, OpenBSD and NetBSD must rely on explicit O_CLOEXEC. + +#if defined(POSIX_SPAWN_CLOEXEC_DEFAULT) + spawn_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; +#elif defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP) + posix_spawn_file_actions_addclosefrom_np(&actions, 3); +#endif + // Handle standard input redirection (/dev/null), posix_spawn_file_actions_addopen handles opening // and dup2 natively if (posix_spawn_file_actions_addopen(&actions, 0, "/dev/null", O_RDWR, 0) != 0) { @@ -76,15 +92,6 @@ ExecFile::execute(const char* file, char* const* argv, int flags) { posix_spawn_file_actions_addopen(&actions, 2, "/dev/null", O_RDWR, 0); } - posix_spawnattr_t attr; - posix_spawnattr_init(&attr); - - short spawn_flags = 0; - -#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT - spawn_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; -#endif - if (flags & flag_background) { #ifdef POSIX_SPAWN_SETSID spawn_flags |= POSIX_SPAWN_SETSID;