aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/callproc.c31
-rw-r--r--src/lisp.h4
-rw-r--r--src/process.c10
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
1232int 1244int
1233emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, 1245emacs_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
4498extern int emacs_spawn (pid_t *, int, int, int, char **, char **, const char *, 4498extern int emacs_spawn (pid_t *, int, int, int, char **, char **,
4499 const char *); 4499 const char *, const char *, const sigset_t *);
4500extern char **make_environment_block (Lisp_Object); 4500extern char **make_environment_block (Lisp_Object);
4501extern void init_callproc_1 (void); 4501extern void init_callproc_1 (void);
4502extern void init_callproc (void); 4502extern 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