diff options
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/src/process.c b/src/process.c index e2e337f90df..115eb8faca4 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1197,9 +1197,19 @@ create_process (process, new_argv, current_dir) | |||
| 1197 | { | 1197 | { |
| 1198 | int pid, inchannel, outchannel; | 1198 | int pid, inchannel, outchannel; |
| 1199 | int sv[2]; | 1199 | int sv[2]; |
| 1200 | #ifdef POSIX_SIGNALS | ||
| 1201 | sigset_t procmask; | ||
| 1202 | sigset_t blocked; | ||
| 1203 | struct sigaction sigint_action; | ||
| 1204 | struct sigaction sigquit_action; | ||
| 1205 | #ifdef AIX | ||
| 1206 | struct sigaction sighup_action; | ||
| 1207 | #endif | ||
| 1208 | #else /* !POSIX_SIGNALS */ | ||
| 1200 | #ifdef SIGCHLD | 1209 | #ifdef SIGCHLD |
| 1201 | SIGTYPE (*sigchld)(); | 1210 | SIGTYPE (*sigchld)(); |
| 1202 | #endif | 1211 | #endif |
| 1212 | #endif /* !POSIX_SIGNALS */ | ||
| 1203 | /* Use volatile to protect variables from being clobbered by longjmp. */ | 1213 | /* Use volatile to protect variables from being clobbered by longjmp. */ |
| 1204 | volatile int forkin, forkout; | 1214 | volatile int forkin, forkout; |
| 1205 | volatile int pty_flag = 0; | 1215 | volatile int pty_flag = 0; |
| @@ -1298,6 +1308,24 @@ create_process (process, new_argv, current_dir) | |||
| 1298 | 1308 | ||
| 1299 | /* Delay interrupts until we have a chance to store | 1309 | /* Delay interrupts until we have a chance to store |
| 1300 | the new fork's pid in its process structure */ | 1310 | the new fork's pid in its process structure */ |
| 1311 | #ifdef POSIX_SIGNALS | ||
| 1312 | sigemptyset (&blocked); | ||
| 1313 | #ifdef SIGCHLD | ||
| 1314 | sigaddset (&blocked, SIGCHLD); | ||
| 1315 | #endif | ||
| 1316 | #ifdef HAVE_VFORK | ||
| 1317 | /* On many hosts (e.g. Solaris 2.4), if a vforked child calls `signal', | ||
| 1318 | this sets the parent's signal handlers as well as the child's. | ||
| 1319 | So delay all interrupts whose handlers the child might munge, | ||
| 1320 | and record the current handlers so they can be restored later. */ | ||
| 1321 | sigaddset (&blocked, SIGINT ); sigaction (SIGINT , 0, &sigint_action ); | ||
| 1322 | sigaddset (&blocked, SIGQUIT); sigaction (SIGQUIT, 0, &sigquit_action); | ||
| 1323 | #ifdef AIX | ||
| 1324 | sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action ); | ||
| 1325 | #endif | ||
| 1326 | #endif /* HAVE_VFORK */ | ||
| 1327 | sigprocmask (SIG_BLOCK, &blocked, &procmask); | ||
| 1328 | #else /* !POSIX_SIGNALS */ | ||
| 1301 | #ifdef SIGCHLD | 1329 | #ifdef SIGCHLD |
| 1302 | #ifdef BSD4_1 | 1330 | #ifdef BSD4_1 |
| 1303 | sighold (SIGCHLD); | 1331 | sighold (SIGCHLD); |
| @@ -1312,6 +1340,7 @@ create_process (process, new_argv, current_dir) | |||
| 1312 | #endif /* ordinary USG */ | 1340 | #endif /* ordinary USG */ |
| 1313 | #endif /* not BSD4_1 */ | 1341 | #endif /* not BSD4_1 */ |
| 1314 | #endif /* SIGCHLD */ | 1342 | #endif /* SIGCHLD */ |
| 1343 | #endif /* !POSIX_SIGNALS */ | ||
| 1315 | 1344 | ||
| 1316 | FD_SET (inchannel, &input_wait_mask); | 1345 | FD_SET (inchannel, &input_wait_mask); |
| 1317 | FD_SET (inchannel, &non_keyboard_wait_mask); | 1346 | FD_SET (inchannel, &non_keyboard_wait_mask); |
| @@ -1455,6 +1484,13 @@ create_process (process, new_argv, current_dir) | |||
| 1455 | #endif | 1484 | #endif |
| 1456 | #endif /* HAVE_PTYS */ | 1485 | #endif /* HAVE_PTYS */ |
| 1457 | 1486 | ||
| 1487 | signal (SIGINT, SIG_DFL); | ||
| 1488 | signal (SIGQUIT, SIG_DFL); | ||
| 1489 | |||
| 1490 | /* Stop blocking signals in the child. */ | ||
| 1491 | #ifdef POSIX_SIGNALS | ||
| 1492 | sigprocmask (SIG_SETMASK, &procmask, 0); | ||
| 1493 | #else /* !POSIX_SIGNALS */ | ||
| 1458 | #ifdef SIGCHLD | 1494 | #ifdef SIGCHLD |
| 1459 | #ifdef BSD4_1 | 1495 | #ifdef BSD4_1 |
| 1460 | sigrelse (SIGCHLD); | 1496 | sigrelse (SIGCHLD); |
| @@ -1468,9 +1504,7 @@ create_process (process, new_argv, current_dir) | |||
| 1468 | #endif /* ordinary USG */ | 1504 | #endif /* ordinary USG */ |
| 1469 | #endif /* not BSD4_1 */ | 1505 | #endif /* not BSD4_1 */ |
| 1470 | #endif /* SIGCHLD */ | 1506 | #endif /* SIGCHLD */ |
| 1471 | 1507 | #endif /* !POSIX_SIGNALS */ | |
| 1472 | signal (SIGINT, SIG_DFL); | ||
| 1473 | signal (SIGQUIT, SIG_DFL); | ||
| 1474 | 1508 | ||
| 1475 | if (pty_flag) | 1509 | if (pty_flag) |
| 1476 | child_setup_tty (xforkout); | 1510 | child_setup_tty (xforkout); |
| @@ -1521,6 +1555,18 @@ create_process (process, new_argv, current_dir) | |||
| 1521 | #endif | 1555 | #endif |
| 1522 | XPROCESS (process)->tty_name = Qnil; | 1556 | XPROCESS (process)->tty_name = Qnil; |
| 1523 | 1557 | ||
| 1558 | #ifdef POSIX_SIGNALS | ||
| 1559 | #ifdef HAVE_VFORK | ||
| 1560 | /* Restore the parent's signal handlers. */ | ||
| 1561 | sigaction (SIGINT, &sigint_action, 0); | ||
| 1562 | sigaction (SIGQUIT, &sigquit_action, 0); | ||
| 1563 | #ifdef AIX | ||
| 1564 | sigaction (SIGHUP, &sighup_action, 0); | ||
| 1565 | #endif | ||
| 1566 | #endif /* HAVE_VFORK */ | ||
| 1567 | /* Stop blocking signals in the parent. */ | ||
| 1568 | sigprocmask (SIG_SETMASK, &procmask, 0); | ||
| 1569 | #else /* !POSIX_SIGNALS */ | ||
| 1524 | #ifdef SIGCHLD | 1570 | #ifdef SIGCHLD |
| 1525 | #ifdef BSD4_1 | 1571 | #ifdef BSD4_1 |
| 1526 | sigrelse (SIGCHLD); | 1572 | sigrelse (SIGCHLD); |
| @@ -1538,6 +1584,7 @@ create_process (process, new_argv, current_dir) | |||
| 1538 | #endif /* ordinary USG */ | 1584 | #endif /* ordinary USG */ |
| 1539 | #endif /* not BSD4_1 */ | 1585 | #endif /* not BSD4_1 */ |
| 1540 | #endif /* SIGCHLD */ | 1586 | #endif /* SIGCHLD */ |
| 1587 | #endif /* !POSIX_SIGNALS */ | ||
| 1541 | } | 1588 | } |
| 1542 | #endif /* not VMS */ | 1589 | #endif /* not VMS */ |
| 1543 | 1590 | ||