From: Tilghman Lesher Date: Mon, 11 Dec 2006 00:52:19 +0000 (+0000) Subject: Merged revisions 48375 via svnmerge from X-Git-Tag: 1.6.0-beta1~3^2~3760 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d670858735fce93f57eb72d3b8a0bba923015d31;p=thirdparty%2Fasterisk.git Merged revisions 48375 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ................ r48375 | tilghman | 2006-12-10 18:47:21 -0600 (Sun, 10 Dec 2006) | 13 lines Merged revisions 48374 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r48374 | tilghman | 2006-12-10 18:33:59 -0600 (Sun, 10 Dec 2006) | 5 lines When doing a fork() and exec(), two problems existed (Issue 8086): 1) Ignored signals stayed ignored after the exec(). 2) Signals could possibly fire between the fork() and exec(), causing Asterisk signal handlers within the child to execute, which caused nasty race conditions. ........ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@48376 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/apps/app_externalivr.c b/apps/app_externalivr.c index f9b8905884..bcda8d6634 100644 --- a/apps/app_externalivr.c +++ b/apps/app_externalivr.c @@ -40,6 +40,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include #include #include +#include #include "asterisk/lock.h" #include "asterisk/file.h" @@ -262,9 +263,13 @@ static int app_exec(struct ast_channel *chan, void *data) .finishlist = AST_LIST_HEAD_INIT_VALUE, }; struct ivr_localuser *u = &foo; + sigset_t fullset, oldset; lu = ast_module_user_add(chan); - + + sigfillset(&fullset); + pthread_sigmask(SIG_BLOCK, &fullset, &oldset); + u->abort_current_sound = 0; u->chan = chan; @@ -313,6 +318,9 @@ static int app_exec(struct ast_channel *chan, void *data) /* child process */ int i; + signal(SIGPIPE, SIG_DFL); + pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); + if (ast_opt_high_priority) ast_set_priority(0); @@ -336,6 +344,8 @@ static int app_exec(struct ast_channel *chan, void *data) int waitfds[2] = { child_errors_fd, child_commands_fd }; struct ast_channel *rchan; + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + close(child_stdin[0]); child_stdin[0] = 0; close(child_stdout[1]); diff --git a/apps/app_festival.c b/apps/app_festival.c index e024598738..7af2e78a6a 100644 --- a/apps/app_festival.c +++ b/apps/app_festival.c @@ -130,19 +130,26 @@ static int send_waveform_to_fd(char *waveform, int length, int fd) { #ifdef __PPC__ char c; #endif + sigset_t fullset, oldset; + + sigfillset(&fullset); + pthread_sigmask(SIG_BLOCK, &fullset, &oldset); res = fork(); if (res < 0) ast_log(LOG_WARNING, "Fork failed\n"); - if (res) + if (res) { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); return res; + } for (x=0;x<256;x++) { if (x != fd) close(x); } if (ast_opt_high_priority) ast_set_priority(0); - + signal(SIGPIPE, SIG_DFL); + pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); /*IAS */ #ifdef __PPC__ for( x=0; xfds[0], STDIN_FILENO); @@ -99,10 +111,6 @@ static pid_t spawn_ras(struct ast_channel *chan, char *args) for (x=STDERR_FILENO + 1;x<1024;x++) close(x); - /* Restore original signal handlers */ - for (x=0;x 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[]) diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index f560432bb5..96e24a4a7d 100644 --- a/res/res_musiconhold.c +++ b/res/res_musiconhold.c @@ -340,6 +340,7 @@ static int spawn_mp3(struct mohclass *class) int argc = 0; DIR *dir = NULL; struct dirent *de; + sigset_t signal_set, old_set; if (!strcasecmp(class->dir, "nodir")) { @@ -424,6 +425,11 @@ static int spawn_mp3(struct mohclass *class) if (time(NULL) - class->start < respawn_time) { sleep(respawn_time - (time(NULL) - class->start)); } + + /* Block signals during the fork() */ + sigfillset(&signal_set); + pthread_sigmask(SIG_BLOCK, &signal_set, &old_set); + time(&class->start); class->pid = fork(); if (class->pid < 0) { @@ -438,6 +444,10 @@ static int spawn_mp3(struct mohclass *class) if (ast_opt_high_priority) ast_set_priority(0); + /* Reset ignored signals back to default */ + signal(SIGPIPE, SIG_DFL); + pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL); + close(fds[0]); /* Stdout goes to pipe */ dup2(fds[1], STDOUT_FILENO); @@ -464,6 +474,7 @@ static int spawn_mp3(struct mohclass *class) _exit(1); } else { /* Parent */ + pthread_sigmask(SIG_SETMASK, &old_set, NULL); close(fds[1]); } return fds[0];