Merged revisions 48375 via svnmerge from
[asterisk/asterisk.git] / res / res_agi.c
index b4d6170..042fdbf 100644 (file)
@@ -241,7 +241,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);
@@ -283,11 +283,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) {
@@ -315,9 +318,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);
                }
@@ -334,6 +346,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];
@@ -350,7 +363,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, int argc, char *argv[])