diff options
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 574 |
1 files changed, 259 insertions, 315 deletions
diff --git a/src/process.c b/src/process.c index c654369627d..ab215766c07 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 | ||
| @@ -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; | 1893 | |
| 1885 | } | 1894 | /* Back in the parent process. */ |
| 1895 | |||
| 1896 | #if HAVE_WORKING_VFORK | ||
| 1897 | environ = save_environ; | ||
| 1898 | #endif | ||
| 1899 | |||
| 1900 | XPROCESS (process)->pid = pid; | ||
| 1886 | 1901 | ||
| 1887 | UNBLOCK_INPUT; | 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. */ |
| @@ -4739,21 +4746,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4739 | check_write = 0; | 4746 | check_write = 0; |
| 4740 | } | 4747 | } |
| 4741 | 4748 | ||
| 4742 | #if 0 /* When polling is used, interrupt_input is 0, | ||
| 4743 | so get_input_pending should read the input. | ||
| 4744 | So this should not be needed. */ | ||
| 4745 | /* If we are using polling for input, | ||
| 4746 | and we see input available, make it get read now. | ||
| 4747 | Otherwise it might not actually get read for a second. | ||
| 4748 | And on hpux, since we turn off polling in wait_reading_process_output, | ||
| 4749 | it might never get read at all if we don't spend much time | ||
| 4750 | outside of wait_reading_process_output. */ | ||
| 4751 | if (read_kbd && interrupt_input | ||
| 4752 | && keyboard_bit_set (&Available) | ||
| 4753 | && input_polling_used ()) | ||
| 4754 | kill (getpid (), SIGALRM); | ||
| 4755 | #endif | ||
| 4756 | |||
| 4757 | /* Check for keyboard input */ | 4749 | /* Check for keyboard input */ |
| 4758 | /* If there is any, return immediately | 4750 | /* If there is any, return immediately |
| 4759 | to give it higher priority than subprocesses */ | 4751 | to give it higher priority than subprocesses */ |
| @@ -4817,7 +4809,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4817 | 4809 | ||
| 4818 | if (read_kbd && interrupt_input | 4810 | if (read_kbd && interrupt_input |
| 4819 | && keyboard_bit_set (&Available) && ! noninteractive) | 4811 | && keyboard_bit_set (&Available) && ! noninteractive) |
| 4820 | kill (getpid (), SIGIO); | 4812 | handle_input_available_signal (SIGIO); |
| 4821 | #endif | 4813 | #endif |
| 4822 | 4814 | ||
| 4823 | if (! wait_proc) | 4815 | if (! wait_proc) |
| @@ -4937,7 +4929,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4937 | pset_status (p, Qfailed); | 4929 | pset_status (p, Qfailed); |
| 4938 | } | 4930 | } |
| 4939 | else | 4931 | else |
| 4940 | kill (getpid (), SIGCHLD); | 4932 | handle_child_signal (SIGCHLD); |
| 4941 | } | 4933 | } |
| 4942 | #endif /* HAVE_PTYS */ | 4934 | #endif /* HAVE_PTYS */ |
| 4943 | /* If we can detect process termination, don't consider the | 4935 | /* If we can detect process termination, don't consider the |
| @@ -5393,25 +5385,6 @@ read_process_output (Lisp_Object proc, register int channel) | |||
| 5393 | 5385 | ||
| 5394 | /* Sending data to subprocess */ | 5386 | /* Sending data to subprocess */ |
| 5395 | 5387 | ||
| 5396 | static sys_jmp_buf send_process_frame; | ||
| 5397 | static Lisp_Object process_sent_to; | ||
| 5398 | |||
| 5399 | static _Noreturn void | ||
| 5400 | handle_pipe_signal (int sig) | ||
| 5401 | { | ||
| 5402 | sigset_t unblocked; | ||
| 5403 | sigemptyset (&unblocked); | ||
| 5404 | sigaddset (&unblocked, SIGPIPE); | ||
| 5405 | pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); | ||
| 5406 | sys_longjmp (send_process_frame, 1); | ||
| 5407 | } | ||
| 5408 | |||
| 5409 | static void | ||
| 5410 | deliver_pipe_signal (int sig) | ||
| 5411 | { | ||
| 5412 | handle_on_main_thread (sig, handle_pipe_signal); | ||
| 5413 | } | ||
| 5414 | |||
| 5415 | /* In send_process, when a write fails temporarily, | 5388 | /* In send_process, when a write fails temporarily, |
| 5416 | wait_reading_process_output is called. It may execute user code, | 5389 | wait_reading_process_output is called. It may execute user code, |
| 5417 | e.g. timers, that attempts to write new data to the same process. | 5390 | e.g. timers, that attempts to write new data to the same process. |
| @@ -5495,14 +5468,12 @@ write_queue_pop (struct Lisp_Process *p, Lisp_Object *obj, | |||
| 5495 | This function can evaluate Lisp code and can garbage collect. */ | 5468 | This function can evaluate Lisp code and can garbage collect. */ |
| 5496 | 5469 | ||
| 5497 | static void | 5470 | static void |
| 5498 | send_process (volatile Lisp_Object proc, const char *volatile buf, | 5471 | send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, |
| 5499 | volatile ptrdiff_t len, volatile Lisp_Object object) | 5472 | Lisp_Object object) |
| 5500 | { | 5473 | { |
| 5501 | /* Use volatile to protect variables from being clobbered by longjmp. */ | ||
| 5502 | struct Lisp_Process *p = XPROCESS (proc); | 5474 | struct Lisp_Process *p = XPROCESS (proc); |
| 5503 | ssize_t rv; | 5475 | ssize_t rv; |
| 5504 | struct coding_system *coding; | 5476 | struct coding_system *coding; |
| 5505 | struct sigaction old_sigpipe_action; | ||
| 5506 | 5477 | ||
| 5507 | if (p->raw_status_new) | 5478 | if (p->raw_status_new) |
| 5508 | update_status (p); | 5479 | update_status (p); |
| @@ -5609,145 +5580,126 @@ send_process (volatile Lisp_Object proc, const char *volatile buf, | |||
| 5609 | pty_max_bytes--; | 5580 | pty_max_bytes--; |
| 5610 | } | 5581 | } |
| 5611 | 5582 | ||
| 5612 | /* 2000-09-21: Emacs 20.7, sparc-sun-solaris-2.6, GCC 2.95.2, | 5583 | /* If there is already data in the write_queue, put the new data |
| 5613 | CFLAGS="-g -O": The value of the parameter `proc' is clobbered | 5584 | in the back of queue. Otherwise, ignore it. */ |
| 5614 | when returning with longjmp despite being declared volatile. */ | 5585 | if (!NILP (p->write_queue)) |
| 5615 | if (!sys_setjmp (send_process_frame)) | 5586 | write_queue_push (p, object, buf, len, 0); |
| 5616 | { | ||
| 5617 | p = XPROCESS (proc); /* Repair any setjmp clobbering. */ | ||
| 5618 | process_sent_to = proc; | ||
| 5619 | 5587 | ||
| 5620 | /* If there is already data in the write_queue, put the new data | 5588 | do /* while !NILP (p->write_queue) */ |
| 5621 | in the back of queue. Otherwise, ignore it. */ | 5589 | { |
| 5622 | if (!NILP (p->write_queue)) | 5590 | ptrdiff_t cur_len = -1; |
| 5623 | write_queue_push (p, object, buf, len, 0); | 5591 | const char *cur_buf; |
| 5592 | Lisp_Object cur_object; | ||
| 5624 | 5593 | ||
| 5625 | do /* while !NILP (p->write_queue) */ | 5594 | /* If write_queue is empty, ignore it. */ |
| 5595 | if (!write_queue_pop (p, &cur_object, &cur_buf, &cur_len)) | ||
| 5626 | { | 5596 | { |
| 5627 | ptrdiff_t cur_len = -1; | 5597 | cur_len = len; |
| 5628 | const char *cur_buf; | 5598 | cur_buf = buf; |
| 5629 | Lisp_Object cur_object; | 5599 | cur_object = object; |
| 5600 | } | ||
| 5630 | 5601 | ||
| 5631 | /* If write_queue is empty, ignore it. */ | 5602 | while (cur_len > 0) |
| 5632 | if (!write_queue_pop (p, &cur_object, &cur_buf, &cur_len)) | 5603 | { |
| 5604 | /* Send this batch, using one or more write calls. */ | ||
| 5605 | ptrdiff_t written = 0; | ||
| 5606 | int outfd = p->outfd; | ||
| 5607 | #ifdef DATAGRAM_SOCKETS | ||
| 5608 | if (DATAGRAM_CHAN_P (outfd)) | ||
| 5633 | { | 5609 | { |
| 5634 | cur_len = len; | 5610 | rv = sendto (outfd, cur_buf, cur_len, |
| 5635 | cur_buf = buf; | 5611 | 0, datagram_address[outfd].sa, |
| 5636 | cur_object = object; | 5612 | datagram_address[outfd].len); |
| 5613 | if (0 <= rv) | ||
| 5614 | written = rv; | ||
| 5615 | else if (errno == EMSGSIZE) | ||
| 5616 | report_file_error ("sending datagram", Fcons (proc, Qnil)); | ||
| 5637 | } | 5617 | } |
| 5638 | 5618 | else | |
| 5639 | while (cur_len > 0) | ||
| 5640 | { | ||
| 5641 | /* Send this batch, using one or more write calls. */ | ||
| 5642 | ptrdiff_t written = 0; | ||
| 5643 | int outfd = p->outfd; | ||
| 5644 | struct sigaction action; | ||
| 5645 | emacs_sigaction_init (&action, deliver_pipe_signal); | ||
| 5646 | sigaction (SIGPIPE, &action, &old_sigpipe_action); | ||
| 5647 | #ifdef DATAGRAM_SOCKETS | ||
| 5648 | if (DATAGRAM_CHAN_P (outfd)) | ||
| 5649 | { | ||
| 5650 | rv = sendto (outfd, cur_buf, cur_len, | ||
| 5651 | 0, datagram_address[outfd].sa, | ||
| 5652 | datagram_address[outfd].len); | ||
| 5653 | if (0 <= rv) | ||
| 5654 | written = rv; | ||
| 5655 | else if (errno == EMSGSIZE) | ||
| 5656 | { | ||
| 5657 | sigaction (SIGPIPE, &old_sigpipe_action, 0); | ||
| 5658 | report_file_error ("sending datagram", | ||
| 5659 | Fcons (proc, Qnil)); | ||
| 5660 | } | ||
| 5661 | } | ||
| 5662 | else | ||
| 5663 | #endif | 5619 | #endif |
| 5664 | { | 5620 | { |
| 5665 | #ifdef HAVE_GNUTLS | 5621 | #ifdef HAVE_GNUTLS |
| 5666 | if (p->gnutls_p) | 5622 | if (p->gnutls_p) |
| 5667 | written = emacs_gnutls_write (p, cur_buf, cur_len); | 5623 | written = emacs_gnutls_write (p, cur_buf, cur_len); |
| 5668 | else | 5624 | else |
| 5669 | #endif | 5625 | #endif |
| 5670 | written = emacs_write (outfd, cur_buf, cur_len); | 5626 | written = emacs_write (outfd, cur_buf, cur_len); |
| 5671 | rv = (written ? 0 : -1); | 5627 | rv = (written ? 0 : -1); |
| 5672 | #ifdef ADAPTIVE_READ_BUFFERING | 5628 | #ifdef ADAPTIVE_READ_BUFFERING |
| 5673 | if (p->read_output_delay > 0 | 5629 | if (p->read_output_delay > 0 |
| 5674 | && p->adaptive_read_buffering == 1) | 5630 | && p->adaptive_read_buffering == 1) |
| 5675 | { | 5631 | { |
| 5676 | p->read_output_delay = 0; | 5632 | p->read_output_delay = 0; |
| 5677 | process_output_delay_count--; | 5633 | process_output_delay_count--; |
| 5678 | p->read_output_skip = 0; | 5634 | p->read_output_skip = 0; |
| 5679 | } | ||
| 5680 | #endif | ||
| 5681 | } | 5635 | } |
| 5682 | sigaction (SIGPIPE, &old_sigpipe_action, 0); | 5636 | #endif |
| 5637 | } | ||
| 5683 | 5638 | ||
| 5684 | if (rv < 0) | 5639 | if (rv < 0) |
| 5685 | { | 5640 | { |
| 5686 | if (0 | 5641 | if (0 |
| 5687 | #ifdef EWOULDBLOCK | 5642 | #ifdef EWOULDBLOCK |
| 5688 | || errno == EWOULDBLOCK | 5643 | || errno == EWOULDBLOCK |
| 5689 | #endif | 5644 | #endif |
| 5690 | #ifdef EAGAIN | 5645 | #ifdef EAGAIN |
| 5691 | || errno == EAGAIN | 5646 | || errno == EAGAIN |
| 5692 | #endif | 5647 | #endif |
| 5693 | ) | 5648 | ) |
| 5694 | /* Buffer is full. Wait, accepting input; | 5649 | /* Buffer is full. Wait, accepting input; |
| 5695 | that may allow the program | 5650 | that may allow the program |
| 5696 | to finish doing output and read more. */ | 5651 | to finish doing output and read more. */ |
| 5697 | { | 5652 | { |
| 5698 | #ifdef BROKEN_PTY_READ_AFTER_EAGAIN | 5653 | #ifdef BROKEN_PTY_READ_AFTER_EAGAIN |
| 5699 | /* A gross hack to work around a bug in FreeBSD. | 5654 | /* A gross hack to work around a bug in FreeBSD. |
| 5700 | In the following sequence, read(2) returns | 5655 | In the following sequence, read(2) returns |
| 5701 | bogus data: | 5656 | bogus data: |
| 5702 | 5657 | ||
| 5703 | write(2) 1022 bytes | 5658 | write(2) 1022 bytes |
| 5704 | write(2) 954 bytes, get EAGAIN | 5659 | write(2) 954 bytes, get EAGAIN |
| 5705 | read(2) 1024 bytes in process_read_output | 5660 | read(2) 1024 bytes in process_read_output |
| 5706 | read(2) 11 bytes in process_read_output | 5661 | read(2) 11 bytes in process_read_output |
| 5707 | 5662 | ||
| 5708 | That is, read(2) returns more bytes than have | 5663 | That is, read(2) returns more bytes than have |
| 5709 | ever been written successfully. The 1033 bytes | 5664 | ever been written successfully. The 1033 bytes |
| 5710 | read are the 1022 bytes written successfully | 5665 | read are the 1022 bytes written successfully |
| 5711 | after processing (for example with CRs added if | 5666 | after processing (for example with CRs added if |
| 5712 | the terminal is set up that way which it is | 5667 | the terminal is set up that way which it is |
| 5713 | here). The same bytes will be seen again in a | 5668 | here). The same bytes will be seen again in a |
| 5714 | later read(2), without the CRs. */ | 5669 | later read(2), without the CRs. */ |
| 5715 | 5670 | ||
| 5716 | if (errno == EAGAIN) | 5671 | if (errno == EAGAIN) |
| 5717 | { | 5672 | { |
| 5718 | int flags = FWRITE; | 5673 | int flags = FWRITE; |
| 5719 | ioctl (p->outfd, TIOCFLUSH, &flags); | 5674 | ioctl (p->outfd, TIOCFLUSH, &flags); |
| 5720 | } | 5675 | } |
| 5721 | #endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ | 5676 | #endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ |
| 5722 | 5677 | ||
| 5723 | /* Put what we should have written in wait_queue. */ | 5678 | /* Put what we should have written in wait_queue. */ |
| 5724 | write_queue_push (p, cur_object, cur_buf, cur_len, 1); | 5679 | write_queue_push (p, cur_object, cur_buf, cur_len, 1); |
| 5725 | wait_reading_process_output (0, 20 * 1000 * 1000, | 5680 | wait_reading_process_output (0, 20 * 1000 * 1000, |
| 5726 | 0, 0, Qnil, NULL, 0); | 5681 | 0, 0, Qnil, NULL, 0); |
| 5727 | /* Reread queue, to see what is left. */ | 5682 | /* Reread queue, to see what is left. */ |
| 5728 | break; | 5683 | break; |
| 5729 | } | ||
| 5730 | else | ||
| 5731 | /* This is a real error. */ | ||
| 5732 | report_file_error ("writing to process", Fcons (proc, Qnil)); | ||
| 5733 | } | 5684 | } |
| 5734 | cur_buf += written; | 5685 | else if (errno == EPIPE) |
| 5735 | cur_len -= written; | 5686 | { |
| 5687 | p->raw_status_new = 0; | ||
| 5688 | pset_status (p, list2 (Qexit, make_number (256))); | ||
| 5689 | p->tick = ++process_tick; | ||
| 5690 | deactivate_process (proc); | ||
| 5691 | error ("process %s no longer connected to pipe; closed it", | ||
| 5692 | SDATA (p->name)); | ||
| 5693 | } | ||
| 5694 | else | ||
| 5695 | /* This is a real error. */ | ||
| 5696 | report_file_error ("writing to process", Fcons (proc, Qnil)); | ||
| 5736 | } | 5697 | } |
| 5698 | cur_buf += written; | ||
| 5699 | cur_len -= written; | ||
| 5737 | } | 5700 | } |
| 5738 | while (!NILP (p->write_queue)); | ||
| 5739 | } | ||
| 5740 | else | ||
| 5741 | { | ||
| 5742 | sigaction (SIGPIPE, &old_sigpipe_action, 0); | ||
| 5743 | proc = process_sent_to; | ||
| 5744 | p = XPROCESS (proc); | ||
| 5745 | p->raw_status_new = 0; | ||
| 5746 | pset_status (p, Fcons (Qexit, Fcons (make_number (256), Qnil))); | ||
| 5747 | p->tick = ++process_tick; | ||
| 5748 | deactivate_process (proc); | ||
| 5749 | error ("SIGPIPE raised on process %s; closed it", SDATA (p->name)); | ||
| 5750 | } | 5701 | } |
| 5702 | while (!NILP (p->write_queue)); | ||
| 5751 | } | 5703 | } |
| 5752 | 5704 | ||
| 5753 | DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region, | 5705 | DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region, |
| @@ -6178,39 +6130,27 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) | |||
| 6178 | #ifdef SIGUSR2 | 6130 | #ifdef SIGUSR2 |
| 6179 | parse_signal ("usr2", SIGUSR2); | 6131 | parse_signal ("usr2", SIGUSR2); |
| 6180 | #endif | 6132 | #endif |
| 6181 | #ifdef SIGTERM | ||
| 6182 | parse_signal ("term", SIGTERM); | 6133 | parse_signal ("term", SIGTERM); |
| 6183 | #endif | ||
| 6184 | #ifdef SIGHUP | 6134 | #ifdef SIGHUP |
| 6185 | parse_signal ("hup", SIGHUP); | 6135 | parse_signal ("hup", SIGHUP); |
| 6186 | #endif | 6136 | #endif |
| 6187 | #ifdef SIGINT | ||
| 6188 | parse_signal ("int", SIGINT); | 6137 | parse_signal ("int", SIGINT); |
| 6189 | #endif | ||
| 6190 | #ifdef SIGQUIT | 6138 | #ifdef SIGQUIT |
| 6191 | parse_signal ("quit", SIGQUIT); | 6139 | parse_signal ("quit", SIGQUIT); |
| 6192 | #endif | 6140 | #endif |
| 6193 | #ifdef SIGILL | ||
| 6194 | parse_signal ("ill", SIGILL); | 6141 | parse_signal ("ill", SIGILL); |
| 6195 | #endif | ||
| 6196 | #ifdef SIGABRT | ||
| 6197 | parse_signal ("abrt", SIGABRT); | 6142 | parse_signal ("abrt", SIGABRT); |
| 6198 | #endif | ||
| 6199 | #ifdef SIGEMT | 6143 | #ifdef SIGEMT |
| 6200 | parse_signal ("emt", SIGEMT); | 6144 | parse_signal ("emt", SIGEMT); |
| 6201 | #endif | 6145 | #endif |
| 6202 | #ifdef SIGKILL | 6146 | #ifdef SIGKILL |
| 6203 | parse_signal ("kill", SIGKILL); | 6147 | parse_signal ("kill", SIGKILL); |
| 6204 | #endif | 6148 | #endif |
| 6205 | #ifdef SIGFPE | ||
| 6206 | parse_signal ("fpe", SIGFPE); | 6149 | parse_signal ("fpe", SIGFPE); |
| 6207 | #endif | ||
| 6208 | #ifdef SIGBUS | 6150 | #ifdef SIGBUS |
| 6209 | parse_signal ("bus", SIGBUS); | 6151 | parse_signal ("bus", SIGBUS); |
| 6210 | #endif | 6152 | #endif |
| 6211 | #ifdef SIGSEGV | ||
| 6212 | parse_signal ("segv", SIGSEGV); | 6153 | parse_signal ("segv", SIGSEGV); |
| 6213 | #endif | ||
| 6214 | #ifdef SIGSYS | 6154 | #ifdef SIGSYS |
| 6215 | parse_signal ("sys", SIGSYS); | 6155 | parse_signal ("sys", SIGSYS); |
| 6216 | #endif | 6156 | #endif |
| @@ -6375,27 +6315,15 @@ process has been transmitted to the serial port. */) | |||
| 6375 | ** Malloc WARNING: This should never call malloc either directly or | 6315 | ** Malloc WARNING: This should never call malloc either directly or |
| 6376 | indirectly; if it does, that is a bug */ | 6316 | indirectly; if it does, that is a bug */ |
| 6377 | 6317 | ||
| 6378 | #ifdef SIGCHLD | 6318 | /* Record the changed status of the child process PID with wait status W. */ |
| 6379 | 6319 | void | |
| 6380 | /* Record one child's changed status. Return true if a child was found. */ | 6320 | record_child_status_change (pid_t pid, int w) |
| 6381 | static bool | ||
| 6382 | record_child_status_change (void) | ||
| 6383 | { | 6321 | { |
| 6322 | #ifdef SIGCHLD | ||
| 6384 | Lisp_Object proc; | 6323 | Lisp_Object proc; |
| 6385 | struct Lisp_Process *p; | 6324 | struct Lisp_Process *p; |
| 6386 | pid_t pid; | ||
| 6387 | int w; | ||
| 6388 | Lisp_Object tail; | 6325 | Lisp_Object tail; |
| 6389 | 6326 | ||
| 6390 | do | ||
| 6391 | pid = waitpid (-1, &w, WNOHANG | WUNTRACED); | ||
| 6392 | while (pid < 0 && errno == EINTR); | ||
| 6393 | |||
| 6394 | /* PID == 0 means no processes found, PID == -1 means a real failure. | ||
| 6395 | Either way, we have done all our job. */ | ||
| 6396 | if (pid <= 0) | ||
| 6397 | return false; | ||
| 6398 | |||
| 6399 | /* Find the process that signaled us, and record its status. */ | 6327 | /* Find the process that signaled us, and record its status. */ |
| 6400 | 6328 | ||
| 6401 | /* The process can have been deleted by Fdelete_process. */ | 6329 | /* The process can have been deleted by Fdelete_process. */ |
| @@ -6406,7 +6334,7 @@ record_child_status_change (void) | |||
| 6406 | || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid))) | 6334 | || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid))) |
| 6407 | { | 6335 | { |
| 6408 | XSETCAR (tail, Qnil); | 6336 | XSETCAR (tail, Qnil); |
| 6409 | return true; | 6337 | return; |
| 6410 | } | 6338 | } |
| 6411 | } | 6339 | } |
| 6412 | 6340 | ||
| @@ -6476,10 +6404,11 @@ record_child_status_change (void) | |||
| 6476 | if (input_available_clear_time) | 6404 | if (input_available_clear_time) |
| 6477 | *input_available_clear_time = make_emacs_time (0, 0); | 6405 | *input_available_clear_time = make_emacs_time (0, 0); |
| 6478 | } | 6406 | } |
| 6479 | 6407 | #endif | |
| 6480 | return true; | ||
| 6481 | } | 6408 | } |
| 6482 | 6409 | ||
| 6410 | #ifdef SIGCHLD | ||
| 6411 | |||
| 6483 | /* On some systems, the SIGCHLD handler must return right away. If | 6412 | /* On some systems, the SIGCHLD handler must return right away. If |
| 6484 | any more processes want to signal us, we will get another signal. | 6413 | any more processes want to signal us, we will get another signal. |
| 6485 | Otherwise, loop around to use up all the processes that have | 6414 | Otherwise, loop around to use up all the processes that have |
| @@ -6495,14 +6424,29 @@ enum { CAN_HANDLE_MULTIPLE_CHILDREN = 1 }; | |||
| 6495 | static void | 6424 | static void |
| 6496 | handle_child_signal (int sig) | 6425 | handle_child_signal (int sig) |
| 6497 | { | 6426 | { |
| 6498 | while (record_child_status_change () && CAN_HANDLE_MULTIPLE_CHILDREN) | 6427 | do |
| 6499 | continue; | 6428 | { |
| 6429 | pid_t pid; | ||
| 6430 | int status; | ||
| 6431 | |||
| 6432 | do | ||
| 6433 | pid = waitpid (-1, &status, WNOHANG | WUNTRACED); | ||
| 6434 | while (pid < 0 && errno == EINTR); | ||
| 6435 | |||
| 6436 | /* PID == 0 means no processes found, PID == -1 means a real failure. | ||
| 6437 | Either way, we have done all our job. */ | ||
| 6438 | if (pid <= 0) | ||
| 6439 | break; | ||
| 6440 | |||
| 6441 | record_child_status_change (pid, status); | ||
| 6442 | } | ||
| 6443 | while (CAN_HANDLE_MULTIPLE_CHILDREN); | ||
| 6500 | } | 6444 | } |
| 6501 | 6445 | ||
| 6502 | static void | 6446 | static void |
| 6503 | deliver_child_signal (int sig) | 6447 | deliver_child_signal (int sig) |
| 6504 | { | 6448 | { |
| 6505 | handle_on_main_thread (sig, handle_child_signal); | 6449 | deliver_process_signal (sig, handle_child_signal); |
| 6506 | } | 6450 | } |
| 6507 | 6451 | ||
| 6508 | #endif /* SIGCHLD */ | 6452 | #endif /* SIGCHLD */ |