Fix background task execution.

This commit is contained in:
Jari Sundell
2026-07-03 10:53:00 +02:00
committed by GitHub
parent 23921cc97c
commit 786f1234d2
4 changed files with 53 additions and 22 deletions
+33 -22
View File
@@ -38,24 +38,10 @@ ExecFile::execute(const char* file, char* const* argv, int flags) {
result = write(m_log_fd, "\n---\n", sizeof("\n---\n"));
}
int pipe_fd[2];
if ((flags & flag_capture) && pipe(pipe_fd))
throw torrent::input_error("ExecFile::execute(...) Pipe creation failed.");
auto clean_fn = [pipe_fd, flags]() {
if (flags & flag_capture) {
::close(pipe_fd[0]);
::close(pipe_fd[1]);
}
};
posix_spawn_file_actions_t actions{};
if (posix_spawn_file_actions_init(&actions) != 0) {
clean_fn();
if (posix_spawn_file_actions_init(&actions) != 0)
throw torrent::internal_error("ExecFile::execute(...) posix_spawn_file_actions_init failed.");
}
// Handle standard input redirection (/dev/null), posix_spawn_file_actions_addopen handles opening
// and dup2 natively
@@ -64,6 +50,11 @@ ExecFile::execute(const char* file, char* const* argv, int flags) {
posix_spawn_file_actions_addclose(&actions, 0);
}
int pipe_fd[2] = {-1, -1};
if ((flags & flag_capture) && pipe(pipe_fd))
throw torrent::input_error("ExecFile::execute(...) Pipe creation failed.");
// Handle standard output redirection
if (flags & flag_capture) {
posix_spawn_file_actions_adddup2(&actions, pipe_fd[1], 1);
@@ -88,23 +79,36 @@ ExecFile::execute(const char* file, char* const* argv, int flags) {
posix_spawnattr_t attr;
posix_spawnattr_init(&attr);
// If you are using standard close-on-exec (O_CLOEXEC) across rtorrent, posix_spawn honors it
// automatically. If you want to explicitly enforce a clean slate, modern systems support
// POSIX_SPAWN_CLOEXEC_DEFAULT.
short spawn_flags = 0;
#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT);
spawn_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
#endif
pid_t child_pid{};
if (flags & flag_background) {
#ifdef POSIX_SPAWN_SETSID
spawn_flags |= POSIX_SPAWN_SETSID;
#else
spawn_flags |= POSIX_SPAWN_SETPGROUP;
posix_spawnattr_setpgroup(&attr, 0);
#endif
}
int spawn_status = posix_spawnp(&child_pid, file, &actions, &attr, argv, environ);
posix_spawnattr_setflags(&attr, spawn_flags);
pid_t child_pid{};
int spawn_status = posix_spawnp(&child_pid, file, &actions, &attr, argv, environ);
posix_spawn_file_actions_destroy(&actions);
posix_spawnattr_destroy(&attr);
if (spawn_status != 0) {
clean_fn();
if (pipe_fd[0] != -1)
::close(pipe_fd[0]);
if (pipe_fd[1] != -1)
::close(pipe_fd[1]);
throw torrent::input_error("ExecFile::execute(...) posix_spawn failed: " + std::string(std::strerror(spawn_status)));
}
@@ -131,6 +135,13 @@ ExecFile::execute(const char* file, char* const* argv, int flags) {
}
}
if (flags & flag_background) {
if (m_log_fd != -1)
result = write(m_log_fd, "\n--- Running in Background ---\n", sizeof("\n--- Running in Background ---\n"));
return 0;
}
int status;
while (waitpid(child_pid, &status, 0) == -1) {