diff options
| author | Philipp Stephani | 2021-01-09 21:17:42 +0100 |
|---|---|---|
| committer | Philipp Stephani | 2021-01-09 21:26:52 +0100 |
| commit | 4cebd2ded01f733957919cea9d10a67101cb7a67 (patch) | |
| tree | 03d6987b9a16f111409d2cda87d4fb413ad350ca /src/process.c | |
| parent | ace749f2e3be5b23cf4cd29c702a0e82d4d871c3 (diff) | |
| download | emacs-4cebd2ded01f733957919cea9d10a67101cb7a67.tar.gz emacs-4cebd2ded01f733957919cea9d10a67101cb7a67.zip | |
Don't unblock SIGCHLD too early.
We first need to register the received process ID so that
'handle_child_signal' checks it. Otherwise we might never call
'waitpid' for these processes, risking deadlock.
* src/callproc.c (call_process):
* src/process.c (create_process): Don't unblock SIGCHLD before
registering the process ID to wait for.
* src/callproc.c (emacs_spawn): Accept a signal set from the caller.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/process.c b/src/process.c index 06d750d3368..67e930e18f1 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -2059,6 +2059,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2059 | bool pty_flag = 0; | 2059 | bool pty_flag = 0; |
| 2060 | char pty_name[PTY_NAME_SIZE]; | 2060 | char pty_name[PTY_NAME_SIZE]; |
| 2061 | Lisp_Object lisp_pty_name = Qnil; | 2061 | Lisp_Object lisp_pty_name = Qnil; |
| 2062 | sigset_t oldset; | ||
| 2062 | 2063 | ||
| 2063 | inchannel = outchannel = -1; | 2064 | inchannel = outchannel = -1; |
| 2064 | 2065 | ||
| @@ -2139,13 +2140,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2139 | setup_process_coding_systems (process); | 2140 | setup_process_coding_systems (process); |
| 2140 | char **env = make_environment_block (current_dir); | 2141 | char **env = make_environment_block (current_dir); |
| 2141 | 2142 | ||
| 2143 | block_input (); | ||
| 2144 | block_child_signal (&oldset); | ||
| 2145 | |||
| 2142 | pty_flag = p->pty_flag; | 2146 | pty_flag = p->pty_flag; |
| 2143 | eassert (pty_flag == ! NILP (lisp_pty_name)); | 2147 | eassert (pty_flag == ! NILP (lisp_pty_name)); |
| 2144 | 2148 | ||
| 2145 | vfork_errno | 2149 | vfork_errno |
| 2146 | = emacs_spawn (&pid, forkin, forkout, forkerr, new_argv, env, | 2150 | = emacs_spawn (&pid, forkin, forkout, forkerr, new_argv, env, |
| 2147 | SSDATA (current_dir), | 2151 | SSDATA (current_dir), |
| 2148 | pty_flag ? SSDATA (lisp_pty_name) : NULL); | 2152 | pty_flag ? SSDATA (lisp_pty_name) : NULL, &oldset); |
| 2149 | 2153 | ||
| 2150 | eassert ((vfork_errno == 0) == (0 < pid)); | 2154 | eassert ((vfork_errno == 0) == (0 < pid)); |
| 2151 | 2155 | ||
| @@ -2153,6 +2157,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2153 | if (pid >= 0) | 2157 | if (pid >= 0) |
| 2154 | p->alive = 1; | 2158 | p->alive = 1; |
| 2155 | 2159 | ||
| 2160 | /* Stop blocking in the parent. */ | ||
| 2161 | unblock_child_signal (&oldset); | ||
| 2162 | unblock_input (); | ||
| 2163 | |||
| 2156 | /* Environment block no longer needed. */ | 2164 | /* Environment block no longer needed. */ |
| 2157 | unbind_to (count, Qnil); | 2165 | unbind_to (count, Qnil); |
| 2158 | 2166 | ||