diff options
Diffstat (limited to 'res/res_agi.c')
-rw-r--r-- | res/res_agi.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/res/res_agi.c b/res/res_agi.c index ecac92282..a8417587f 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -240,7 +240,7 @@ static enum agi_result launch_script(char *script, char *argv[], int *fds, int * int audio[2]; int x; int res; - sigset_t signal_set; + sigset_t signal_set, old_set; if (!strncasecmp(script, "agi://", 6)) return launch_netscript(script, argv, fds, efd, opid); @@ -282,11 +282,14 @@ static enum agi_result launch_script(char *script, char *argv[], int *fds, int * return AGI_RESULT_FAILURE; } } - ast_replace_sigchld(); + + /* Block SIGHUP during the fork - prevents a race */ + sigfillset(&signal_set); + pthread_sigmask(SIG_BLOCK, &signal_set, &old_set); pid = fork(); if (pid < 0) { ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); - ast_unreplace_sigchld(); + pthread_sigmask(SIG_SETMASK, &old_set, NULL); return AGI_RESULT_FAILURE; } if (!pid) { @@ -314,9 +317,18 @@ static enum agi_result launch_script(char *script, char *argv[], int *fds, int * } else { close(STDERR_FILENO + 1); } - + + /* Before we unblock our signals, return our trapped signals back to the defaults */ + signal(SIGHUP, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGURG, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + signal(SIGXFSZ, SIG_DFL); + /* unblock important signal handlers */ - if (sigfillset(&signal_set) || pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) { + if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) { ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno)); _exit(1); } @@ -332,6 +344,7 @@ static enum agi_result launch_script(char *script, char *argv[], int *fds, int * fflush(stdout); _exit(1); } + pthread_sigmask(SIG_SETMASK, &old_set, NULL); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script); fds[0] = toast[0]; @@ -348,7 +361,6 @@ static enum agi_result launch_script(char *script, char *argv[], int *fds, int * *opid = pid; return AGI_RESULT_SUCCESS; - } static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced) |