[asterisk-commits] tilghman: trunk r266146 - in /trunk: ./ main/ utils/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed May 26 16:17:49 CDT 2010


Author: tilghman
Date: Wed May 26 16:17:46 2010
New Revision: 266146

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=266146
Log:
Merged revisions 266142 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r266142 | tilghman | 2010-05-26 16:11:44 -0500 (Wed, 26 May 2010) | 14 lines
  
  Use sigaction for signals which should persist past the initial trigger, not signal.
  
  If you call signal() in a Solaris signal handler, instead of just resetting
  the signal handler, it causes the signal to refire, because the signal is not
  marked as handled prior to the signal handler being called.  This effectively
  causes Solaris to immediately exceed the threadstack in recursive signal
  handlers and crash.
  
  (closes issue #17000)
   Reported by: rmcgilvr
   Patches: 
         20100526__issue17000.diff.txt uploaded by tilghman (license 14)
   Tested by: rmcgilvr
........

Modified:
    trunk/   (props changed)
    trunk/main/asterisk.c
    trunk/main/logger.c
    trunk/utils/extconf.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/asterisk.c?view=diff&rev=266146&r1=266145&r2=266146
==============================================================================
--- trunk/main/asterisk.c (original)
+++ trunk/main/asterisk.c Wed May 26 16:17:46 2010
@@ -970,16 +970,24 @@
 }
 
 /*! \brief NULL handler so we can collect the child exit status */
-static void null_sig_handler(int sig)
-{
-
-}
+static void _null_sig_handler(int sig)
+{
+
+}
+
+static struct sigaction null_sig_handler = {
+	.sa_handler = _null_sig_handler,
+};
+
+static struct sigaction ignore_sig_handler = {
+	.sa_handler = SIG_IGN,
+};
 
 AST_MUTEX_DEFINE_STATIC(safe_system_lock);
 /*! \brief Keep track of how many threads are currently trying to wait*() on
  *  a child process */
 static unsigned int safe_system_level = 0;
-static void *safe_system_prev_handler;
+static struct sigaction safe_system_prev_handler;
 
 void ast_replace_sigchld(void)
 {
@@ -989,8 +997,9 @@
 	level = safe_system_level++;
 
 	/* only replace the handler if it has not already been done */
-	if (level == 0)
-		safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
+	if (level == 0) {
+		sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
+	}
 
 	ast_mutex_unlock(&safe_system_lock);
 }
@@ -1003,8 +1012,9 @@
 	level = --safe_system_level;
 
 	/* only restore the handler if we are the last one */
-	if (level == 0)
-		signal(SIGCHLD, safe_system_prev_handler);
+	if (level == 0) {
+		sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
+	}
 
 	ast_mutex_unlock(&safe_system_lock);
 }
@@ -1437,13 +1447,16 @@
  system call.  We don't actually need to do anything though.  
  Remember: Cannot EVER ast_log from within a signal handler 
  */
-static void urg_handler(int num)
-{
-	signal(num, urg_handler);
+static void _urg_handler(int num)
+{
 	return;
 }
 
-static void hup_handler(int num)
+static struct sigaction urg_handler = {
+	.sa_handler = _urg_handler,
+};
+
+static void _hup_handler(int num)
 {
 	int a = 0;
 	if (option_verbose > 1) 
@@ -1456,10 +1469,13 @@
 			fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
 		}
 	}
-	signal(num, hup_handler);
-}
-
-static void child_handler(int sig)
+}
+
+static struct sigaction hup_handler = {
+	.sa_handler = _hup_handler,
+};
+
+static void _child_handler(int sig)
 {
 	/* Must not ever ast_log or ast_verbose within signal handler */
 	int n, status;
@@ -1471,8 +1487,11 @@
 		;
 	if (n == 0 && option_debug)	
 		printf("Huh?  Child handler, but nobody there?\n");
-	signal(sig, child_handler);
-}
+}
+
+static struct sigaction child_handler = {
+	.sa_handler = _child_handler,
+};
 
 /*! \brief Set maximum open files */
 static void set_ulimit(int value)
@@ -1672,7 +1691,7 @@
 	sig_flags.need_quit = 1;
 	if (sig_alert_pipe[1] != -1) {
 		if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
-			fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
+			fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
 		}
 	}
 	/* There is no need to restore the signal handler here, since the app
@@ -3322,7 +3341,7 @@
 	/* Must install this signal handler up here to ensure that if the canary
 	 * fails to execute that it doesn't kill the Asterisk process.
 	 */
