aboutsummaryrefslogtreecommitdiffstats
path: root/src/sysdep.c
diff options
context:
space:
mode:
authorJoakim Verona2012-09-10 16:03:53 +0200
committerJoakim Verona2012-09-10 16:03:53 +0200
commitb035a30e5cd2f34fedc04c253eeb5a11afed8145 (patch)
treeb9350cce389602f4967bdc1beed745929155ad5d /src/sysdep.c
parent4a37733c693d59a9b83a3fb2d0c7f9461d149f60 (diff)
parenta31a4cdacb196cc96dcb9bd229edb1d635e01344 (diff)
downloademacs-b035a30e5cd2f34fedc04c253eeb5a11afed8145.tar.gz
emacs-b035a30e5cd2f34fedc04c253eeb5a11afed8145.zip
upstream
Diffstat (limited to 'src/sysdep.c')
-rw-r--r--src/sysdep.c165
1 files changed, 98 insertions, 67 deletions
diff --git a/src/sysdep.c b/src/sysdep.c
index b84e6a4ea3a..0f16d1a7645 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -21,7 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#define SYSTIME_INLINE EXTERN_INLINE 22#define SYSTIME_INLINE EXTERN_INLINE
23 23
24#include <signal.h> 24#include <execinfo.h>
25#include <stdio.h> 25#include <stdio.h>
26#include <setjmp.h> 26#include <setjmp.h>
27#ifdef HAVE_PWD_H 27#ifdef HAVE_PWD_H
@@ -302,27 +302,34 @@ wait_for_termination_1 (pid_t pid, int interruptible)
302 termination of subprocesses, perhaps involving a kernel bug too, 302 termination of subprocesses, perhaps involving a kernel bug too,
303 but no idea what it is. Just as a hunch we signal SIGCHLD to see 303 but no idea what it is. Just as a hunch we signal SIGCHLD to see
304 if that causes the problem to go away or get worse. */ 304 if that causes the problem to go away or get worse. */
305 sigsetmask (sigmask (SIGCHLD)); 305 sigset_t sigchild_mask;
306 sigemptyset (&sigchild_mask);
307 sigaddset (&sigchild_mask, SIGCHLD);
308 pthread_sigmask (SIG_SETMASK, &sigchild_mask, 0);
309
306 if (0 > kill (pid, 0)) 310 if (0 > kill (pid, 0))
307 { 311 {
308 sigsetmask (SIGEMPTYMASK); 312 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
309 kill (getpid (), SIGCHLD); 313 kill (getpid (), SIGCHLD);
310 break; 314 break;
311 } 315 }
312 if (wait_debugging) 316 if (wait_debugging)
313 sleep (1); 317 sleep (1);
314 else 318 else
315 sigpause (SIGEMPTYMASK); 319 sigsuspend (&empty_mask);
316#else /* not BSD_SYSTEM, and not HPUX version >= 6 */ 320#else /* not BSD_SYSTEM, and not HPUX version >= 6 */
317#ifdef WINDOWSNT 321#ifdef WINDOWSNT
318 wait (0); 322 wait (0);
319 break; 323 break;
320#else /* not WINDOWSNT */ 324#else /* not WINDOWSNT */
321 sigblock (sigmask (SIGCHLD)); 325 sigset_t blocked;
326 sigemptyset (&blocked);
327 sigaddset (&blocked, SIGCHLD);
328 pthread_sigmask (SIG_BLOCK, &blocked, 0);
322 errno = 0; 329 errno = 0;
323 if (kill (pid, 0) == -1 && errno == ESRCH) 330 if (kill (pid, 0) == -1 && errno == ESRCH)
324 { 331 {
325 sigunblock (sigmask (SIGCHLD)); 332 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
326 break; 333 break;
327 } 334 }
328 335
@@ -456,11 +463,11 @@ child_setup_tty (int out)
456#endif /* not MSDOS */ 463#endif /* not MSDOS */
457 464
458 465
459/* Record a signal code and the handler for it. */ 466/* Record a signal code and the action for it. */
460struct save_signal 467struct save_signal
461{ 468{
462 int code; 469 int code;
463 void (*handler) (int); 470 struct sigaction action;
464}; 471};
465 472
466static void save_signal_handlers (struct save_signal *); 473static void save_signal_handlers (struct save_signal *);
@@ -618,8 +625,9 @@ save_signal_handlers (struct save_signal *saved_handlers)
618{ 625{
619 while (saved_handlers->code) 626 while (saved_handlers->code)
620 { 627 {
621 saved_handlers->handler 628 struct sigaction action;
622 = (void (*) (int)) signal (saved_handlers->code, SIG_IGN); 629 emacs_sigaction_init (&action, SIG_IGN);
630 sigaction (saved_handlers->code, &action, &saved_handlers->action);
623 saved_handlers++; 631 saved_handlers++;
624 } 632 }
625} 633}
@@ -629,7 +637,7 @@ restore_signal_handlers (struct save_signal *saved_handlers)
629{ 637{
630 while (saved_handlers->code) 638 while (saved_handlers->code)
631 { 639 {
632 signal (saved_handlers->code, saved_handlers->handler); 640 sigaction (saved_handlers->code, &saved_handlers->action, 0);
633 saved_handlers++; 641 saved_handlers++;
634 } 642 }
635} 643}
@@ -686,13 +694,17 @@ reset_sigio (int fd)
686void 694void
687request_sigio (void) 695request_sigio (void)
688{ 696{
697 sigset_t unblocked;
698
689 if (noninteractive) 699 if (noninteractive)
690 return; 700 return;
691 701
702 sigemptyset (&unblocked);
692#ifdef SIGWINCH 703#ifdef SIGWINCH
693 sigunblock (sigmask (SIGWINCH)); 704 sigaddset (&unblocked, SIGWINCH);
694#endif 705#endif
695 sigunblock (sigmask (SIGIO)); 706 sigaddset (&unblocked, SIGIO);
707 pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
696 708
697 interrupts_deferred = 0; 709 interrupts_deferred = 0;
698} 710}
@@ -700,6 +712,8 @@ request_sigio (void)
700void 712void
701unrequest_sigio (void) 713unrequest_sigio (void)
702{ 714{
715 sigset_t blocked;
716
703 if (noninteractive) 717 if (noninteractive)
704 return; 718 return;
705 719
@@ -708,10 +722,12 @@ unrequest_sigio (void)
708 return; 722 return;
709#endif 723#endif
710 724
725 sigemptyset (&blocked);
711#ifdef SIGWINCH 726#ifdef SIGWINCH
712 sigblock (sigmask (SIGWINCH)); 727 sigaddset (&blocked, SIGWINCH);
713#endif 728#endif
714 sigblock (sigmask (SIGIO)); 729 sigaddset (&blocked, SIGIO);
730 pthread_sigmask (SIG_BLOCK, &blocked, 0);
715 interrupts_deferred = 1; 731 interrupts_deferred = 1;
716} 732}
717 733
@@ -1470,20 +1486,16 @@ init_system_name (void)
1470 } 1486 }
1471} 1487}
1472 1488
1473/* POSIX signals support - DJB */
1474/* Anyone with POSIX signals should have ANSI C declarations */
1475
1476sigset_t empty_mask; 1489sigset_t empty_mask;
1477 1490
1478#ifndef WINDOWSNT 1491/* Store into *ACTION a signal action suitable for Emacs, with handler
1479 1492 HANDLER. */
1480signal_handler_t 1493void
1481sys_signal (int signal_number, signal_handler_t action) 1494emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
1482{ 1495{
1483 struct sigaction new_action, old_action; 1496 sigemptyset (&action->sa_mask);
1484 sigemptyset (&new_action.sa_mask); 1497 action->sa_handler = handler;
1485 new_action.sa_handler = action; 1498 action->sa_flags = 0;
1486 new_action.sa_flags = 0;
1487#if defined (SA_RESTART) 1499#if defined (SA_RESTART)
1488 /* Emacs mostly works better with restartable system services. If this 1500 /* Emacs mostly works better with restartable system services. If this
1489 flag exists, we probably want to turn it on here. 1501 flag exists, we probably want to turn it on here.
@@ -1500,56 +1512,44 @@ sys_signal (int signal_number, signal_handler_t action)
1500# if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT) 1512# if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT)
1501 if (noninteractive) 1513 if (noninteractive)
1502# endif 1514# endif
1503 new_action.sa_flags = SA_RESTART; 1515 action->sa_flags = SA_RESTART;
1504#endif 1516#endif
1505 sigaction (signal_number, &new_action, &old_action);
1506 return (old_action.sa_handler);
1507} 1517}
1508 1518
1509#endif /* WINDOWSNT */ 1519#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1510 1520pthread_t main_thread;
1511#ifndef __GNUC__
1512/* If we're compiling with GCC, we don't need this function, since it
1513 can be written as a macro. */
1514sigset_t
1515sys_sigmask (int sig)
1516{
1517 sigset_t mask;
1518 sigemptyset (&mask);
1519 sigaddset (&mask, sig);
1520 return mask;
1521}
1522#endif 1521#endif
1523 1522
1524/* I'd like to have these guys return pointers to the mask storage in here, 1523/* If we are on the main thread, handle the signal SIG with HANDLER.
1525 but there'd be trouble if the code was saving multiple masks. I'll be 1524 Otherwise, redirect the signal to the main thread, blocking it from
1526 safe and pass the structure. It normally won't be more than 2 bytes 1525 this thread. POSIX says any thread can receive a signal that is
1527 anyhow. - DJB */ 1526 associated with a process, process group, or asynchronous event.
1528 1527 On GNU/Linux that is not true, but for other systems (FreeBSD at
1529sigset_t 1528 least) it is. */
1530sys_sigblock (sigset_t new_mask) 1529void
1530handle_on_main_thread (int sig, signal_handler_t handler)
1531{ 1531{
1532 sigset_t old_mask; 1532 /* Preserve errno, to avoid race conditions with signal handlers that
1533 pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask); 1533 might change errno. Races can occur even in single-threaded hosts. */
1534 return (old_mask); 1534 int old_errno = errno;
1535}
1536 1535
1537sigset_t 1536 bool on_main_thread = true;
1538sys_sigunblock (sigset_t new_mask) 1537#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1539{ 1538 if (! pthread_equal (pthread_self (), main_thread))
1540 sigset_t old_mask; 1539 {
1541 pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask); 1540 sigset_t blocked;
1542 return (old_mask); 1541 sigemptyset (&blocked);
1543} 1542 sigaddset (&blocked, sig);
1543 pthread_sigmask (SIG_BLOCK, &blocked, 0);
1544 pthread_kill (main_thread, sig);
1545 on_main_thread = false;
1546 }
1547#endif
1548 if (on_main_thread)
1549 handler (sig);
1544 1550
1545sigset_t 1551 errno = old_errno;
1546sys_sigsetmask (sigset_t new_mask)
1547{
1548 sigset_t old_mask;
1549 pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask);
1550 return (old_mask);
1551} 1552}
1552
1553 1553
1554#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST 1554#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
1555static char *my_sys_siglist[NSIG]; 1555static char *my_sys_siglist[NSIG];
@@ -1564,6 +1564,10 @@ init_signals (void)
1564{ 1564{
1565 sigemptyset (&empty_mask); 1565 sigemptyset (&empty_mask);
1566 1566
1567#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1568 main_thread = pthread_self ();
1569#endif
1570
1567#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST 1571#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
1568 if (! initialized) 1572 if (! initialized)
1569 { 1573 {
@@ -1856,6 +1860,33 @@ snprintf (char *buf, size_t bufsize, char const *format, ...)
1856} 1860}
1857#endif 1861#endif
1858 1862
1863/* If a backtrace is available, output the top lines of it to stderr.
1864 Do not output more than BACKTRACE_LIMIT or BACKTRACE_LIMIT_MAX lines.
1865 This function may be called from a signal handler, so it should
1866 not invoke async-unsafe functions like malloc. */
1867void
1868emacs_backtrace (int backtrace_limit)
1869{
1870 enum { BACKTRACE_LIMIT_MAX = 500 };
1871 void *buffer[BACKTRACE_LIMIT_MAX + 1];
1872 int bounded_limit = min (backtrace_limit, BACKTRACE_LIMIT_MAX);
1873 int npointers = backtrace (buffer, bounded_limit + 1);
1874 if (npointers)
1875 ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12));
1876 backtrace_symbols_fd (buffer, bounded_limit, STDERR_FILENO);
1877 if (bounded_limit < npointers)
1878 ignore_value (write (STDERR_FILENO, "...\n", 4));
1879}
1880
1881#ifndef HAVE_NTGUI
1882/* Using emacs_abort lets GDB return from a breakpoint here. */
1883void
1884emacs_abort (void)
1885{
1886 fatal_error_backtrace (SIGABRT, 10);
1887}
1888#endif
1889
1859int 1890int
1860emacs_open (const char *path, int oflag, int mode) 1891emacs_open (const char *path, int oflag, int mode)
1861{ 1892{