diff options
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 608 |
1 files changed, 276 insertions, 332 deletions
diff --git a/src/process.c b/src/process.c index 6f48463b85b..c941a196539 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -255,11 +255,12 @@ static int keyboard_bit_set (SELECT_TYPE *); | |||
| 255 | static void deactivate_process (Lisp_Object); | 255 | static void deactivate_process (Lisp_Object); |
| 256 | static void status_notify (struct Lisp_Process *); | 256 | static void status_notify (struct Lisp_Process *); |
| 257 | static int read_process_output (Lisp_Object, int); | 257 | static int read_process_output (Lisp_Object, int); |
| 258 | static void handle_child_signal (int); | ||
| 258 | static void create_pty (Lisp_Object); | 259 | static void create_pty (Lisp_Object); |
| 259 | 260 | ||
| 260 | /* If we support a window system, turn on the code to poll periodically | 261 | /* If we support a window system, turn on the code to poll periodically |
| 261 | to detect C-g. It isn't actually used when doing interrupt input. */ | 262 | to detect C-g. It isn't actually used when doing interrupt input. */ |
| 262 | #if defined (HAVE_WINDOW_SYSTEM) && !defined (USE_ASYNC_EVENTS) | 263 | #ifdef HAVE_WINDOW_SYSTEM |
| 263 | #define POLL_FOR_INPUT | 264 | #define POLL_FOR_INPUT |
| 264 | #endif | 265 | #endif |
| 265 | 266 | ||
| @@ -334,82 +335,82 @@ static struct sockaddr_and_len { | |||
| 334 | static int pty_max_bytes; | 335 | static int pty_max_bytes; |
| 335 | 336 | ||
| 336 | /* These setters are used only in this file, so they can be private. */ | 337 | /* These setters are used only in this file, so they can be private. */ |
| 337 | static inline void | 338 | static void |
| 338 | pset_buffer (struct Lisp_Process *p, Lisp_Object val) | 339 | pset_buffer (struct Lisp_Process *p, Lisp_Object val) |
| 339 | { | 340 | { |
| 340 | p->buffer = val; | 341 | p->buffer = val; |
| 341 | } | 342 | } |
| 342 | static inline void | 343 | static void |
| 343 | pset_command (struct Lisp_Process *p, Lisp_Object val) | 344 | pset_command (struct Lisp_Process *p, Lisp_Object val) |
| 344 | { | 345 | { |
| 345 | p->command = val; | 346 | p->command = val; |
| 346 | } | 347 | } |
| 347 | static inline void | 348 | static void |
| 348 | pset_decode_coding_system (struct Lisp_Process *p, Lisp_Object val) | 349 | pset_decode_coding_system (struct Lisp_Process *p, Lisp_Object val) |
| 349 | { | 350 | { |
| 350 | p->decode_coding_system = val; | 351 | p->decode_coding_system = val; |
| 351 | } | 352 | } |
| 352 | static inline void | 353 | static void |
| 353 | pset_decoding_buf (struct Lisp_Process *p, Lisp_Object val) | 354 | pset_decoding_buf (struct Lisp_Process *p, Lisp_Object val) |
| 354 | { | 355 | { |
| 355 | p->decoding_buf = val; | 356 | p->decoding_buf = val; |
| 356 | } | 357 | } |
| 357 | static inline void | 358 | static void |
| 358 | pset_encode_coding_system (struct Lisp_Process *p, Lisp_Object val) | 359 | pset_encode_coding_system (struct Lisp_Process *p, Lisp_Object val) |
| 359 | { | 360 | { |
| 360 | p->encode_coding_system = val; | 361 | p->encode_coding_system = val; |
| 361 | } | 362 | } |
| 362 | static inline void | 363 | static void |
| 363 | pset_encoding_buf (struct Lisp_Process *p, Lisp_Object val) | 364 | pset_encoding_buf (struct Lisp_Process *p, Lisp_Object val) |
| 364 | { | 365 | { |
| 365 | p->encoding_buf = val; | 366 | p->encoding_buf = val; |
| 366 | } | 367 | } |
| 367 | static inline void | 368 | static void |
| 368 | pset_filter (struct Lisp_Process *p, Lisp_Object val) | 369 | pset_filter (struct Lisp_Process *p, Lisp_Object val) |
| 369 | { | 370 | { |
| 370 | p->filter = val; | 371 | p->filter = val; |
| 371 | } | 372 | } |
| 372 | static inline void | 373 | static void |
| 373 | pset_log (struct Lisp_Process *p, Lisp_Object val) | 374 | pset_log (struct Lisp_Process *p, Lisp_Object val) |
| 374 | { | 375 | { |
| 375 | p->log = val; | 376 | p->log = val; |
| 376 | } | 377 | } |
| 377 | static inline void | 378 | static void |
| 378 | pset_mark (struct Lisp_Process *p, Lisp_Object val) | 379 | pset_mark (struct Lisp_Process *p, Lisp_Object val) |
| 379 | { | 380 | { |
| 380 | p->mark = val; | 381 | p->mark = val; |
| 381 | } | 382 | } |
| 382 | static inline void | 383 | static void |
| 383 | pset_name (struct Lisp_Process *p, Lisp_Object val) | 384 | pset_name (struct Lisp_Process *p, Lisp_Object val) |
| 384 | { | 385 | { |
| 385 | p->name = val; | 386 | p->name = val; |
| 386 | } | 387 | } |
| 387 | static inline void | 388 | static void |
| 388 | pset_plist (struct Lisp_Process *p, Lisp_Object val) | 389 | pset_plist (struct Lisp_Process *p, Lisp_Object val) |
| 389 | { | 390 | { |
| 390 | p->plist = val; | 391 | p->plist = val; |
| 391 | } | 392 | } |
| 392 | static inline void | 393 | static void |
| 393 | pset_sentinel (struct Lisp_Process *p, Lisp_Object val) | 394 | pset_sentinel (struct Lisp_Process *p, Lisp_Object val) |
| 394 | { | 395 | { |
| 395 | p->sentinel = val; | 396 | p->sentinel = val; |
| 396 | } | 397 | } |
| 397 | static inline void | 398 | static void |
| 398 | pset_status (struct Lisp_Process *p, Lisp_Object val) | 399 | pset_status (struct Lisp_Process *p, Lisp_Object val) |
| 399 | { | 400 | { |
| 400 | p->status = val; | 401 | p->status = val; |
| 401 | } | 402 | } |
| 402 | static inline void | 403 | static void |
| 403 | pset_tty_name (struct Lisp_Process *p, Lisp_Object val) | 404 | pset_tty_name (struct Lisp_Process *p, Lisp_Object val) |
| 404 | { | 405 | { |
| 405 | p->tty_name = val; | 406 | p->tty_name = val; |
| 406 | } | 407 | } |
| 407 | static inline void | 408 | static void |
| 408 | pset_type (struct Lisp_Process *p, Lisp_Object val) | 409 | pset_type (struct Lisp_Process *p, Lisp_Object val) |
| 409 | { | 410 | { |
| 410 | p->type = val; | 411 | p->type = val; |
| 411 | } | 412 | } |
| 412 | static inline void | 413 | static void |
| 413 | pset_write_queue (struct Lisp_Process *p, Lisp_Object val) | 414 | pset_write_queue (struct Lisp_Process *p, Lisp_Object val) |
| 414 | { | 415 | { |
| 415 | p->write_queue = val; | 416 | p->write_queue = val; |
| @@ -569,7 +570,7 @@ status_message (struct Lisp_Process *p) | |||
| 569 | 570 | ||
| 570 | if (EQ (symbol, Qsignal) || EQ (symbol, Qstop)) | 571 | if (EQ (symbol, Qsignal) || EQ (symbol, Qstop)) |
| 571 | { | 572 | { |
| 572 | char *signame; | 573 | char const *signame; |
| 573 | synchronize_system_messages_locale (); | 574 | synchronize_system_messages_locale (); |
| 574 | signame = strsignal (code); | 575 | signame = strsignal (code); |
| 575 | if (signame == 0) | 576 | if (signame == 0) |
| @@ -1610,11 +1611,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1610 | int wait_child_setup[2]; | 1611 | int wait_child_setup[2]; |
| 1611 | #endif | 1612 | #endif |
| 1612 | #ifdef SIGCHLD | 1613 | #ifdef SIGCHLD |
| 1613 | sigset_t blocked, procmask; | 1614 | sigset_t blocked; |
| 1614 | #endif | 1615 | #endif |
| 1615 | /* Use volatile to protect variables from being clobbered by vfork. */ | 1616 | /* Use volatile to protect variables from being clobbered by vfork. */ |
| 1616 | volatile int forkin, forkout; | 1617 | volatile int forkin, forkout; |
| 1617 | volatile int pty_flag = 0; | 1618 | volatile int pty_flag = 0; |
| 1619 | volatile Lisp_Object lisp_pty_name = Qnil; | ||
| 1620 | volatile Lisp_Object encoded_current_dir; | ||
| 1621 | #if HAVE_WORKING_VFORK | ||
| 1622 | char **volatile save_environ; | ||
| 1623 | #endif | ||
| 1618 | 1624 | ||
| 1619 | inchannel = outchannel = -1; | 1625 | inchannel = outchannel = -1; |
| 1620 | 1626 | ||
| @@ -1640,6 +1646,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1640 | forkin = forkout = -1; | 1646 | forkin = forkout = -1; |
| 1641 | #endif /* not USG, or USG_SUBTTY_WORKS */ | 1647 | #endif /* not USG, or USG_SUBTTY_WORKS */ |
| 1642 | pty_flag = 1; | 1648 | pty_flag = 1; |
| 1649 | lisp_pty_name = build_string (pty_name); | ||
| 1643 | } | 1650 | } |
| 1644 | else | 1651 | else |
| 1645 | #endif /* HAVE_PTYS */ | 1652 | #endif /* HAVE_PTYS */ |
| @@ -1704,14 +1711,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1704 | XPROCESS (process)->pty_flag = pty_flag; | 1711 | XPROCESS (process)->pty_flag = pty_flag; |
| 1705 | pset_status (XPROCESS (process), Qrun); | 1712 | pset_status (XPROCESS (process), Qrun); |
| 1706 | 1713 | ||
| 1707 | #ifdef SIGCHLD | ||
| 1708 | /* Delay interrupts until we have a chance to store | ||
| 1709 | the new fork's pid in its process structure */ | ||
| 1710 | sigemptyset (&blocked); | ||
| 1711 | sigaddset (&blocked, SIGCHLD); | ||
| 1712 | pthread_sigmask (SIG_BLOCK, &blocked, &procmask); | ||
| 1713 | #endif | ||
| 1714 | |||
| 1715 | FD_SET (inchannel, &input_wait_mask); | 1714 | FD_SET (inchannel, &input_wait_mask); |
| 1716 | FD_SET (inchannel, &non_keyboard_wait_mask); | 1715 | FD_SET (inchannel, &non_keyboard_wait_mask); |
| 1717 | if (inchannel > max_process_desc) | 1716 | if (inchannel > max_process_desc) |
| @@ -1729,89 +1728,99 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1729 | error. */ | 1728 | error. */ |
| 1730 | setup_process_coding_systems (process); | 1729 | setup_process_coding_systems (process); |
| 1731 | 1730 | ||
| 1732 | BLOCK_INPUT; | 1731 | encoded_current_dir = ENCODE_FILE (current_dir); |
| 1733 | 1732 | ||
| 1734 | { | 1733 | block_input (); |
| 1735 | /* child_setup must clobber environ on systems with true vfork. | 1734 | |
| 1736 | Protect it from permanent change. */ | 1735 | #ifdef SIGCHLD |
| 1737 | char **save_environ = environ; | 1736 | /* Block SIGCHLD until we have a chance to store the new fork's |
| 1738 | volatile Lisp_Object encoded_current_dir = ENCODE_FILE (current_dir); | 1737 | pid in its process structure. */ |
| 1738 | sigemptyset (&blocked); | ||
| 1739 | sigaddset (&blocked, SIGCHLD); | ||
| 1740 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 1741 | #endif | ||
| 1742 | |||
| 1743 | #if HAVE_WORKING_VFORK | ||
| 1744 | /* child_setup must clobber environ on systems with true vfork. | ||
| 1745 | Protect it from permanent change. */ | ||
| 1746 | save_environ = environ; | ||
| 1747 | #endif | ||
| 1739 | 1748 | ||
| 1740 | #ifndef WINDOWSNT | 1749 | #ifndef WINDOWSNT |
| 1741 | pid = vfork (); | 1750 | pid = vfork (); |
| 1742 | if (pid == 0) | 1751 | if (pid == 0) |
| 1743 | #endif /* not WINDOWSNT */ | 1752 | #endif /* not WINDOWSNT */ |
| 1744 | { | 1753 | { |
| 1745 | int xforkin = forkin; | 1754 | int xforkin = forkin; |
| 1746 | int xforkout = forkout; | 1755 | int xforkout = forkout; |
| 1747 | 1756 | ||
| 1748 | /* Make the pty be the controlling terminal of the process. */ | 1757 | /* Make the pty be the controlling terminal of the process. */ |
| 1749 | #ifdef HAVE_PTYS | 1758 | #ifdef HAVE_PTYS |
| 1750 | /* First, disconnect its current controlling terminal. */ | 1759 | /* First, disconnect its current controlling terminal. */ |
| 1751 | #ifdef HAVE_SETSID | 1760 | #ifdef HAVE_SETSID |
| 1752 | /* We tried doing setsid only if pty_flag, but it caused | 1761 | /* We tried doing setsid only if pty_flag, but it caused |
| 1753 | process_set_signal to fail on SGI when using a pipe. */ | 1762 | process_set_signal to fail on SGI when using a pipe. */ |
| 1754 | setsid (); | 1763 | setsid (); |
| 1755 | /* Make the pty's terminal the controlling terminal. */ | 1764 | /* Make the pty's terminal the controlling terminal. */ |
| 1756 | if (pty_flag && xforkin >= 0) | 1765 | if (pty_flag && xforkin >= 0) |
| 1757 | { | 1766 | { |
| 1758 | #ifdef TIOCSCTTY | 1767 | #ifdef TIOCSCTTY |
| 1759 | /* We ignore the return value | 1768 | /* We ignore the return value |
| 1760 | because faith@cs.unc.edu says that is necessary on Linux. */ | 1769 | because faith@cs.unc.edu says that is necessary on Linux. */ |
| 1761 | ioctl (xforkin, TIOCSCTTY, 0); | 1770 | ioctl (xforkin, TIOCSCTTY, 0); |
| 1762 | #endif | 1771 | #endif |
| 1763 | } | 1772 | } |
| 1764 | #else /* not HAVE_SETSID */ | 1773 | #else /* not HAVE_SETSID */ |
| 1765 | #ifdef USG | 1774 | #ifdef USG |
| 1766 | /* It's very important to call setpgrp here and no time | 1775 | /* It's very important to call setpgrp here and no time |
| 1767 | afterwards. Otherwise, we lose our controlling tty which | 1776 | afterwards. Otherwise, we lose our controlling tty which |
| 1768 | is set when we open the pty. */ | 1777 | is set when we open the pty. */ |
| 1769 | setpgrp (); | 1778 | setpgrp (); |
| 1770 | #endif /* USG */ | 1779 | #endif /* USG */ |
| 1771 | #endif /* not HAVE_SETSID */ | 1780 | #endif /* not HAVE_SETSID */ |
| 1772 | #if defined (LDISC1) | 1781 | #if defined (LDISC1) |
| 1773 | if (pty_flag && xforkin >= 0) | 1782 | if (pty_flag && xforkin >= 0) |
| 1774 | { | 1783 | { |
| 1775 | struct termios t; | 1784 | struct termios t; |
| 1776 | tcgetattr (xforkin, &t); | 1785 | tcgetattr (xforkin, &t); |
| 1777 | t.c_lflag = LDISC1; | 1786 | t.c_lflag = LDISC1; |
| 1778 | if (tcsetattr (xforkin, TCSANOW, &t) < 0) | 1787 | if (tcsetattr (xforkin, TCSANOW, &t) < 0) |
| 1779 | emacs_write (1, "create_process/tcsetattr LDISC1 failed\n", 39); | 1788 | emacs_write (1, "create_process/tcsetattr LDISC1 failed\n", 39); |
| 1780 | } | 1789 | } |
| 1781 | #else | 1790 | #else |
| 1782 | #if defined (NTTYDISC) && defined (TIOCSETD) | 1791 | #if defined (NTTYDISC) && defined (TIOCSETD) |
| 1783 | if (pty_flag && xforkin >= 0) | 1792 | if (pty_flag && xforkin >= 0) |
| 1784 | { | 1793 | { |
| 1785 | /* Use new line discipline. */ | 1794 | /* Use new line discipline. */ |
| 1786 | int ldisc = NTTYDISC; | 1795 | int ldisc = NTTYDISC; |
| 1787 | ioctl (xforkin, TIOCSETD, &ldisc); | 1796 | ioctl (xforkin, TIOCSETD, &ldisc); |
| 1788 | } | 1797 | } |
| 1789 | #endif | 1798 | #endif |
| 1790 | #endif | 1799 | #endif |
| 1791 | #ifdef TIOCNOTTY | 1800 | #ifdef TIOCNOTTY |
| 1792 | /* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you | 1801 | /* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you |
| 1793 | can do TIOCSPGRP only to the process's controlling tty. */ | 1802 | can do TIOCSPGRP only to the process's controlling tty. */ |
| 1794 | if (pty_flag) | 1803 | if (pty_flag) |
| 1795 | { | 1804 | { |
| 1796 | /* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here? | 1805 | /* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here? |
| 1797 | I can't test it since I don't have 4.3. */ | 1806 | I can't test it since I don't have 4.3. */ |
| 1798 | int j = emacs_open ("/dev/tty", O_RDWR, 0); | 1807 | int j = emacs_open ("/dev/tty", O_RDWR, 0); |
| 1799 | if (j >= 0) | 1808 | if (j >= 0) |
| 1800 | { | 1809 | { |
| 1801 | ioctl (j, TIOCNOTTY, 0); | 1810 | ioctl (j, TIOCNOTTY, 0); |
| 1802 | emacs_close (j); | 1811 | emacs_close (j); |
| 1803 | } | 1812 | } |
| 1804 | #ifndef USG | 1813 | #ifndef USG |
| 1805 | /* In order to get a controlling terminal on some versions | 1814 | /* In order to get a controlling terminal on some versions |
| 1806 | of BSD, it is necessary to put the process in pgrp 0 | 1815 | of BSD, it is necessary to put the process in pgrp 0 |
| 1807 | before it opens the terminal. */ | 1816 | before it opens the terminal. */ |
| 1808 | #ifdef HAVE_SETPGID | 1817 | #ifdef HAVE_SETPGID |
| 1809 | setpgid (0, 0); | 1818 | setpgid (0, 0); |
| 1810 | #else | 1819 | #else |
| 1811 | setpgrp (0, 0); | 1820 | setpgrp (0, 0); |
| 1812 | #endif | 1821 | #endif |
| 1813 | #endif | 1822 | #endif |
| 1814 | } | 1823 | } |
| 1815 | #endif /* TIOCNOTTY */ | 1824 | #endif /* TIOCNOTTY */ |
| 1816 | 1825 | ||
| 1817 | #if !defined (DONT_REOPEN_PTY) | 1826 | #if !defined (DONT_REOPEN_PTY) |
| @@ -1823,70 +1832,79 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1823 | both HAVE_SETSID and TIOCSCTTY are defined. */ | 1832 | both HAVE_SETSID and TIOCSCTTY are defined. */ |
| 1824 | /* Now close the pty (if we had it open) and reopen it. | 1833 | /* Now close the pty (if we had it open) and reopen it. |
| 1825 | This makes the pty the controlling terminal of the subprocess. */ | 1834 | This makes the pty the controlling terminal of the subprocess. */ |
| 1826 | if (pty_flag) | 1835 | if (pty_flag) |
| 1827 | { | 1836 | { |
| 1828 | 1837 | ||
| 1829 | /* I wonder if emacs_close (emacs_open (pty_name, ...)) | 1838 | /* I wonder if emacs_close (emacs_open (pty_name, ...)) |
| 1830 | would work? */ | 1839 | would work? */ |
| 1831 | if (xforkin >= 0) | 1840 | if (xforkin >= 0) |
| 1832 | emacs_close (xforkin); | 1841 | emacs_close (xforkin); |
| 1833 | xforkout = xforkin = emacs_open (pty_name, O_RDWR, 0); | 1842 | xforkout = xforkin = emacs_open (pty_name, O_RDWR, 0); |
| 1834 | 1843 | ||
| 1835 | if (xforkin < 0) | 1844 | if (xforkin < 0) |
| 1836 | { | 1845 | { |
| 1837 | emacs_write (1, "Couldn't open the pty terminal ", 31); | 1846 | emacs_write (1, "Couldn't open the pty terminal ", 31); |
| 1838 | emacs_write (1, pty_name, strlen (pty_name)); | 1847 | emacs_write (1, pty_name, strlen (pty_name)); |
| 1839 | emacs_write (1, "\n", 1); | 1848 | emacs_write (1, "\n", 1); |
| 1840 | _exit (1); | 1849 | _exit (1); |
| 1841 | } | 1850 | } |
| 1842 | 1851 | ||
| 1843 | } | 1852 | } |
| 1844 | #endif /* not DONT_REOPEN_PTY */ | 1853 | #endif /* not DONT_REOPEN_PTY */ |
| 1845 | 1854 | ||
| 1846 | #ifdef SETUP_SLAVE_PTY | 1855 | #ifdef SETUP_SLAVE_PTY |
| 1847 | if (pty_flag) | 1856 | if (pty_flag) |
| 1848 | { | 1857 | { |
| 1849 | SETUP_SLAVE_PTY; | 1858 | SETUP_SLAVE_PTY; |
| 1850 | } | 1859 | } |
| 1851 | #endif /* SETUP_SLAVE_PTY */ | 1860 | #endif /* SETUP_SLAVE_PTY */ |
| 1852 | #ifdef AIX | 1861 | #ifdef AIX |
| 1853 | /* On AIX, we've disabled SIGHUP above once we start a child on a pty. | 1862 | /* On AIX, we've disabled SIGHUP above once we start a child on a pty. |
| 1854 | Now reenable it in the child, so it will die when we want it to. */ | 1863 | Now reenable it in the child, so it will die when we want it to. */ |
| 1855 | if (pty_flag) | 1864 | if (pty_flag) |
| 1856 | signal (SIGHUP, SIG_DFL); | 1865 | signal (SIGHUP, SIG_DFL); |
| 1857 | #endif | 1866 | #endif |
| 1858 | #endif /* HAVE_PTYS */ | 1867 | #endif /* HAVE_PTYS */ |
| 1859 | 1868 | ||
| 1860 | signal (SIGINT, SIG_DFL); | 1869 | signal (SIGINT, SIG_DFL); |
| 1861 | signal (SIGQUIT, SIG_DFL); | 1870 | signal (SIGQUIT, SIG_DFL); |
| 1862 | /* GConf causes us to ignore SIGPIPE, make sure it is restored | 1871 | |
| 1863 | in the child. */ | 1872 | /* Emacs ignores SIGPIPE, but the child should not. */ |
| 1864 | signal (SIGPIPE, SIG_DFL); | 1873 | signal (SIGPIPE, SIG_DFL); |
| 1865 | 1874 | ||
| 1866 | #ifdef SIGCHLD | 1875 | #ifdef SIGCHLD |
| 1867 | /* Stop blocking signals in the child. */ | 1876 | /* Stop blocking signals in the child. */ |
| 1868 | pthread_sigmask (SIG_SETMASK, &procmask, 0); | 1877 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 1869 | #endif | 1878 | #endif |
| 1870 | 1879 | ||
| 1871 | if (pty_flag) | 1880 | if (pty_flag) |
| 1872 | child_setup_tty (xforkout); | 1881 | child_setup_tty (xforkout); |
| 1873 | #ifdef WINDOWSNT | 1882 | #ifdef WINDOWSNT |
| 1874 | pid = child_setup (xforkin, xforkout, xforkout, | 1883 | pid = child_setup (xforkin, xforkout, xforkout, |
| 1875 | new_argv, 1, encoded_current_dir); | 1884 | new_argv, 1, encoded_current_dir); |
| 1876 | #else /* not WINDOWSNT */ | 1885 | #else /* not WINDOWSNT */ |
| 1877 | #ifdef FD_CLOEXEC | 1886 | #ifdef FD_CLOEXEC |
| 1878 | emacs_close (wait_child_setup[0]); | 1887 | emacs_close (wait_child_setup[0]); |
| 1879 | #endif | 1888 | #endif |
| 1880 | child_setup (xforkin, xforkout, xforkout, | 1889 | child_setup (xforkin, xforkout, xforkout, |
| 1881 | new_argv, 1, encoded_current_dir); | 1890 | new_argv, 1, encoded_current_dir); |
| 1882 | #endif /* not WINDOWSNT */ | 1891 | #endif /* not WINDOWSNT */ |
| 1883 | } | 1892 | } |
| 1884 | environ = save_environ; | ||
| 1885 | } | ||
| 1886 | 1893 | ||
| 1887 | UNBLOCK_INPUT; | 1894 | /* Back in the parent process. */ |
| 1895 | |||
| 1896 | #if HAVE_WORKING_VFORK | ||
| 1897 | environ = save_environ; | ||
| 1898 | #endif | ||
| 1899 | |||
| 1900 | XPROCESS (process)->pid = pid; | ||
| 1901 | |||
| 1902 | /* Stop blocking signals in the parent. */ | ||
| 1903 | #ifdef SIGCHLD | ||
| 1904 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | ||
| 1905 | #endif | ||
| 1906 | unblock_input (); | ||
| 1888 | 1907 | ||
| 1889 | /* This runs in the Emacs process. */ | ||
| 1890 | if (pid < 0) | 1908 | if (pid < 0) |
| 1891 | { | 1909 | { |
| 1892 | if (forkin >= 0) | 1910 | if (forkin >= 0) |
| @@ -1897,7 +1915,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1897 | else | 1915 | else |
| 1898 | { | 1916 | { |
| 1899 | /* vfork succeeded. */ | 1917 | /* vfork succeeded. */ |
| 1900 | XPROCESS (process)->pid = pid; | ||
| 1901 | 1918 | ||
| 1902 | #ifdef WINDOWSNT | 1919 | #ifdef WINDOWSNT |
| 1903 | register_child (pid, inchannel); | 1920 | register_child (pid, inchannel); |
| @@ -1923,12 +1940,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1923 | if (forkin != forkout && forkout >= 0) | 1940 | if (forkin != forkout && forkout >= 0) |
| 1924 | emacs_close (forkout); | 1941 | emacs_close (forkout); |
| 1925 | 1942 | ||
| 1926 | #ifdef HAVE_PTYS | 1943 | pset_tty_name (XPROCESS (process), lisp_pty_name); |
| 1927 | if (pty_flag) | ||
| 1928 | pset_tty_name (XPROCESS (process), build_string (pty_name)); | ||
| 1929 | else | ||
| 1930 | #endif | ||
| 1931 | pset_tty_name (XPROCESS (process), Qnil); | ||
| 1932 | 1944 | ||
| 1933 | #if !defined (WINDOWSNT) && defined (FD_CLOEXEC) | 1945 | #if !defined (WINDOWSNT) && defined (FD_CLOEXEC) |
| 1934 | /* Wait for child_setup to complete in case that vfork is | 1946 | /* Wait for child_setup to complete in case that vfork is |
| @@ -1945,11 +1957,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1945 | #endif | 1957 | #endif |
| 1946 | } | 1958 | } |
| 1947 | 1959 | ||
| 1948 | #ifdef SIGCHLD | ||
| 1949 | /* Stop blocking signals in the parent. */ | ||
| 1950 | pthread_sigmask (SIG_SETMASK, &procmask, 0); | ||
| 1951 | #endif | ||
| 1952 | |||
| 1953 | /* Now generate the error if vfork failed. */ | 1960 | /* Now generate the error if vfork failed. */ |
| 1954 | if (pid < 0) | 1961 | if (pid < 0) |
| 1955 | report_file_error ("Doing vfork", Qnil); | 1962 | report_file_error ("Doing vfork", Qnil); |
| @@ -3402,9 +3409,9 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3402 | #ifdef HAVE_GETADDRINFO | 3409 | #ifdef HAVE_GETADDRINFO |
| 3403 | if (res != &ai) | 3410 | if (res != &ai) |
| 3404 | { | 3411 | { |
| 3405 | BLOCK_INPUT; | 3412 | block_input (); |
| 3406 | freeaddrinfo (res); | 3413 | freeaddrinfo (res); |
| 3407 | UNBLOCK_INPUT; | 3414 | unblock_input (); |
| 3408 | } | 3415 | } |
| 3409 | #endif | 3416 | #endif |
| 3410 | 3417 | ||
| @@ -4372,7 +4379,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4372 | Otherwise, do pending quit if requested. */ | 4379 | Otherwise, do pending quit if requested. */ |
| 4373 | if (read_kbd >= 0) | 4380 | if (read_kbd >= 0) |
| 4374 | QUIT; | 4381 | QUIT; |
| 4375 | else | 4382 | else if (pending_signals) |
| 4376 | process_pending_signals (); | 4383 | process_pending_signals (); |
| 4377 | 4384 | ||
| 4378 | /* Exit now if the cell we're waiting for became non-nil. */ | 4385 | /* Exit now if the cell we're waiting for became non-nil. */ |
| @@ -4740,21 +4747,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4740 | check_write = 0; | 4747 | check_write = 0; |
| 4741 | } | 4748 | } |
| 4742 | 4749 | ||
| 4743 | #if 0 /* When polling is used, interrupt_input is 0, | ||
| 4744 | so get_input_pending should read the input. | ||
| 4745 | So this should not be needed. */ | ||
| 4746 | /* If we are using polling for input, | ||
| 4747 | and we see input available, make it get read now. | ||
| 4748 | Otherwise it might not actually get read for a second. | ||
| 4749 | And on hpux, since we turn off polling in wait_reading_process_output, | ||
| 4750 | it might never get read at all if we don't spend much time | ||
| 4751 | outside of wait_reading_process_output. */ | ||
| 4752 | if (read_kbd && interrupt_input | ||
| 4753 | && keyboard_bit_set (&Available) | ||
| 4754 | && input_polling_used ()) | ||
| 4755 | kill (getpid (), SIGALRM); | ||
| 4756 | #endif | ||
| 4757 | |||
| 4758 | /* Check for keyboard input */ | 4750 | /* Check for keyboard input */ |
| 4759 | /* If there is any, return immediately | 4751 | /* If there is any, return immediately |
| 4760 | to give it higher priority than subprocesses */ | 4752 | to give it higher priority than subprocesses */ |
| @@ -4818,7 +4810,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4818 | 4810 | ||
| 4819 | if (read_kbd && interrupt_input | 4811 | if (read_kbd && interrupt_input |
| 4820 | && keyboard_bit_set (&Available) && ! noninteractive) | 4812 | && keyboard_bit_set (&Available) && ! noninteractive) |
| 4821 | kill (getpid (), SIGIO); | 4813 | handle_input_available_signal (SIGIO); |
| 4822 | #endif | 4814 | #endif |
| 4823 | 4815 | ||
| 4824 | if (! wait_proc) | 4816 | if (! wait_proc) |
| @@ -4938,7 +4930,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4938 | pset_status (p, Qfailed); | 4930 | pset_status (p, Qfailed); |
| 4939 | } | 4931 | } |
| 4940 | else | 4932 | else |
| 4941 | kill (getpid (), SIGCHLD); | 4933 | handle_child_signal (SIGCHLD); |
| 4942 | } | 4934 | } |
| 4943 | #endif /* HAVE_PTYS */ | 4935 | #endif /* HAVE_PTYS */ |
| 4944 | /* If we can detect process termination, don't consider the | 4936 | /* If we can detect process termination, don't consider the |
| @@ -5394,25 +5386,6 @@ read_process_output (Lisp_Object proc, register int channel) | |||
| 5394 | 5386 | ||
| 5395 | /* Sending data to subprocess */ | 5387 | /* Sending data to subprocess */ |
| 5396 | 5388 | ||
| 5397 | static sys_jmp_buf send_process_frame; | ||
| 5398 | static Lisp_Object process_sent_to; | ||
| 5399 | |||
| 5400 | static _Noreturn void | ||
| 5401 | handle_pipe_signal (int sig) | ||
| 5402 | { | ||
| 5403 | sigset_t unblocked; | ||
| 5404 | sigemptyset (&unblocked); | ||
| 5405 | sigaddset (&unblocked, SIGPIPE); | ||
| 5406 | pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); | ||
| 5407 | sys_longjmp (send_process_frame, 1); | ||
| 5408 | } | ||
| 5409 | |||
| 5410 | static void | ||
| 5411 | deliver_pipe_signal (int sig) | ||
| 5412 | { | ||
| 5413 | handle_on_main_thread (sig, handle_pipe_signal); | ||
| 5414 | } | ||
| 5415 | |||
| 5416 | /* In send_process, when a write fails temporarily, | 5389 | /* In send_process, when a write fails temporarily, |
| 5417 | wait_reading_process_output is called. It may execute user code, | 5390 | wait_reading_process_output is called. It may execute user code, |
| 5418 | e.g. timers, that attempts to write new data to the same process. | 5391 | e.g. timers, that attempts to write new data to the same process. |
| @@ -5496,14 +5469,12 @@ write_queue_pop (struct Lisp_Process *p, Lisp_Object *obj, | |||
| 5496 | This function can evaluate Lisp code and can garbage collect. */ | 5469 | This function can evaluate Lisp code and can garbage collect. */ |
| 5497 | 5470 | ||
| 5498 | static void | 5471 | static void |
| 5499 | send_process (volatile Lisp_Object proc, const char *volatile buf, | 5472 | send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, |
| 5500 | volatile ptrdiff_t len, volatile Lisp_Object object) | 5473 | Lisp_Object object) |
| 5501 | { | 5474 | { |
| 5502 | /* Use volatile to protect variables from being clobbered by longjmp. */ | ||
| 5503 | struct Lisp_Process *p = XPROCESS (proc); | 5475 | struct Lisp_Process *p = XPROCESS (proc); |
| 5504 | ssize_t rv; | 5476 | ssize_t rv; |
| 5505 | struct coding_system *coding; | 5477 | struct coding_system *coding; |
| 5506 | struct sigaction old_sigpipe_action; | ||
| 5507 | 5478 | ||
| 5508 | if (p->raw_status_new) | 5479 | if (p->raw_status_new) |
| 5509 | update_status (p); | 5480 | update_status (p); |
| @@ -5610,145 +5581,126 @@ send_process (volatile Lisp_Object proc, const char *volatile buf, | |||
| 5610 | pty_max_bytes--; | 5581 | pty_max_bytes--; |
| 5611 | } | 5582 | } |
| 5612 | 5583 | ||
| 5613 | /* 2000-09-21: Emacs 20.7, sparc-sun-solaris-2.6, GCC 2.95.2, | 5584 | /* If there is already data in the write_queue, put the new data |
| 5614 | CFLAGS="-g -O": The value of the parameter `proc' is clobbered | 5585 | in the back of queue. Otherwise, ignore it. */ |
| 5615 | when returning with longjmp despite being declared volatile. */ | 5586 | if (!NILP (p->write_queue)) |
| 5616 | if (!sys_setjmp (send_process_frame)) | 5587 | write_queue_push (p, object, buf, len, 0); |
| 5617 | { | ||
| 5618 | p = XPROCESS (proc); /* Repair any setjmp clobbering. */ | ||
| 5619 | process_sent_to = proc; | ||
| 5620 | 5588 | ||
| 5621 | /* If there is already data in the write_queue, put the new data | 5589 | do /* while !NILP (p->write_queue) */ |
| 5622 | in the back of queue. Otherwise, ignore it. */ | 5590 | { |
| 5623 | if (!NILP (p->write_queue)) | 5591 | ptrdiff_t cur_len = -1; |
| 5624 | write_queue_push (p, object, buf, len, 0); | 5592 | const char *cur_buf; |
| 5593 | Lisp_Object cur_object; | ||
| 5625 | 5594 | ||
| 5626 | do /* while !NILP (p->write_queue) */ | 5595 | /* If write_queue is empty, ignore it. */ |
| 5596 | if (!write_queue_pop (p, &cur_object, &cur_buf, &cur_len)) | ||
| 5627 | { | 5597 | { |
| 5628 | ptrdiff_t cur_len = -1; | 5598 | cur_len = len; |
| 5629 | const char *cur_buf; | 5599 | cur_buf = buf; |
| 5630 | Lisp_Object cur_object; | 5600 | cur_object = object; |
| 5601 | } | ||
| 5631 | 5602 | ||
| 5632 | /* If write_queue is empty, ignore it. */ | 5603 | while (cur_len > 0) |
| 5633 | if (!write_queue_pop (p, &cur_object, &cur_buf, &cur_len)) | 5604 | { |
| 5605 | /* Send this batch, using one or more write calls. */ | ||
| 5606 | ptrdiff_t written = 0; | ||
| 5607 | int outfd = p->outfd; | ||
| 5608 | #ifdef DATAGRAM_SOCKETS | ||
| 5609 | if (DATAGRAM_CHAN_P (outfd)) | ||
| 5634 | { | 5610 | { |
| 5635 | cur_len = len; | 5611 | rv = sendto (outfd, cur_buf, cur_len, |
| 5636 | cur_buf = buf; | 5612 | 0, datagram_address[outfd].sa, |
| 5637 | cur_object = object; | 5613 | datagram_address[outfd].len); |
| 5614 | if (0 <= rv) | ||
| 5615 | written = rv; | ||
| 5616 | else if (errno == EMSGSIZE) | ||
| 5617 | report_file_error ("sending datagram", Fcons (proc, Qnil)); | ||
| 5638 | } | 5618 | } |
| 5639 | 5619 | else | |
| 5640 | while (cur_len > 0) | ||
| 5641 | { | ||
| 5642 | /* Send this batch, using one or more write calls. */ | ||
| 5643 | ptrdiff_t written = 0; | ||
| 5644 | int outfd = p->outfd; | ||
| 5645 | struct sigaction action; | ||
| 5646 | emacs_sigaction_init (&action, deliver_pipe_signal); | ||
| 5647 | sigaction (SIGPIPE, &action, &old_sigpipe_action); | ||
| 5648 | #ifdef DATAGRAM_SOCKETS | ||
| 5649 | if (DATAGRAM_CHAN_P (outfd)) | ||
| 5650 | { | ||
| 5651 | rv = sendto (outfd, cur_buf, cur_len, | ||
| 5652 | 0, datagram_address[outfd].sa, | ||
| 5653 | datagram_address[outfd].len); | ||
| 5654 | if (0 <= rv) | ||
| 5655 | written = rv; | ||
| 5656 | else if (errno == EMSGSIZE) | ||
| 5657 | { | ||
| 5658 | sigaction (SIGPIPE, &old_sigpipe_action, 0); | ||
| 5659 | report_file_error ("sending datagram", | ||
| 5660 | Fcons (proc, Qnil)); | ||
| 5661 | } | ||
| 5662 | } | ||
| 5663 | else | ||
| 5664 | #endif | 5620 | #endif |
| 5665 | { | 5621 | { |
| 5666 | #ifdef HAVE_GNUTLS | 5622 | #ifdef HAVE_GNUTLS |
| 5667 | if (p->gnutls_p) | 5623 | if (p->gnutls_p) |
| 5668 | written = emacs_gnutls_write (p, cur_buf, cur_len); | 5624 | written = emacs_gnutls_write (p, cur_buf, cur_len); |
| 5669 | else | 5625 | else |
| 5670 | #endif | 5626 | #endif |
| 5671 | written = emacs_write (outfd, cur_buf, cur_len); | 5627 | written = emacs_write (outfd, cur_buf, cur_len); |
| 5672 | rv = (written ? 0 : -1); | 5628 | rv = (written ? 0 : -1); |
| 5673 | #ifdef ADAPTIVE_READ_BUFFERING | 5629 | #ifdef ADAPTIVE_READ_BUFFERING |
| 5674 | if (p->read_output_delay > 0 | 5630 | if (p->read_output_delay > 0 |
| 5675 | && p->adaptive_read_buffering == 1) | 5631 | && p->adaptive_read_buffering == 1) |
| 5676 | { | 5632 | { |
| 5677 | p->read_output_delay = 0; | 5633 | p->read_output_delay = 0; |
| 5678 | process_output_delay_count--; | 5634 | process_output_delay_count--; |
| 5679 | p->read_output_skip = 0; | 5635 | p->read_output_skip = 0; |
| 5680 | } | ||
| 5681 | #endif | ||
| 5682 | } | 5636 | } |
| 5683 | sigaction (SIGPIPE, &old_sigpipe_action, 0); | 5637 | #endif |
| 5638 | } | ||
| 5684 | 5639 | ||
| 5685 | if (rv < 0) | 5640 | if (rv < 0) |
| 5686 | { | 5641 | { |
| 5687 | if (0 | 5642 | if (0 |
| 5688 | #ifdef EWOULDBLOCK | 5643 | #ifdef EWOULDBLOCK |
| 5689 | || errno == EWOULDBLOCK | 5644 | || errno == EWOULDBLOCK |
| 5690 | #endif | 5645 | #endif |
| 5691 | #ifdef EAGAIN | 5646 | #ifdef EAGAIN |
| 5692 | || errno == EAGAIN | 5647 | || errno == EAGAIN |
| 5693 | #endif | 5648 | #endif |
| 5694 | ) | 5649 | ) |
| 5695 | /* Buffer is full. Wait, accepting input; | 5650 | /* Buffer is full. Wait, accepting input; |
| 5696 | that may allow the program | 5651 | that may allow the program |
| 5697 | to finish doing output and read more. */ | 5652 | to finish doing output and read more. */ |
| 5698 | { | 5653 | { |
| 5699 | #ifdef BROKEN_PTY_READ_AFTER_EAGAIN | 5654 | #ifdef BROKEN_PTY_READ_AFTER_EAGAIN |
| 5700 | /* A gross hack to work around a bug in FreeBSD. | 5655 | /* A gross hack to work around a bug in FreeBSD. |
| 5701 | In the following sequence, read(2) returns | 5656 | In the following sequence, read(2) returns |
| 5702 | bogus data: | 5657 | bogus data: |
| 5703 | 5658 | ||
| 5704 | write(2) 1022 bytes | 5659 | write(2) 1022 bytes |
| 5705 | write(2) 954 bytes, get EAGAIN | 5660 | write(2) 954 bytes, get EAGAIN |
| 5706 | read(2) 1024 bytes in process_read_output | 5661 | read(2) 1024 bytes in process_read_output |
| 5707 | read(2) 11 bytes in process_read_output | 5662 | read(2) 11 bytes in process_read_output |
| 5708 | 5663 | ||
| 5709 | That is, read(2) returns more bytes than have | 5664 | That is, read(2) returns more bytes than have |
| 5710 | ever been written successfully. The 1033 bytes | 5665 | ever been written successfully. The 1033 bytes |
| 5711 | read are the 1022 bytes written successfully | 5666 | read are the 1022 bytes written successfully |
| 5712 | after processing (for example with CRs added if | 5667 | after processing (for example with CRs added if |
| 5713 | the terminal is set up that way which it is | 5668 | the terminal is set up that way which it is |
| 5714 | here). The same bytes will be seen again in a | 5669 | here). The same bytes will be seen again in a |
| 5715 | later read(2), without the CRs. */ | 5670 | later read(2), without the CRs. */ |
| 5716 | 5671 | ||
| 5717 | if (errno == EAGAIN) | 5672 | if (errno == EAGAIN) |
| 5718 | { | 5673 | { |
| 5719 | int flags = FWRITE; | 5674 | int flags = FWRITE; |
| 5720 | ioctl (p->outfd, TIOCFLUSH, &flags); | 5675 | ioctl (p->outfd, TIOCFLUSH, &flags); |
| 5721 | } | 5676 | } |
| 5722 | #endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ | 5677 | #endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ |
| 5723 | 5678 | ||
| 5724 | /* Put what we should have written in wait_queue. */ | 5679 | /* Put what we should have written in wait_queue. */ |
| 5725 | write_queue_push (p, cur_object, cur_buf, cur_len, 1); | 5680 | write_queue_push (p, cur_object, cur_buf, cur_len, 1); |
| 5726 | wait_reading_process_output (0, 20 * 1000 * 1000, | 5681 | wait_reading_process_output (0, 20 * 1000 * 1000, |
| 5727 | 0, 0, Qnil, NULL, 0); | 5682 | 0, 0, Qnil, NULL, 0); |
| 5728 | /* Reread queue, to see what is left. */ | 5683 | /* Reread queue, to see what is left. */ |
| 5729 | break; | 5684 | break; |
| 5730 | } | ||
| 5731 | else | ||
| 5732 | /* This is a real error. */ | ||
| 5733 | report_file_error ("writing to process", Fcons (proc, Qnil)); | ||
| 5734 | } | 5685 | } |
| 5735 | cur_buf += written; | 5686 | else if (errno == EPIPE) |
| 5736 | cur_len -= written; | 5687 | { |
| 5688 | p->raw_status_new = 0; | ||
| 5689 | pset_status (p, list2 (Qexit, make_number (256))); | ||
| 5690 | p->tick = ++process_tick; | ||
| 5691 | deactivate_process (proc); | ||
| 5692 | error ("process %s no longer connected to pipe; closed it", | ||
| 5693 | SDATA (p->name)); | ||
| 5694 | } | ||
| 5695 | else | ||
| 5696 | /* This is a real error. */ | ||
| 5697 | report_file_error ("writing to process", Fcons (proc, Qnil)); | ||
| 5737 | } | 5698 | } |
| 5699 | cur_buf += written; | ||
| 5700 | cur_len -= written; | ||
| 5738 | } | 5701 | } |
| 5739 | while (!NILP (p->write_queue)); | ||
| 5740 | } | ||
| 5741 | else | ||
| 5742 | { | ||
| 5743 | sigaction (SIGPIPE, &old_sigpipe_action, 0); | ||
| 5744 | proc = process_sent_to; | ||
| 5745 | p = XPROCESS (proc); | ||
| 5746 | p->raw_status_new = 0; | ||
| 5747 | pset_status (p, Fcons (Qexit, Fcons (make_number (256), Qnil))); | ||
| 5748 | p->tick = ++process_tick; | ||
| 5749 | deactivate_process (proc); | ||
| 5750 | error ("SIGPIPE raised on process %s; closed it", SDATA (p->name)); | ||
| 5751 | } | 5702 | } |
| 5703 | while (!NILP (p->write_queue)); | ||
| 5752 | } | 5704 | } |
| 5753 | 5705 | ||
| 5754 | DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region, | 5706 | DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region, |
| @@ -6179,39 +6131,27 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) | |||
| 6179 | #ifdef SIGUSR2 | 6131 | #ifdef SIGUSR2 |
| 6180 | parse_signal ("usr2", SIGUSR2); | 6132 | parse_signal ("usr2", SIGUSR2); |
| 6181 | #endif | 6133 | #endif |
| 6182 | #ifdef SIGTERM | ||
| 6183 | parse_signal ("term", SIGTERM); | 6134 | parse_signal ("term", SIGTERM); |
| 6184 | #endif | ||
| 6185 | #ifdef SIGHUP | 6135 | #ifdef SIGHUP |
| 6186 | parse_signal ("hup", SIGHUP); | 6136 | parse_signal ("hup", SIGHUP); |
| 6187 | #endif | 6137 | #endif |
| 6188 | #ifdef SIGINT | ||
| 6189 | parse_signal ("int", SIGINT); | 6138 | parse_signal ("int", SIGINT); |
| 6190 | #endif | ||
| 6191 | #ifdef SIGQUIT | 6139 | #ifdef SIGQUIT |
| 6192 | parse_signal ("quit", SIGQUIT); | 6140 | parse_signal ("quit", SIGQUIT); |
| 6193 | #endif | 6141 | #endif |
| 6194 | #ifdef SIGILL | ||
| 6195 | parse_signal ("ill", SIGILL); | 6142 | parse_signal ("ill", SIGILL); |
| 6196 | #endif | ||
| 6197 | #ifdef SIGABRT | ||
| 6198 | parse_signal ("abrt", SIGABRT); | 6143 | parse_signal ("abrt", SIGABRT); |
| 6199 | #endif | ||
| 6200 | #ifdef SIGEMT | 6144 | #ifdef SIGEMT |
| 6201 | parse_signal ("emt", SIGEMT); | 6145 | parse_signal ("emt", SIGEMT); |
| 6202 | #endif | 6146 | #endif |
| 6203 | #ifdef SIGKILL | 6147 | #ifdef SIGKILL |
| 6204 | parse_signal ("kill", SIGKILL); | 6148 | parse_signal ("kill", SIGKILL); |
| 6205 | #endif | 6149 | #endif |
| 6206 | #ifdef SIGFPE | ||
| 6207 | parse_signal ("fpe", SIGFPE); | 6150 | parse_signal ("fpe", SIGFPE); |
| 6208 | #endif | ||
| 6209 | #ifdef SIGBUS | 6151 | #ifdef SIGBUS |
| 6210 | parse_signal ("bus", SIGBUS); | 6152 | parse_signal ("bus", SIGBUS); |
| 6211 | #endif | 6153 | #endif |
| 6212 | #ifdef SIGSEGV | ||
| 6213 | parse_signal ("segv", SIGSEGV); | 6154 | parse_signal ("segv", SIGSEGV); |
| 6214 | #endif | ||
| 6215 | #ifdef SIGSYS | 6155 | #ifdef SIGSYS |
| 6216 | parse_signal ("sys", SIGSYS); | 6156 | parse_signal ("sys", SIGSYS); |
| 6217 | #endif | 6157 | #endif |
| @@ -6376,27 +6316,15 @@ process has been transmitted to the serial port. */) | |||
| 6376 | ** Malloc WARNING: This should never call malloc either directly or | 6316 | ** Malloc WARNING: This should never call malloc either directly or |
| 6377 | indirectly; if it does, that is a bug */ | 6317 | indirectly; if it does, that is a bug */ |
| 6378 | 6318 | ||
| 6379 | #ifdef SIGCHLD | 6319 | /* Record the changed status of the child process PID with wait status W. */ |
| 6380 | 6320 | void | |
| 6381 | /* Record one child's changed status. Return true if a child was found. */ | 6321 | record_child_status_change (pid_t pid, int w) |
| 6382 | static bool | ||
| 6383 | record_child_status_change (void) | ||
| 6384 | { | 6322 | { |
| 6323 | #ifdef SIGCHLD | ||
| 6385 | Lisp_Object proc; | 6324 | Lisp_Object proc; |
| 6386 | struct Lisp_Process *p; | 6325 | struct Lisp_Process *p; |
| 6387 | pid_t pid; | ||
| 6388 | int w; | ||
| 6389 | Lisp_Object tail; | 6326 | Lisp_Object tail; |
| 6390 | 6327 | ||
| 6391 | do | ||
| 6392 | pid = waitpid (-1, &w, WNOHANG | WUNTRACED); | ||
| 6393 | while (pid < 0 && errno == EINTR); | ||
| 6394 | |||
| 6395 | /* PID == 0 means no processes found, PID == -1 means a real failure. | ||
| 6396 | Either way, we have done all our job. */ | ||
| 6397 | if (pid <= 0) | ||
| 6398 | return false; | ||
| 6399 | |||
| 6400 | /* Find the process that signaled us, and record its status. */ | 6328 | /* Find the process that signaled us, and record its status. */ |
| 6401 | 6329 | ||
| 6402 | /* The process can have been deleted by Fdelete_process. */ | 6330 | /* The process can have been deleted by Fdelete_process. */ |
| @@ -6407,7 +6335,7 @@ record_child_status_change (void) | |||
| 6407 | || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid))) | 6335 | || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid))) |
| 6408 | { | 6336 | { |
| 6409 | XSETCAR (tail, Qnil); | 6337 | XSETCAR (tail, Qnil); |
| 6410 | return true; | 6338 | return; |
| 6411 | } | 6339 | } |
| 6412 | } | 6340 | } |
| 6413 | 6341 | ||
| @@ -6477,10 +6405,11 @@ record_child_status_change (void) | |||
| 6477 | if (input_available_clear_time) | 6405 | if (input_available_clear_time) |
| 6478 | *input_available_clear_time = make_emacs_time (0, 0); | 6406 | *input_available_clear_time = make_emacs_time (0, 0); |
| 6479 | } | 6407 | } |
| 6480 | 6408 | #endif | |
| 6481 | return true; | ||
| 6482 | } | 6409 | } |
| 6483 | 6410 | ||
| 6411 | #ifdef SIGCHLD | ||
| 6412 | |||
| 6484 | /* On some systems, the SIGCHLD handler must return right away. If | 6413 | /* On some systems, the SIGCHLD handler must return right away. If |
| 6485 | any more processes want to signal us, we will get another signal. | 6414 | any more processes want to signal us, we will get another signal. |
| 6486 | Otherwise, loop around to use up all the processes that have | 6415 | Otherwise, loop around to use up all the processes that have |
| @@ -6496,14 +6425,29 @@ enum { CAN_HANDLE_MULTIPLE_CHILDREN = 1 }; | |||
| 6496 | static void | 6425 | static void |
| 6497 | handle_child_signal (int sig) | 6426 | handle_child_signal (int sig) |
| 6498 | { | 6427 | { |
| 6499 | while (record_child_status_change () && CAN_HANDLE_MULTIPLE_CHILDREN) | 6428 | do |
| 6500 | continue; | 6429 | { |
| 6430 | pid_t pid; | ||
| 6431 | int status; | ||
| 6432 | |||
| 6433 | do | ||
| 6434 | pid = waitpid (-1, &status, WNOHANG | WUNTRACED); | ||
| 6435 | while (pid < 0 && errno == EINTR); | ||
| 6436 | |||
| 6437 | /* PID == 0 means no processes found, PID == -1 means a real failure. | ||
| 6438 | Either way, we have done all our job. */ | ||
| 6439 | if (pid <= 0) | ||
| 6440 | break; | ||
| 6441 | |||
| 6442 | record_child_status_change (pid, status); | ||
| 6443 | } | ||
| 6444 | while (CAN_HANDLE_MULTIPLE_CHILDREN); | ||
| 6501 | } | 6445 | } |
| 6502 | 6446 | ||
| 6503 | static void | 6447 | static void |
| 6504 | deliver_child_signal (int sig) | 6448 | deliver_child_signal (int sig) |
| 6505 | { | 6449 | { |
| 6506 | handle_on_main_thread (sig, handle_child_signal); | 6450 | deliver_process_signal (sig, handle_child_signal); |
| 6507 | } | 6451 | } |
| 6508 | 6452 | ||
| 6509 | #endif /* SIGCHLD */ | 6453 | #endif /* SIGCHLD */ |