diff --git a/apps/app_externalivr.c b/apps/app_externalivr.c index f9b8905884c130721b280de3b4f6394a91495a4c..bcda8d6634651f0dcae6b9717e5d4755f0c80677 100644 --- a/apps/app_externalivr.c +++ b/apps/app_externalivr.c @@ -40,6 +40,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include <string.h> #include <unistd.h> #include <errno.h> +#include <signal.h> #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 e0245987387820b2321ef0402f538fa6353d51c0..7af2e78a6a1b7a389ae8da723ffba38319967eaa 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; x<length; x+=2) diff --git a/apps/app_ices.c b/apps/app_ices.c index 869254738fc594edac5d9466fdd8906b4d18984d..91725fdc6b26eaf0b839a2b1eb08e5b049e3907e 100644 --- a/apps/app_ices.c +++ b/apps/app_ices.c @@ -65,15 +65,27 @@ static int icesencode(char *filename, int fd) { int res; int x; + 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; + } + + /* Stop ignoring PIPE */ + signal(SIGPIPE, SIG_DFL); + pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); + if (ast_opt_high_priority) ast_set_priority(0); dup2(fd, STDIN_FILENO); - for (x=STDERR_FILENO + 1;x<256;x++) { + for (x=STDERR_FILENO + 1;x<1024;x++) { if ((x != STDIN_FILENO) && (x != STDOUT_FILENO)) close(x); } @@ -84,7 +96,7 @@ static int icesencode(char *filename, int fd) /* As a last-ditch effort, try to use PATH */ execlp("ices", "ices", filename, (char *)NULL); ast_log(LOG_WARNING, "Execute of ices failed\n"); - return -1; + _exit(0); } static int ices_exec(struct ast_channel *chan, void *data) diff --git a/apps/app_mp3.c b/apps/app_mp3.c index 704666d8f6da141472ddd2404aca41184b1f8a86..e0df37d61ebf944149e2ac450992d0365e9d31f7 100644 --- a/apps/app_mp3.c +++ b/apps/app_mp3.c @@ -64,15 +64,25 @@ static int mp3play(char *filename, int fd) { int res; int x; + 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; + } if (ast_opt_high_priority) ast_set_priority(0); + signal(SIGPIPE, SIG_DFL); + pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); + dup2(fd, STDOUT_FILENO); - for (x=0;x<256;x++) { + for (x=STDERR_FILENO + 1;x<256;x++) { if (x != STDOUT_FILENO) close(x); } @@ -94,7 +104,7 @@ static int mp3play(char *filename, int fd) execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); } ast_log(LOG_WARNING, "Execute of mpg123 failed\n"); - return -1; + _exit(0); } static int timed_read(int fd, void *data, int datalen, int timeout) diff --git a/apps/app_nbscat.c b/apps/app_nbscat.c index 60623cc9370597ae814226d04c81a948f15640af..1fb51e688ad448ac27552ef8ba654e7b208be6c6 100644 --- a/apps/app_nbscat.c +++ b/apps/app_nbscat.c @@ -68,16 +68,26 @@ static int NBScatplay(int fd) { int res; int x; + 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; + } + signal(SIGPIPE, SIG_DFL); + pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); + if (ast_opt_high_priority) ast_set_priority(0); dup2(fd, STDOUT_FILENO); - for (x=0;x<256;x++) { + for (x = STDERR_FILENO + 1; x < 1024; x++) { if (x != STDOUT_FILENO) close(x); } @@ -85,7 +95,7 @@ static int NBScatplay(int fd) execl(NBSCAT, "nbscat8k", "-d", (char *)NULL); execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL); ast_log(LOG_WARNING, "Execute of nbscat8k failed\n"); - return -1; + _exit(0); } static int timed_read(int fd, void *data, int datalen) diff --git a/apps/app_zapras.c b/apps/app_zapras.c index 9e841603c4275b7ff8bf85550879e5d908fc28a0..7b85f70402ed4eecfedf25c7d583358dd2406458 100644 --- a/apps/app_zapras.c +++ b/apps/app_zapras.c @@ -82,11 +82,23 @@ static pid_t spawn_ras(struct ast_channel *chan, char *args) char *argv[PPP_MAX_ARGS]; int argc = 0; char *stringp=NULL; + sigset_t fullset, oldset; + + sigfillset(&fullset); + pthread_sigmask(SIG_BLOCK, &fullset, &oldset); /* Start by forking */ pid = fork(); - if (pid) + if (pid) { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); return pid; + } + + /* Restore original signal handlers */ + for (x=0;x<NSIG;x++) + signal(x, SIG_DFL); + + pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); /* Execute RAS on File handles */ dup2(chan->fds[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<NSIG;x++) - signal(x, SIG_DFL); - /* Reset all arguments */ memset(argv, 0, sizeof(argv)); diff --git a/res/res_agi.c b/res/res_agi.c index b4d61702514921294025c51872c288829e9b67a6..042fdbfbca42ce47ca86ea958719f2d382c17961 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -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[]) diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index f560432bb5e521580dd9808c0955ac2ab9a45bde..96e24a4a7d551f43be8702c8c4fca273507b272e 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];