diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2014-12-02 18:59:39 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2014-12-02 18:59:39 +0000 |
| commit | 8208e75294b4eb016ae578f9ae132d9f8dfe4785 (patch) | |
| tree | 101c54315245a6f33d660d320edb75a191b584d3 /src/shell_manager.cc | |
| parent | 798d4c3a1eba4c2ff28729aba2b42afd88847535 (diff) | |
Handle SIGCHLD signals when piping
Diffstat (limited to 'src/shell_manager.cc')
| -rw-r--r-- | src/shell_manager.cc | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/src/shell_manager.cc b/src/shell_manager.cc index ef12f50d..0391dc4f 100644 --- a/src/shell_manager.cc +++ b/src/shell_manager.cc @@ -50,6 +50,10 @@ String ShellManager::pipe(StringView input, ::pipe(read_pipe); ::pipe(error_pipe); + static sig_atomic_t exited; exited = 0; + static sig_atomic_t sig_exit_status; + signal(SIGCHLD, [](int) { wait(&sig_exit_status); exited = 1; }); + String output; if (pid_t pid = fork()) { @@ -89,7 +93,13 @@ String ShellManager::pipe(StringView input, if (not error.empty()) write_debug("shell stderr: <<<\n" + error + ">>>"); - waitpid(pid, exit_status, 0); + signal(SIGCHLD, SIG_DFL); + + if (not exited) + waitpid(pid, exit_status, 0); + else if (exit_status) + *exit_status = sig_exit_status; + if (exit_status) { if (WIFEXITED(*exit_status)) |
