diff options
| author | Paul Eggert | 2013-07-20 23:53:47 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-20 23:53:47 -0700 |
| commit | ee01079735d08d5d9481b26d89f87257ac02efff (patch) | |
| tree | 2c3d87556a649501e1ea9eea723364ad146ae7ba /src/process.c | |
| parent | 02c66599e3b30ef2119d5307099f16e2b53018da (diff) | |
| download | emacs-ee01079735d08d5d9481b26d89f87257ac02efff.tar.gz emacs-ee01079735d08d5d9481b26d89f87257ac02efff.zip | |
Avoid vfork-related deadlock more cleanly.
* callproc.c (child_setup): When the child's exec fails, output
the program name, as that's more useful. Use O_NONBLOCK to avoid
deadlock.
* process.c (create_process_1): Remove; no longer needed.
(create_process): Remove timer hack; no longer needed, now that
the child avoids deadlock.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 39 |
1 files changed, 6 insertions, 33 deletions
diff --git a/src/process.c b/src/process.c index 12035da7b58..34783fae5fd 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1599,12 +1599,6 @@ start_process_unwind (Lisp_Object proc) | |||
| 1599 | remove_process (proc); | 1599 | remove_process (proc); |
| 1600 | } | 1600 | } |
| 1601 | 1601 | ||
| 1602 | static void | ||
| 1603 | create_process_1 (struct atimer *timer) | ||
| 1604 | { | ||
| 1605 | /* Nothing to do. */ | ||
| 1606 | } | ||
| 1607 | |||
| 1608 | 1602 | ||
| 1609 | static void | 1603 | static void |
| 1610 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | 1604 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) |
| @@ -1841,14 +1835,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1841 | unblock_child_signal (); | 1835 | unblock_child_signal (); |
| 1842 | unblock_input (); | 1836 | unblock_input (); |
| 1843 | 1837 | ||
| 1838 | if (forkin >= 0) | ||
| 1839 | emacs_close (forkin); | ||
| 1840 | if (forkin != forkout && forkout >= 0) | ||
| 1841 | emacs_close (forkout); | ||
| 1842 | |||
| 1844 | if (pid < 0) | 1843 | if (pid < 0) |
| 1845 | { | 1844 | report_file_errno ("Doing vfork", Qnil, vfork_errno); |
| 1846 | if (forkin >= 0) | ||
| 1847 | emacs_close (forkin); | ||
| 1848 | if (forkin != forkout && forkout >= 0) | ||
| 1849 | emacs_close (forkout); | ||
| 1850 | report_file_errno ("Doing vfork", Qnil, vfork_errno); | ||
| 1851 | } | ||
| 1852 | else | 1845 | else |
| 1853 | { | 1846 | { |
| 1854 | /* vfork succeeded. */ | 1847 | /* vfork succeeded. */ |
| @@ -1857,26 +1850,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1857 | register_child (pid, inchannel); | 1850 | register_child (pid, inchannel); |
| 1858 | #endif /* WINDOWSNT */ | 1851 | #endif /* WINDOWSNT */ |
| 1859 | 1852 | ||
| 1860 | /* If the subfork execv fails, and it exits, | ||
| 1861 | this close hangs. I don't know why. | ||
| 1862 | So have an interrupt jar it loose. */ | ||
| 1863 | { | ||
| 1864 | struct atimer *timer; | ||
| 1865 | EMACS_TIME offset = make_emacs_time (1, 0); | ||
| 1866 | |||
| 1867 | stop_polling (); | ||
| 1868 | timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0); | ||
| 1869 | |||
| 1870 | if (forkin >= 0) | ||
| 1871 | emacs_close (forkin); | ||
| 1872 | |||
| 1873 | cancel_atimer (timer); | ||
| 1874 | start_polling (); | ||
| 1875 | } | ||
| 1876 | |||
| 1877 | if (forkin != forkout && forkout >= 0) | ||
| 1878 | emacs_close (forkout); | ||
| 1879 | |||
| 1880 | pset_tty_name (XPROCESS (process), lisp_pty_name); | 1853 | pset_tty_name (XPROCESS (process), lisp_pty_name); |
| 1881 | 1854 | ||
| 1882 | #ifndef WINDOWSNT | 1855 | #ifndef WINDOWSNT |