diff options
Diffstat (limited to 'src/sysdep.c')
| -rw-r--r-- | src/sysdep.c | 111 |
1 files changed, 38 insertions, 73 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index 42b8baf78e0..0f16d1a7645 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -22,7 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 22 | #define SYSTIME_INLINE EXTERN_INLINE | 22 | #define SYSTIME_INLINE EXTERN_INLINE |
| 23 | 23 | ||
| 24 | #include <execinfo.h> | 24 | #include <execinfo.h> |
| 25 | #include <signal.h> | ||
| 26 | #include <stdio.h> | 25 | #include <stdio.h> |
| 27 | #include <setjmp.h> | 26 | #include <setjmp.h> |
| 28 | #ifdef HAVE_PWD_H | 27 | #ifdef HAVE_PWD_H |
| @@ -303,27 +302,34 @@ wait_for_termination_1 (pid_t pid, int interruptible) | |||
| 303 | termination of subprocesses, perhaps involving a kernel bug too, | 302 | termination of subprocesses, perhaps involving a kernel bug too, |
| 304 | 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 |
| 305 | if that causes the problem to go away or get worse. */ | 304 | if that causes the problem to go away or get worse. */ |
| 306 | 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 | |||
| 307 | if (0 > kill (pid, 0)) | 310 | if (0 > kill (pid, 0)) |
| 308 | { | 311 | { |
| 309 | sigsetmask (SIGEMPTYMASK); | 312 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 310 | kill (getpid (), SIGCHLD); | 313 | kill (getpid (), SIGCHLD); |
| 311 | break; | 314 | break; |
| 312 | } | 315 | } |
| 313 | if (wait_debugging) | 316 | if (wait_debugging) |
| 314 | sleep (1); | 317 | sleep (1); |
| 315 | else | 318 | else |
| 316 | sigpause (SIGEMPTYMASK); | 319 | sigsuspend (&empty_mask); |
| 317 | #else /* not BSD_SYSTEM, and not HPUX version >= 6 */ | 320 | #else /* not BSD_SYSTEM, and not HPUX version >= 6 */ |
| 318 | #ifdef WINDOWSNT | 321 | #ifdef WINDOWSNT |
| 319 | wait (0); | 322 | wait (0); |
| 320 | break; | 323 | break; |
| 321 | #else /* not WINDOWSNT */ | 324 | #else /* not WINDOWSNT */ |
| 322 | sigblock (sigmask (SIGCHLD)); | 325 | sigset_t blocked; |
| 326 | sigemptyset (&blocked); | ||
| 327 | sigaddset (&blocked, SIGCHLD); | ||
| 328 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 323 | errno = 0; | 329 | errno = 0; |
| 324 | if (kill (pid, 0) == -1 && errno == ESRCH) | 330 | if (kill (pid, 0) == -1 && errno == ESRCH) |
| 325 | { | 331 | { |
| 326 | sigunblock (sigmask (SIGCHLD)); | 332 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); |
| 327 | break; | 333 | break; |
| 328 | } | 334 | } |
| 329 | 335 | ||
| @@ -457,11 +463,11 @@ child_setup_tty (int out) | |||
| 457 | #endif /* not MSDOS */ | 463 | #endif /* not MSDOS */ |
| 458 | 464 | ||
| 459 | 465 | ||
| 460 | /* Record a signal code and the handler for it. */ | 466 | /* Record a signal code and the action for it. */ |
| 461 | struct save_signal | 467 | struct save_signal |
| 462 | { | 468 | { |
| 463 | int code; | 469 | int code; |
| 464 | void (*handler) (int); | 470 | struct sigaction action; |
| 465 | }; | 471 | }; |
| 466 | 472 | ||
| 467 | static void save_signal_handlers (struct save_signal *); | 473 | static void save_signal_handlers (struct save_signal *); |
| @@ -619,8 +625,9 @@ save_signal_handlers (struct save_signal *saved_handlers) | |||
| 619 | { | 625 | { |
| 620 | while (saved_handlers->code) | 626 | while (saved_handlers->code) |
| 621 | { | 627 | { |
| 622 | saved_handlers->handler | 628 | struct sigaction action; |
| 623 | = (void (*) (int)) signal (saved_handlers->code, SIG_IGN); | 629 | emacs_sigaction_init (&action, SIG_IGN); |
| 630 | sigaction (saved_handlers->code, &action, &saved_handlers->action); | ||
| 624 | saved_handlers++; | 631 | saved_handlers++; |
| 625 | } | 632 | } |
| 626 | } | 633 | } |
| @@ -630,7 +637,7 @@ restore_signal_handlers (struct save_signal *saved_handlers) | |||
| 630 | { | 637 | { |
| 631 | while (saved_handlers->code) | 638 | while (saved_handlers->code) |
| 632 | { | 639 | { |
| 633 | signal (saved_handlers->code, saved_handlers->handler); | 640 | sigaction (saved_handlers->code, &saved_handlers->action, 0); |
| 634 | saved_handlers++; | 641 | saved_handlers++; |
| 635 | } | 642 | } |
| 636 | } | 643 | } |
| @@ -687,13 +694,17 @@ reset_sigio (int fd) | |||
| 687 | void | 694 | void |
| 688 | request_sigio (void) | 695 | request_sigio (void) |
| 689 | { | 696 | { |
| 697 | sigset_t unblocked; | ||
| 698 | |||
| 690 | if (noninteractive) | 699 | if (noninteractive) |
| 691 | return; | 700 | return; |
| 692 | 701 | ||
| 702 | sigemptyset (&unblocked); | ||
| 693 | #ifdef SIGWINCH | 703 | #ifdef SIGWINCH |
| 694 | sigunblock (sigmask (SIGWINCH)); | 704 | sigaddset (&unblocked, SIGWINCH); |
| 695 | #endif | 705 | #endif |
| 696 | sigunblock (sigmask (SIGIO)); | 706 | sigaddset (&unblocked, SIGIO); |
| 707 | pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); | ||
| 697 | 708 | ||
| 698 | interrupts_deferred = 0; | 709 | interrupts_deferred = 0; |
| 699 | } | 710 | } |
| @@ -701,6 +712,8 @@ request_sigio (void) | |||
| 701 | void | 712 | void |
| 702 | unrequest_sigio (void) | 713 | unrequest_sigio (void) |
| 703 | { | 714 | { |
| 715 | sigset_t blocked; | ||
| 716 | |||
| 704 | if (noninteractive) | 717 | if (noninteractive) |
| 705 | return; | 718 | return; |
| 706 | 719 | ||
| @@ -709,10 +722,12 @@ unrequest_sigio (void) | |||
| 709 | return; | 722 | return; |
| 710 | #endif | 723 | #endif |
| 711 | 724 | ||
| 725 | sigemptyset (&blocked); | ||
| 712 | #ifdef SIGWINCH | 726 | #ifdef SIGWINCH |
| 713 | sigblock (sigmask (SIGWINCH)); | 727 | sigaddset (&blocked, SIGWINCH); |
| 714 | #endif | 728 | #endif |
| 715 | sigblock (sigmask (SIGIO)); | 729 | sigaddset (&blocked, SIGIO); |
| 730 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 716 | interrupts_deferred = 1; | 731 | interrupts_deferred = 1; |
| 717 | } | 732 | } |
| 718 | 733 | ||
| @@ -1471,20 +1486,16 @@ init_system_name (void) | |||
| 1471 | } | 1486 | } |
| 1472 | } | 1487 | } |
| 1473 | 1488 | ||
| 1474 | /* POSIX signals support - DJB */ | ||
| 1475 | /* Anyone with POSIX signals should have ANSI C declarations */ | ||
| 1476 | |||
| 1477 | sigset_t empty_mask; | 1489 | sigset_t empty_mask; |
| 1478 | 1490 | ||
| 1479 | #ifndef WINDOWSNT | 1491 | /* Store into *ACTION a signal action suitable for Emacs, with handler |
| 1480 | 1492 | HANDLER. */ | |
| 1481 | signal_handler_t | 1493 | void |
| 1482 | sys_signal (int signal_number, signal_handler_t action) | 1494 | emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) |
| 1483 | { | 1495 | { |
| 1484 | struct sigaction new_action, old_action; | 1496 | sigemptyset (&action->sa_mask); |
| 1485 | sigemptyset (&new_action.sa_mask); | 1497 | action->sa_handler = handler; |
| 1486 | new_action.sa_handler = action; | 1498 | action->sa_flags = 0; |
| 1487 | new_action.sa_flags = 0; | ||
| 1488 | #if defined (SA_RESTART) | 1499 | #if defined (SA_RESTART) |
| 1489 | /* Emacs mostly works better with restartable system services. If this | 1500 | /* Emacs mostly works better with restartable system services. If this |
| 1490 | flag exists, we probably want to turn it on here. | 1501 | flag exists, we probably want to turn it on here. |
| @@ -1501,54 +1512,8 @@ sys_signal (int signal_number, signal_handler_t action) | |||
| 1501 | # if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT) | 1512 | # if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT) |
| 1502 | if (noninteractive) | 1513 | if (noninteractive) |
| 1503 | # endif | 1514 | # endif |
| 1504 | new_action.sa_flags = SA_RESTART; | 1515 | action->sa_flags = SA_RESTART; |
| 1505 | #endif | 1516 | #endif |
| 1506 | sigaction (signal_number, &new_action, &old_action); | ||
| 1507 | return (old_action.sa_handler); | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | #endif /* WINDOWSNT */ | ||
| 1511 | |||
| 1512 | #ifndef __GNUC__ | ||
| 1513 | /* If we're compiling with GCC, we don't need this function, since it | ||
| 1514 | can be written as a macro. */ | ||
| 1515 | sigset_t | ||
| 1516 | sys_sigmask (int sig) | ||
| 1517 | { | ||
| 1518 | sigset_t mask; | ||
| 1519 | sigemptyset (&mask); | ||
| 1520 | sigaddset (&mask, sig); | ||
| 1521 | return mask; | ||
| 1522 | } | ||
| 1523 | #endif | ||
| 1524 | |||
| 1525 | /* I'd like to have these guys return pointers to the mask storage in here, | ||
| 1526 | but there'd be trouble if the code was saving multiple masks. I'll be | ||
| 1527 | safe and pass the structure. It normally won't be more than 2 bytes | ||
| 1528 | anyhow. - DJB */ | ||
| 1529 | |||
| 1530 | sigset_t | ||
| 1531 | sys_sigblock (sigset_t new_mask) | ||
| 1532 | { | ||
| 1533 | sigset_t old_mask; | ||
| 1534 | pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask); | ||
| 1535 | return (old_mask); | ||
| 1536 | } | ||
| 1537 | |||
| 1538 | sigset_t | ||
| 1539 | sys_sigunblock (sigset_t new_mask) | ||
| 1540 | { | ||
| 1541 | sigset_t old_mask; | ||
| 1542 | pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask); | ||
| 1543 | return (old_mask); | ||
| 1544 | } | ||
| 1545 | |||
| 1546 | sigset_t | ||
| 1547 | sys_sigsetmask (sigset_t new_mask) | ||
| 1548 | { | ||
| 1549 | sigset_t old_mask; | ||
| 1550 | pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask); | ||
| 1551 | return (old_mask); | ||
| 1552 | } | 1517 | } |
| 1553 | 1518 | ||
| 1554 | #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD | 1519 | #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD |