diff options
| author | Paul Eggert | 2018-11-10 09:00:43 -0800 |
|---|---|---|
| committer | Paul Eggert | 2018-11-10 09:04:42 -0800 |
| commit | 9cd23a29147acb86c860ce11febe24cf837f3f8a (patch) | |
| tree | 8d13a8949a3e4f67b2b7a9e3baa2944b9f4162b5 /src | |
| parent | a062fc4137ff195fe269076cda07a61c2e1a8012 (diff) | |
| download | emacs-9cd23a29147acb86c860ce11febe24cf837f3f8a.tar.gz emacs-9cd23a29147acb86c860ce11febe24cf837f3f8a.zip | |
Dissociate controlling tty better on Darwin
* src/process.c (dissociate_controlling_tty): New function.
(create_process): Use it to dissociate controlling tty if setsid
fails, which happens on Darwin after a vfork (Bug#33154).
Do this on all platforms, not just on Darwin, as a similar
problem is plausible elsewhere.
* src/callproc.c (call_process): Use the new function here, too,
for consistency and to avoid duplicate code.
Diffstat (limited to 'src')
| -rw-r--r-- | src/callproc.c | 14 | ||||
| -rw-r--r-- | src/process.c | 40 | ||||
| -rw-r--r-- | src/process.h | 1 |
3 files changed, 24 insertions, 31 deletions
diff --git a/src/callproc.c b/src/callproc.c index a2cfd2e94da..9f47c79b81a 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -643,19 +643,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 643 | #endif | 643 | #endif |
| 644 | 644 | ||
| 645 | unblock_child_signal (&oldset); | 645 | unblock_child_signal (&oldset); |
| 646 | 646 | dissociate_controlling_tty (); | |
| 647 | #ifdef DARWIN_OS | ||
| 648 | /* Darwin doesn't let us run setsid after a vfork, so use | ||
| 649 | TIOCNOTTY when necessary. */ | ||
| 650 | int j = emacs_open (DEV_TTY, O_RDWR, 0); | ||
| 651 | if (j >= 0) | ||
| 652 | { | ||
| 653 | ioctl (j, TIOCNOTTY, 0); | ||
| 654 | emacs_close (j); | ||
| 655 | } | ||
| 656 | #else | ||
| 657 | setsid (); | ||
| 658 | #endif | ||
| 659 | 647 | ||
| 660 | /* Emacs ignores SIGPIPE, but the child should not. */ | 648 | /* Emacs ignores SIGPIPE, but the child should not. */ |
| 661 | signal (SIGPIPE, SIG_DFL); | 649 | signal (SIGPIPE, SIG_DFL); |
diff --git a/src/process.c b/src/process.c index 6cda4f27acc..7e78e172d36 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1949,6 +1949,26 @@ close_process_fd (int *fd_addr) | |||
| 1949 | } | 1949 | } |
| 1950 | } | 1950 | } |
| 1951 | 1951 | ||
| 1952 | void | ||
| 1953 | dissociate_controlling_tty (void) | ||
| 1954 | { | ||
| 1955 | if (setsid () < 0) | ||
| 1956 | { | ||
| 1957 | #ifdef TIOCNOTTY | ||
| 1958 | /* Needed on Darwin after vfork, since setsid fails in a vforked | ||
| 1959 | child that has not execed. | ||
| 1960 | I wonder: would just ioctl (fd, TIOCNOTTY, 0) work here, for | ||
| 1961 | some fd that the caller already has? */ | ||
| 1962 | int ttyfd = emacs_open (DEV_TTY, O_RDWR, 0); | ||
| 1963 | if (0 <= ttyfd) | ||
| 1964 | { | ||
| 1965 | ioctl (ttyfd, TIOCNOTTY, 0); | ||
| 1966 | emacs_close (ttyfd); | ||
| 1967 | } | ||
| 1968 | #endif | ||
| 1969 | } | ||
| 1970 | } | ||
| 1971 | |||
| 1952 | /* Indexes of file descriptors in open_fds. */ | 1972 | /* Indexes of file descriptors in open_fds. */ |
| 1953 | enum | 1973 | enum |
| 1954 | { | 1974 | { |
| @@ -2097,9 +2117,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2097 | { | 2117 | { |
| 2098 | /* Make the pty be the controlling terminal of the process. */ | 2118 | /* Make the pty be the controlling terminal of the process. */ |
| 2099 | #ifdef HAVE_PTYS | 2119 | #ifdef HAVE_PTYS |
| 2100 | /* First, disconnect its current controlling terminal. | 2120 | dissociate_controlling_tty (); |
| 2101 | Do this even if !PTY_FLAG; see Bug#30762. */ | 2121 | |
| 2102 | setsid (); | ||
| 2103 | /* Make the pty's terminal the controlling terminal. */ | 2122 | /* Make the pty's terminal the controlling terminal. */ |
| 2104 | if (pty_flag && forkin >= 0) | 2123 | if (pty_flag && forkin >= 0) |
| 2105 | { | 2124 | { |
| @@ -2128,21 +2147,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2128 | } | 2147 | } |
| 2129 | #endif | 2148 | #endif |
| 2130 | #endif | 2149 | #endif |
| 2131 | #ifdef TIOCNOTTY | ||
| 2132 | /* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you | ||
| 2133 | can do TIOCSPGRP only to the process's controlling tty. */ | ||
| 2134 | if (pty_flag) | ||
| 2135 | { | ||
| 2136 | /* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here? | ||
| 2137 | I can't test it since I don't have 4.3. */ | ||
| 2138 | int j = emacs_open (DEV_TTY, O_RDWR, 0); | ||
| 2139 | if (j >= 0) | ||
| 2140 | { | ||
| 2141 | ioctl (j, TIOCNOTTY, 0); | ||
| 2142 | emacs_close (j); | ||
| 2143 | } | ||
| 2144 | } | ||
| 2145 | #endif /* TIOCNOTTY */ | ||
| 2146 | 2150 | ||
| 2147 | #if !defined (DONT_REOPEN_PTY) | 2151 | #if !defined (DONT_REOPEN_PTY) |
| 2148 | /*** There is a suggestion that this ought to be a | 2152 | /*** There is a suggestion that this ought to be a |
diff --git a/src/process.h b/src/process.h index 3c6dd7b91f4..67b783400d8 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -300,6 +300,7 @@ extern Lisp_Object network_interface_info (Lisp_Object); | |||
| 300 | extern Lisp_Object remove_slash_colon (Lisp_Object); | 300 | extern Lisp_Object remove_slash_colon (Lisp_Object); |
| 301 | 301 | ||
| 302 | extern void update_processes_for_thread_death (Lisp_Object); | 302 | extern void update_processes_for_thread_death (Lisp_Object); |
| 303 | extern void dissociate_controlling_tty (void); | ||
| 303 | 304 | ||
| 304 | INLINE_HEADER_END | 305 | INLINE_HEADER_END |
| 305 | 306 | ||