[asterisk-commits] markm: branch 1.10 r328609 - in /branches/1.10: ./ main/asterisk.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jul 18 07:37:57 CDT 2011


Author: markm
Date: Mon Jul 18 07:37:53 2011
New Revision: 328609

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

........
  r328593 | markm | 2011-07-18 08:06:50 -0400 (Mon, 18 Jul 2011) | 8 lines
  
  Fixed invalid read and null pointer deref on asterisk shutdown.
  
  In some cases when starting asterisk with -c and hitting control-c to shutdown, there will be an invalid read and null pointer deref causing a crash.
  
  (closes issue ASTERISK-17927)
  Reported by: Mark Murawski
  Tested by: Mark Murawski, Kinsey Moore, Tilghman Lesher
........

Modified:
    branches/1.10/   (props changed)
    branches/1.10/main/asterisk.c

Propchange: branches/1.10/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Modified: branches/1.10/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.10/main/asterisk.c?view=diff&rev=328609&r1=328608&r2=328609
==============================================================================
--- branches/1.10/main/asterisk.c (original)
+++ branches/1.10/main/asterisk.c Mon Jul 18 07:37:53 2011
@@ -291,6 +291,7 @@
 static struct {
 	 unsigned int need_reload:1;
 	 unsigned int need_quit:1;
+	 unsigned int need_quit_handler:1;
 } sig_flags;
 
 #if !defined(LOW_MEMORY)
@@ -1657,20 +1658,23 @@
 			ast_module_shutdown();
 	}
 	if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
-		pthread_t thisthread = pthread_self();
 		if (getenv("HOME")) {
 			snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
 		}
 		if (!ast_strlen_zero(filename)) {
 			ast_el_write_history(filename);
 		}
-		if (consolethread == AST_PTHREADT_NULL || consolethread == thisthread || mon_sig_flags == thisthread) {
-			/* Only end if we are the consolethread or signal handler, otherwise there's a race with that thread. */
+		if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
+			/* Only end if we are the consolethread, otherwise there's a race with that thread. */
 			if (el != NULL) {
 				el_end(el);
 			}
 			if (el_hist != NULL) {
 				history_end(el_hist);
+			}
+		} else if (mon_sig_flags == pthread_self()) {
+			if (consolethread != AST_PTHREADT_NULL) {
+				pthread_kill(consolethread, SIGURG);
 			}
 		}
 	}
@@ -2150,7 +2154,7 @@
 		}
 		res = ast_poll(fds, max, -1);
 		if (res < 0) {
-			if (sig_flags.need_quit)
+			if (sig_flags.need_quit || sig_flags.need_quit_handler)
 				break;
 			if (errno == EINTR)
 				continue;
@@ -2707,7 +2711,7 @@
 		sprintf(tmp, "%s%s", prefix, data);
 		if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
 			ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
-			if (sig_flags.need_quit == 1) {
+			if (sig_flags.need_quit || sig_flags.need_quit_handler) {
 				return;
 			}
 		}
@@ -2745,7 +2749,7 @@
 			char buffer[512] = "", *curline = buffer, *nextline;
 			int not_written = 1;
 
-			if (sig_flags.need_quit == 1) {
+			if (sig_flags.need_quit || sig_flags.need_quit_handler) {
 				break;
 			}
 
@@ -2793,7 +2797,7 @@
 	for (;;) {
 		ebuf = (char *)el_gets(el, &num);
 
-		if (sig_flags.need_quit == 1) {
+		if (sig_flags.need_quit || sig_flags.need_quit_handler) {
 			break;
 		}
 
@@ -3115,7 +3119,12 @@
 		}
 		if (sig_flags.need_quit) {
 			sig_flags.need_quit = 0;
-			quit_handler(0, 0, 1, 0);
+			if (consolethread != AST_PTHREADT_NULL) {
+				sig_flags.need_quit_handler = 1;
+				pthread_kill(consolethread, SIGURG);
+			} else {
+				quit_handler(0, 0, 1, 0);
+			}
 		}
 		if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
 		}
@@ -3900,7 +3909,13 @@
 		snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
 		set_title(title);
 
+		el_set(el, EL_GETCFN, ast_el_read_char);
+
 		for (;;) {
+			if (sig_flags.need_quit || sig_flags.need_quit_handler) {
+				quit_handler(0, 0, 0, 0);
+				break;
+			}
 			buf = (char *) el_gets(el, &num);
 
 			if (!buf && write(1, "", 1) < 0)




More information about the asterisk-commits mailing list