summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorTilghman Lesher <tilghman@meg.abyt.es>2008-04-16 22:57:54 +0000
committerTilghman Lesher <tilghman@meg.abyt.es>2008-04-16 22:57:54 +0000
commit123ac5fd646cb7a0ed3b7055cda609db93c20487 (patch)
tree6dea5b8c8d8bb81a47195b75172db608ff217382 /main
parent752f6681b1ea748a1acef2a55e17c4c564715fde (diff)
Standardized routines for forking processes (keeps all the specialized code in one place).
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@114188 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/app.c63
-rw-r--r--main/asterisk.c6
-rw-r--r--main/logger.c49
3 files changed, 113 insertions, 5 deletions
diff --git a/main/app.c b/main/app.c
index ee72d1078..05cdf1748 100644
--- a/main/app.c
+++ b/main/app.c
@@ -32,6 +32,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#endif
#include <regex.h>
#include <sys/file.h> /* added this to allow to compile, sorry! */
+#include <signal.h>
#include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
#include "asterisk/channel.h"
@@ -1759,3 +1760,65 @@ int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
return 0;
}
+void ast_close_fds_above_n(int n)
+{
+ int x, null;
+ null = open("/dev/null", O_RDONLY);
+ for (x = n + 1; x <= (null >= 8192 ? null : 8192); x++) {
+ if (x != null) {
+ /* Side effect of dup2 is that it closes any existing fd without error.
+ * This prevents valgrind and other debugging tools from sending up
+ * false error reports. */
+ dup2(null, x);
+ close(x);
+ }
+ }
+ close(null);
+}
+
+int ast_safe_fork(int stop_reaper)
+{
+ sigset_t signal_set, old_set;
+ int pid;
+
+ /* Don't let the default signal handler for children reap our status */
+ if (stop_reaper) {
+ ast_replace_sigchld();
+ }
+
+ sigfillset(&signal_set);
+ pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
+
+ pid = fork();
+
+ if (pid != 0) {
+ /* Fork failed or parent */
+ pthread_sigmask(SIG_SETMASK, &old_set, NULL);
+ return pid;
+ } else {
+ /* Child */
+
+ /* 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);
+ }
+
+ return pid;
+ }
+}
+
+void ast_safe_fork_cleanup(void)
+{
+ ast_unreplace_sigchld();
+}
+
diff --git a/main/asterisk.c b/main/asterisk.c
index f08a4d020..99df3ef45 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -848,9 +848,6 @@ void ast_unreplace_sigchld(void)
int ast_safe_system(const char *s)
{
pid_t pid;
-#ifdef HAVE_WORKING_FORK
- int x;
-#endif
int res;
struct rusage rusage;
int status;
@@ -869,8 +866,7 @@ int ast_safe_system(const char *s)
if (ast_opt_high_priority)
ast_set_priority(0);
/* Close file descriptors and launch system command */
- for (x = STDERR_FILENO + 1; x < 4096; x++)
- close(x);
+ ast_close_fds_above_n(STDERR_FILENO);
#endif
execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
_exit(1);
diff --git a/main/logger.c b/main/logger.c
index b7c517fa7..dce2097d9 100644
--- a/main/logger.c
+++ b/main/logger.c
@@ -413,6 +413,55 @@ static void init_logger_chain(int reload, int locked)
ast_config_destroy(cfg);
}
+void ast_child_verbose(int level, const char *fmt, ...)
+{
+ char *msg = NULL, *emsg = NULL, *sptr, *eptr;
+ va_list ap, aq;
+ int size;
+
+ /* Don't bother, if the level isn't that high */
+ if (option_verbose < level) {
+ return;
+ }
+
+ va_start(ap, fmt);
+ va_copy(aq, ap);
+ if ((size = vsnprintf(msg, 0, fmt, ap)) < 0) {
+ va_end(ap);
+ va_end(aq);
+ return;
+ }
+ va_end(ap);
+
+ if (!(msg = ast_malloc(size + 1))) {
+ va_end(aq);
+ return;
+ }
+
+ vsnprintf(msg, size + 1, fmt, aq);
+ va_end(aq);
+
+ if (!(emsg = ast_malloc(size * 2 + 1))) {
+ ast_free(msg);
+ return;
+ }
+
+ for (sptr = msg, eptr = emsg; ; sptr++) {
+ if (*sptr == '"') {
+ *eptr++ = '\\';
+ }
+ *eptr++ = *sptr;
+ if (*sptr == '\0') {
+ break;
+ }
+ }
+ ast_free(msg);
+
+ fprintf(stdout, "verbose \"%s\" %d\n", emsg, level);
+ fflush(stdout);
+ ast_free(emsg);
+}
+
void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
{
va_list ap;