diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/callproc.c | 31 | ||||
| -rw-r--r-- | src/lisp.h | 4 | ||||
| -rw-r--r-- | src/process.c | 10 |
3 files changed, 31 insertions, 14 deletions
diff --git a/src/callproc.c b/src/callproc.c index 8d2a5619eb8..1da315bef18 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -314,6 +314,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 314 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ | 314 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ |
| 315 | char *tempfile = NULL; | 315 | char *tempfile = NULL; |
| 316 | #else | 316 | #else |
| 317 | sigset_t oldset; | ||
| 317 | pid_t pid = -1; | 318 | pid_t pid = -1; |
| 318 | #endif | 319 | #endif |
| 319 | int child_errno; | 320 | int child_errno; |
| @@ -601,9 +602,12 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 601 | 602 | ||
| 602 | #ifndef MSDOS | 603 | #ifndef MSDOS |
| 603 | 604 | ||
| 605 | block_input (); | ||
| 606 | block_child_signal (&oldset); | ||
| 607 | |||
| 604 | child_errno | 608 | child_errno |
| 605 | = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env, | 609 | = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env, |
| 606 | SSDATA (current_dir), NULL); | 610 | SSDATA (current_dir), NULL, &oldset); |
| 607 | eassert ((child_errno == 0) == (0 < pid)); | 611 | eassert ((child_errno == 0) == (0 < pid)); |
| 608 | 612 | ||
| 609 | if (pid > 0) | 613 | if (pid > 0) |
| @@ -624,6 +628,9 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 624 | } | 628 | } |
| 625 | } | 629 | } |
| 626 | 630 | ||
| 631 | unblock_child_signal (&oldset); | ||
| 632 | unblock_input (); | ||
| 633 | |||
| 627 | if (pid < 0) | 634 | if (pid < 0) |
| 628 | report_file_errno (CHILD_SETUP_ERROR_DESC, Qnil, child_errno); | 635 | report_file_errno (CHILD_SETUP_ERROR_DESC, Qnil, child_errno); |
| 629 | 636 | ||
| @@ -1227,17 +1234,21 @@ child_setup (int in, int out, int err, char **new_argv, char **env, | |||
| 1227 | process image file ARGV[0]. Use ENVP for the environment block for | 1234 | process image file ARGV[0]. Use ENVP for the environment block for |
| 1228 | the new process. Use CWD as working directory for the new process. | 1235 | the new process. Use CWD as working directory for the new process. |
| 1229 | If PTY is not NULL, it must be a pseudoterminal device. If PTY is | 1236 | If PTY is not NULL, it must be a pseudoterminal device. If PTY is |
| 1230 | NULL, don't perform any terminal setup. */ | 1237 | NULL, don't perform any terminal setup. OLDSET must be a pointer |
| 1238 | to a signal set initialized by `block_child_signal'. Before | ||
| 1239 | calling this function, call `block_input' and `block_child_signal'; | ||
| 1240 | afterwards, call `unblock_input' and `unblock_child_signal'. Be | ||
| 1241 | sure to call `unblock_child_signal' only after registering NEWPID | ||
| 1242 | in a list where `handle_child_signal' can find it! */ | ||
| 1231 | 1243 | ||
| 1232 | int | 1244 | int |
| 1233 | emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | 1245 | emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, |
| 1234 | char **argv, char **envp, const char *cwd, const char *pty) | 1246 | char **argv, char **envp, const char *cwd, |
| 1247 | const char *pty, const sigset_t *oldset) | ||
| 1235 | { | 1248 | { |
| 1236 | sigset_t oldset; | ||
| 1237 | int pid; | 1249 | int pid; |
| 1238 | 1250 | ||
| 1239 | block_input (); | 1251 | eassert (input_blocked_p ()); |
| 1240 | block_child_signal (&oldset); | ||
| 1241 | 1252 | ||
| 1242 | #ifndef WINDOWSNT | 1253 | #ifndef WINDOWSNT |
| 1243 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 1254 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| @@ -1249,6 +1260,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1249 | int volatile stdout_volatile = std_out; | 1260 | int volatile stdout_volatile = std_out; |
| 1250 | int volatile stderr_volatile = std_err; | 1261 | int volatile stderr_volatile = std_err; |
| 1251 | char **volatile envp_volatile = envp; | 1262 | char **volatile envp_volatile = envp; |
| 1263 | const sigset_t *volatile oldset_volatile = oldset; | ||
| 1252 | 1264 | ||
| 1253 | #ifdef DARWIN_OS | 1265 | #ifdef DARWIN_OS |
| 1254 | /* Darwin doesn't let us run setsid after a vfork, so use fork when | 1266 | /* Darwin doesn't let us run setsid after a vfork, so use fork when |
| @@ -1270,6 +1282,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1270 | std_out = stdout_volatile; | 1282 | std_out = stdout_volatile; |
| 1271 | std_err = stderr_volatile; | 1283 | std_err = stderr_volatile; |
| 1272 | envp = envp_volatile; | 1284 | envp = envp_volatile; |
| 1285 | oldset = oldset_volatile; | ||
| 1273 | 1286 | ||
| 1274 | if (pid == 0) | 1287 | if (pid == 0) |
| 1275 | #endif /* not WINDOWSNT */ | 1288 | #endif /* not WINDOWSNT */ |
| @@ -1364,7 +1377,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1364 | #endif | 1377 | #endif |
| 1365 | 1378 | ||
| 1366 | /* Stop blocking SIGCHLD in the child. */ | 1379 | /* Stop blocking SIGCHLD in the child. */ |
| 1367 | unblock_child_signal (&oldset); | 1380 | unblock_child_signal (oldset); |
| 1368 | 1381 | ||
| 1369 | if (pty_flag) | 1382 | if (pty_flag) |
| 1370 | child_setup_tty (std_out); | 1383 | child_setup_tty (std_out); |
| @@ -1382,10 +1395,6 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1382 | 1395 | ||
| 1383 | int vfork_error = pid < 0 ? errno : 0; | 1396 | int vfork_error = pid < 0 ? errno : 0; |
| 1384 | 1397 | ||
| 1385 | /* Stop blocking in the parent. */ | ||
| 1386 | unblock_child_signal (&oldset); | ||
| 1387 | unblock_input (); | ||
| 1388 | |||
| 1389 | if (pid < 0) | 1398 | if (pid < 0) |
| 1390 | { | 1399 | { |
| 1391 | eassert (0 < vfork_error); | 1400 | eassert (0 < vfork_error); |
diff --git a/src/lisp.h b/src/lisp.h index ca0eb51c061..d139df93424 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4495,8 +4495,8 @@ extern void setup_process_coding_systems (Lisp_Object); | |||
| 4495 | # define CHILD_SETUP_ERROR_DESC "Doing vfork" | 4495 | # define CHILD_SETUP_ERROR_DESC "Doing vfork" |
| 4496 | #endif | 4496 | #endif |
| 4497 | 4497 | ||
| 4498 | extern int emacs_spawn (pid_t *, int, int, int, char **, char **, const char *, | 4498 | extern int emacs_spawn (pid_t *, int, int, int, char **, char **, |
| 4499 | const char *); | 4499 | const char *, const char *, const sigset_t *); |
| 4500 | extern char **make_environment_block (Lisp_Object); | 4500 | extern char **make_environment_block (Lisp_Object); |
| 4501 | extern void init_callproc_1 (void); | 4501 | extern void init_callproc_1 (void); |
| 4502 | extern void init_callproc (void); | 4502 | extern void init_callproc (void); |
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 | ||