[asterisk-commits] tilghman: branch 1.4 r48375 - in /branches/1.4:
./ apps/ res/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Sun Dec 10 17:47:21 MST 2006
Author: tilghman
Date: Sun Dec 10 18:47:21 2006
New Revision: 48375
URL: http://svn.digium.com/view/asterisk?view=rev&rev=48375
Log:
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.
........
Modified:
branches/1.4/ (props changed)
branches/1.4/apps/app_externalivr.c
branches/1.4/apps/app_festival.c
branches/1.4/apps/app_ices.c
branches/1.4/apps/app_mp3.c
branches/1.4/apps/app_nbscat.c
branches/1.4/apps/app_zapras.c
branches/1.4/res/res_agi.c
branches/1.4/res/res_musiconhold.c
Propchange: branches/1.4/
------------------------------------------------------------------------------
Binary property 'branch-1.2-merged' - no diff available.
Modified: branches/1.4/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_externalivr.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_externalivr.c (original)
+++ branches/1.4/apps/app_externalivr.c Sun Dec 10 18:47:21 2006
@@ -40,6 +40,7 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+#include <signal.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
@@ -261,9 +262,13 @@
.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;
@@ -311,6 +316,9 @@
if (!pid) {
/* child process */
int i;
+
+ signal(SIGPIPE, SIG_DFL);
+ pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
if (ast_opt_high_priority)
ast_set_priority(0);
@@ -334,6 +342,8 @@
int ready_fd;
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;
Modified: branches/1.4/apps/app_festival.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_festival.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_festival.c (original)
+++ branches/1.4/apps/app_festival.c Sun Dec 10 18:47:21 2006
@@ -130,19 +130,26 @@
#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)
Modified: branches/1.4/apps/app_ices.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_ices.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_ices.c (original)
+++ branches/1.4/apps/app_ices.c Sun Dec 10 18:47:21 2006
@@ -65,15 +65,27 @@
{
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 @@
/* 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)
Modified: branches/1.4/apps/app_mp3.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_mp3.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_mp3.c (original)
+++ branches/1.4/apps/app_mp3.c Sun Dec 10 18:47:21 2006
@@ -64,15 +64,25 @@
{
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 @@
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)
Modified: branches/1.4/apps/app_nbscat.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_nbscat.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_nbscat.c (original)
+++ branches/1.4/apps/app_nbscat.c Sun Dec 10 18:47:21 2006
@@ -68,16 +68,26 @@
{
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 @@
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)
Modified: branches/1.4/apps/app_zapras.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_zapras.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/apps/app_zapras.c (original)
+++ branches/1.4/apps/app_zapras.c Sun Dec 10 18:47:21 2006
@@ -82,11 +82,23 @@
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);
@@ -98,10 +110,6 @@
/* Close other file descriptors */
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));
Modified: branches/1.4/res/res_agi.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/res/res_agi.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/res/res_agi.c (original)
+++ branches/1.4/res/res_agi.c Sun Dec 10 18:47:21 2006
@@ -240,7 +240,7 @@
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 @@
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 @@
} 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 @@
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 @@
*opid = pid;
return AGI_RESULT_SUCCESS;
-
}
static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced)
Modified: branches/1.4/res/res_musiconhold.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/res/res_musiconhold.c?view=diff&rev=48375&r1=48374&r2=48375
==============================================================================
--- branches/1.4/res/res_musiconhold.c (original)
+++ branches/1.4/res/res_musiconhold.c Sun Dec 10 18:47:21 2006
@@ -340,6 +340,7 @@
int argc = 0;
DIR *dir = NULL;
struct dirent *de;
+ sigset_t signal_set, old_set;
if (!strcasecmp(class->dir, "nodir")) {
@@ -424,6 +425,11 @@
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) {
@@ -437,6 +443,10 @@
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 */
@@ -464,6 +474,7 @@
_exit(1);
} else {
/* Parent */
+ pthread_sigmask(SIG_SETMASK, &old_set, NULL);
close(fds[1]);
}
return fds[0];
More information about the asterisk-commits
mailing list