diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2014-05-23 02:37:02 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2014-05-23 02:37:02 +0200 |
commit | 47a34ece26a093102675e0a2dfc42c8182b98257 (patch) | |
tree | c368e9227ea5a79d5b66c50fff991c5886a168bb /src/shell.c | |
parent | 6b72d65ebb3ed508cdd24ab4c89bd76492dc1ad8 (diff) | |
download | fastd-47a34ece26a093102675e0a2dfc42c8182b98257.tar fastd-47a34ece26a093102675e0a2dfc42c8182b98257.zip |
Revert "Fix waitpid race condition"
This reverts commit 47d84679d6fe71f56d3a013578007dff92ff72db.
Diffstat (limited to 'src/shell.c')
-rw-r--r-- | src/shell.c | 57 |
1 files changed, 22 insertions, 35 deletions
diff --git a/src/shell.c b/src/shell.c index 8542bf9..9d03fbc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -29,7 +29,6 @@ #include <net/if.h> #include <sys/wait.h> -#include <pthread.h> typedef struct shell_env_entry { @@ -104,15 +103,18 @@ static void shell_command_setenv(pid_t pid, const fastd_shell_env_t *env) { } } -static bool shell_command_do_exec(const fastd_shell_command_t *command, const fastd_shell_env_t *env, pid_t *pid) { +static bool shell_command_do_exec(const fastd_shell_command_t *command, const fastd_shell_env_t *env, pid_t *pid_ret) { pid_t parent = getpid(); - *pid = fork(); - if (*pid < 0) { + pid_t pid = fork(); + if (pid < 0) { pr_error_errno("shell_command_do_exec: fork"); return false; } - else if (*pid > 0) { + else if (pid > 0) { + if (pid_ret) + *pid_ret = pid; + return true; } @@ -125,6 +127,12 @@ static bool shell_command_do_exec(const fastd_shell_command_t *command, const fa shell_command_setenv(parent, env); + /* unblock SIGCHLD */ + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + pthread_sigmask(SIG_UNBLOCK, &set, NULL); + execl("/bin/sh", "sh", "-c", command->command, (char*)NULL); _exit(127); } @@ -133,6 +141,12 @@ bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const f if (!fastd_shell_command_isset(command)) return true; + /* block SIGCHLD */ + sigset_t set, oldset; + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + pthread_sigmask(SIG_BLOCK, &set, &oldset); + pid_t pid; if (!shell_command_do_exec(command, env, &pid)) return false; @@ -140,6 +154,8 @@ bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const f int status; pid_t err = waitpid(pid, &status, 0); + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + if (err <= 0) { pr_error_errno("fastd_shell_command_exec_sync: waitpid"); return false; @@ -158,35 +174,6 @@ bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const f return true; } -static void * reap_child(void *arg) { - pid_t *pid = arg; - - pid_t err = waitpid(*pid, NULL, 0); - - pr_debug("child process %u finished", (unsigned)*pid); - - if (err <= 0) - pr_error_errno("reap_child: waitpid"); - - free(pid); - - return NULL; -} - -static void shell_command_exec_async(const fastd_shell_command_t *command, const fastd_shell_env_t *env) { - pid_t *pid = malloc(sizeof(*pid)); - if (!shell_command_do_exec(command, env, pid)) - return; - - pthread_t thread; - if ((errno = pthread_create(&thread, NULL, reap_child, pid)) != 0) { - pr_error_errno("unable to create reaper thread"); - free(pid); - return; - } - - pthread_detach(thread); -} void fastd_shell_command_exec(const fastd_shell_command_t *command, const fastd_shell_env_t *env) { if (!fastd_shell_command_isset(command)) @@ -195,5 +182,5 @@ void fastd_shell_command_exec(const fastd_shell_command_t *command, const fastd_ if (command->sync) fastd_shell_command_exec_sync(command, env, NULL); else - shell_command_exec_async(command, env); + shell_command_do_exec(command, env, NULL); } |