aboutsummaryrefslogtreecommitdiffstats
path: root/res
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-04-16 22:57:54 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-04-16 22:57:54 +0000
commitd9fc402428c10315d158f7cf960c9592276b3c82 (patch)
tree6dea5b8c8d8bb81a47195b75172db608ff217382 /res
parentc99aa3db824dfb5a6eddf4d7d96685e8eb1767d6 (diff)
Standardized routines for forking processes (keeps all the specialized code in one place).
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@114188 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'res')
-rw-r--r--res/res_agi.c32
-rw-r--r--res/res_musiconhold.c27
2 files changed, 12 insertions, 47 deletions
diff --git a/res/res_agi.c b/res/res_agi.c
index 49aa2cfd5..caa015a7e 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -603,8 +603,7 @@ static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds, in
static enum agi_result launch_script(struct ast_channel *chan, char *script, char *argv[], int *fds, int *efd, int *opid)
{
char tmp[256];
- int pid, toast[2], fromast[2], audio[2], x, res;
- sigset_t signal_set, old_set;
+ int pid, toast[2], fromast[2], audio[2], res;
struct stat st;
if (!strncasecmp(script, "agi://", 6))
@@ -657,12 +656,8 @@ static enum agi_result launch_script(struct ast_channel *chan, char *script, cha
}
}
- /* Block SIGHUP during the fork - prevents a race */
- sigfillset(&signal_set);
- pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
- if ((pid = fork()) < 0) {
+ if ((pid = ast_safe_fork(1)) < 0) {
ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
- pthread_sigmask(SIG_SETMASK, &old_set, NULL);
return AGI_RESULT_FAILURE;
}
if (!pid) {
@@ -690,34 +685,17 @@ static enum agi_result launch_script(struct ast_channel *chan, char *script, cha
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 (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
- ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno));
- _exit(1);
- }
-
/* Close everything but stdin/out/error */
- for (x = STDERR_FILENO + 2; x < 1024; x++)
- close(x);
+ ast_close_fds_above_n(STDERR_FILENO + 1);
/* Execute script */
/* XXX argv should be deprecated in favor of passing agi_argX paramaters */
execv(script, argv);
/* Can't use ast_log since FD's are closed */
- fprintf(stdout, "verbose \"Failed to execute '%s': %s\" 2\n", script, strerror(errno));
+ ast_child_verbose(1, "Failed to execute '%s': %s", script, strerror(errno));
fflush(stdout);
_exit(1);
}
- pthread_sigmask(SIG_SETMASK, &old_set, NULL);
ast_verb(3, "Launched AGI Script %s\n", script);
fds[0] = toast[0];
fds[1] = fromast[1];
@@ -2908,8 +2886,8 @@ static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced, int
close(fds[1]);
if (efd > -1)
close(efd);
- ast_unreplace_sigchld();
}
+ ast_safe_fork_cleanup();
switch (res) {
case AGI_RESULT_SUCCESS:
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index e7044eff9..e456b3c7e 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -404,7 +404,6 @@ 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")) {
@@ -490,12 +489,8 @@ static int spawn_mp3(struct mohclass *class)
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();
+ class->pid = ast_safe_fork(0);
if (class->pid < 0) {
close(fds[0]);
close(fds[1]);
@@ -503,24 +498,16 @@ static int spawn_mp3(struct mohclass *class)
return -1;
}
if (!class->pid) {
- int x;
-
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);
- /* Close unused file descriptors */
- for (x=3;x<8192;x++) {
- if (-1 != fcntl(x, F_GETFL)) {
- close(x);
- }
- }
+
+ /* Close everything else */
+ ast_close_fds_above_n(STDERR_FILENO);
+
/* Child */
chdir(class->dir);
if (ast_test_flag(class, MOH_CUSTOM)) {
@@ -533,12 +520,12 @@ static int spawn_mp3(struct mohclass *class)
/* Check PATH as a last-ditch effort */
execvp("mpg123", argv);
}
- ast_log(LOG_WARNING, "Exec failed: %s\n", strerror(errno));
+ /* Can't use logger, since log FDs are closed */
+ fprintf(stderr, "MOH: exec failed: %s\n", strerror(errno));
close(fds[1]);
_exit(1);
} else {
/* Parent */
- pthread_sigmask(SIG_SETMASK, &old_set, NULL);
close(fds[1]);
}
return fds[0];