summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorTilghman Lesher <tilghman@meg.abyt.es>2006-12-11 00:52:19 +0000
committerTilghman Lesher <tilghman@meg.abyt.es>2006-12-11 00:52:19 +0000
commitd670858735fce93f57eb72d3b8a0bba923015d31 (patch)
tree80cfa0cd4517050b2e78379b2f2710141f333d79 /res
parent23e606f70ab2fbcc66be3130ea5253731d82cbcd (diff)
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
Diffstat (limited to 'res')
-rw-r--r--res/res_agi.c24
-rw-r--r--res/res_musiconhold.c11
2 files changed, 29 insertions, 6 deletions
diff --git a/res/res_agi.c b/res/res_agi.c
index b4d617025..042fdbfbc 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 f560432bb..96e24a4a7 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];