diff options
Diffstat (limited to 'res')
-rw-r--r-- | res/res_agi.c | 20 | ||||
-rw-r--r-- | res/res_features.c | 16 | ||||
-rw-r--r-- | res/res_musiconhold.c | 45 | ||||
-rw-r--r-- | res/res_odbc.c | 1 |
4 files changed, 52 insertions, 30 deletions
diff --git a/res/res_agi.c b/res/res_agi.c index 022cee46e..1d39c6936 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -234,7 +234,7 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op 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); @@ -276,6 +276,10 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op return -1; } } + + /* 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)); @@ -293,9 +297,18 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op } 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); } @@ -310,6 +323,7 @@ static int launch_script(char *script, char *argv[], int *fds, int *efd, int *op fprintf(stderr, "Failed to execute '%s': %s\n", script, strerror(errno)); _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]; diff --git a/res/res_features.c b/res/res_features.c index a33844b1e..b1eb6f16c 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -1774,12 +1774,6 @@ static int park_exec(struct ast_channel *chan, void *data) ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park); memset(&config, 0, sizeof(struct ast_bridge_config)); - ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT); - ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT); - config.timelimit = 0; - config.play_warning = 0; - config.warning_freq = 0; - config.warning_sound=NULL; res = ast_bridge_call(chan, peer, &config); /* Simulate the PBX hanging up */ @@ -2058,7 +2052,8 @@ static int load_config(void) ast_unregister_features(); var = ast_variable_browse(cfg, "applicationmap"); while(var) { - char *tmp_val=strdup(var->value); + char *tmp_val_orig=strdup(var->value); + char *tmp_val = tmp_val_orig; char *exten, *party=NULL, *app=NULL, *app_args=NULL; if (!tmp_val) { @@ -2075,7 +2070,7 @@ static int load_config(void) if (!(app && strlen(app)) || !(exten && strlen(exten)) || !(party && strlen(party)) || !(var->name && strlen(var->name))) { ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",app,exten,party,var->name); - free(tmp_val); + free(tmp_val_orig); var = var->next; continue; } @@ -2090,7 +2085,7 @@ static int load_config(void) } if (!feature) { ast_log(LOG_NOTICE, "Malloc failed at feature mapping\n"); - free(tmp_val); + free(tmp_val_orig); var = var->next; continue; } @@ -2099,7 +2094,6 @@ static int load_config(void) ast_copy_string(feature->sname,var->name,FEATURE_SNAME_LEN); ast_copy_string(feature->app,app,FEATURE_APP_LEN); ast_copy_string(feature->exten, exten,FEATURE_EXTEN_LEN); - free(tmp_val); if (app_args) ast_copy_string(feature->app_args,app_args,FEATURE_APP_ARGS_LEN); @@ -2114,6 +2108,7 @@ static int load_config(void) ast_set_flag(feature,AST_FEATURE_FLAG_CALLEE); else { ast_log(LOG_NOTICE, "Invalid party specification for feature '%s', must be caller, or callee\n", var->name); + free(tmp_val_orig); var = var->next; continue; } @@ -2121,6 +2116,7 @@ static int load_config(void) ast_register_feature(feature); if (option_verbose >=1) ast_verbose(VERBOSE_PREFIX_2 "Mapping Feature '%s' to app '%s' with code '%s'\n", var->name, app, exten); + free(tmp_val_orig); } var = var->next; } diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index 6c0c380bd..746fa2d06 100644 --- a/res/res_musiconhold.c +++ b/res/res_musiconhold.c @@ -190,7 +190,7 @@ static void moh_files_release(struct ast_channel *chan, void *data) if (state->origwfmt && ast_set_write_format(chan, state->origwfmt)) { ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, state->origwfmt); } - state->save_pos = state->pos + 1; + state->save_pos = state->pos; } } @@ -201,35 +201,33 @@ static int ast_moh_files_next(struct ast_channel *chan) int tries; if (state->save_pos) { - state->pos = state->save_pos - 1; + state->pos = state->save_pos; state->save_pos = 0; - } else { - /* Try 20 times to find something good */ - for (tries=0;tries < 20;tries++) { - state->samples = 0; - if (chan->stream) { - ast_closestream(chan->stream); - chan->stream = NULL; - state->pos++; - } + } - if (ast_test_flag(state->class, MOH_RANDOMIZE)) - state->pos = rand(); + state->samples = 0; + if (chan->stream) { + ast_closestream(chan->stream); + chan->stream = NULL; + state->pos++; + state->pos %= state->class->total_files; + } - state->pos %= state->class->total_files; + if (ast_test_flag(state->class, MOH_RANDOMIZE)) { + /* Try 20 times to find something good */ + for (tries = 0; tries < 20; tries++) { + state->pos = rand() % state->class->total_files; /* check to see if this file's format can be opened */ if (ast_fileexists(state->class->filearray[state->pos], NULL, NULL) > 0) break; - } } - state->pos = state->pos % state->class->total_files; - if (!ast_openstream_full(chan, state->class->filearray[state->pos], chan->language, 1)) { ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", state->class->filearray[state->pos], strerror(errno)); state->pos++; + state->pos %= state->class->total_files; return -1; } @@ -297,6 +295,8 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params) /* initialize */ memset(state, 0, sizeof(struct moh_files_state)); state->class = class; + if (ast_test_flag(state->class, MOH_RANDOMIZE)) + state->pos = rand() % class->total_files; } state->origwfmt = chan->writeformat; @@ -326,6 +326,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")) { @@ -426,6 +427,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) { @@ -440,6 +446,10 @@ static int spawn_mp3(struct mohclass *class) if (option_highpriority) 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); @@ -466,6 +476,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]; diff --git a/res/res_odbc.c b/res/res_odbc.c index cc4b61f2d..92cd1ccfb 100644 --- a/res/res_odbc.c +++ b/res/res_odbc.c @@ -140,6 +140,7 @@ SQLHSTMT odbc_prepare_and_execute(odbc_obj *obj, SQLHSTMT (*prepare_cb)(odbc_obj ast_log(LOG_WARNING, "SQL Execute error %d! Attempting a reconnect...\n", res); SQLFreeHandle(SQL_HANDLE_STMT, stmt); + stmt = NULL; ast_mutex_lock(&obj->lock); obj->up = 0; |