-	signal(SIGCHLD, child_handler);
+	sigaction(SIGCHLD, &child_handler, NULL);
 
 	/* It's common on some platforms to clear /var/run at boot.  Create the
 	 * socket file directory before we drop privileges. */
@@ -3521,7 +3540,7 @@
 		snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
 
 		/* Don't let the canary child kill Asterisk, if it dies immediately */
-		signal(SIGPIPE, SIG_IGN);
+		sigaction(SIGPIPE, &ignore_sig_handler, NULL);
 
 		canary_pid = fork();
 		if (canary_pid == 0) {
@@ -3575,11 +3594,11 @@
 	sigaddset(&sigs, SIGPIPE);
 	sigaddset(&sigs, SIGWINCH);
 	pthread_sigmask(SIG_BLOCK, &sigs, NULL);
-	signal(SIGURG, urg_handler);
+	sigaction(SIGURG, &urg_handler, NULL);
 	signal(SIGINT, __quit_handler);
 	signal(SIGTERM, __quit_handler);
-	signal(SIGHUP, hup_handler);
-	signal(SIGPIPE, SIG_IGN);
+	sigaction(SIGHUP, &hup_handler, NULL);
+	sigaction(SIGPIPE, &ignore_sig_handler, NULL);
 
 	/* ensure that the random number generators are seeded with a different value every time
 	   Asterisk is started

Modified: trunk/main/logger.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/logger.c?view=diff&rev=266146&r1=266145&r2=266146
==============================================================================
--- trunk/main/logger.c (original)
+++ trunk/main/logger.c Wed May 26 16:17:46 2010
@@ -738,7 +738,7 @@
 	}
 	AST_RWLIST_UNLOCK(&logchannels);
 	ast_cli(a->fd, "\n");
- 		
+
 	return CLI_SUCCESS;
 }
 
@@ -756,12 +756,15 @@
 	AST_CLI_DEFINE(handle_logger_set_level, "Enables/Disables a specific logging level for this console")
 };
 
-static int handle_SIGXFSZ(int sig) 
+static void _handle_SIGXFSZ(int sig)
 {
 	/* Indicate need to reload */
 	filesize_reload_needed = 1;
-	return 0;
-}
+}
+
+static struct sigaction handle_SIGXFSZ = {
+	.sa_handler = _handle_SIGXFSZ,
+};
 
 static void ast_log_vsyslog(struct logmsg *msg)
 {
@@ -929,7 +932,7 @@
 	int res = 0;
 
 	/* auto rotate if sig SIGXFSZ comes a-knockin */
-	(void) signal(SIGXFSZ, (void *) handle_SIGXFSZ);
+	sigaction(SIGXFSZ, &handle_SIGXFSZ, NULL);
 
 	/* start logger thread */
 	ast_cond_init(&logcond, NULL);

Modified: trunk/utils/extconf.c
URL: http://svnview.digium.com/svn/asterisk/trunk/utils/extconf.c?view=diff&rev=266146&r1=266145&r2=266146
==============================================================================
--- trunk/utils/extconf.c (original)
+++ trunk/utils/extconf.c Wed May 26 16:17:46 2010
@@ -1258,13 +1258,17 @@
 /*! \brief Keep track of how many threads are currently trying to wait*() on
  *  a child process */
 static unsigned int safe_system_level = 0;
-static void *safe_system_prev_handler;
+static struct sigaction safe_system_prev_handler;
 
 /*! \brief NULL handler so we can collect the child exit status */
-static void null_sig_handler(int sig)
-{
-
-}
+static void _null_sig_handler(int sig)
+{
+
+}
+
+static struct sigaction null_sig_handler = {
+	.sa_handler = _null_sig_handler,
+};
 
 void ast_replace_sigchld(void);
 
@@ -1275,9 +1279,9 @@
 	level = safe_system_level++;
 
 	/* only replace the handler if it has not already been done */
-	if (level == 0)
-		safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
-
+	if (level == 0) {
+		sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
+	}
 }
 
 void ast_unreplace_sigchld(void);
@@ -1289,9 +1293,9 @@
 	level = --safe_system_level;
 
 	/* only restore the handler if we are the last one */
-	if (level == 0)
-		signal(SIGCHLD, safe_system_prev_handler);
-
+	if (level == 0) {
+		sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
+	}
 }
 
 int ast_safe_system(const char *s);




More information about the asterisk-commits mailing list