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/callproc.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/callproc.c')
| -rw-r--r-- | src/callproc.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/src/callproc.c b/src/callproc.c index e0040ada609..282a08056f8 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -1193,6 +1193,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1193 | { | 1193 | { |
| 1194 | char **env; | 1194 | char **env; |
| 1195 | char *pwd_var; | 1195 | char *pwd_var; |
| 1196 | int exec_errno; | ||
| 1196 | #ifdef WINDOWSNT | 1197 | #ifdef WINDOWSNT |
| 1197 | int cpid; | 1198 | int cpid; |
| 1198 | HANDLE handles[3]; | 1199 | HANDLE handles[3]; |
| @@ -1368,13 +1369,16 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1368 | tcsetpgrp (0, pid); | 1369 | tcsetpgrp (0, pid); |
| 1369 | 1370 | ||
| 1370 | execve (new_argv[0], new_argv, env); | 1371 | execve (new_argv[0], new_argv, env); |
| 1372 | exec_errno = errno; | ||
| 1371 | 1373 | ||
| 1372 | /* Don't output the program name here, as it can be arbitrarily long, | 1374 | /* Avoid deadlock if the child's perror writes to a full pipe; the |
| 1373 | and a long write from a vforked child to its parent can cause a | 1375 | pipe's reader is the parent, but with vfork the parent can't |
| 1374 | deadlock. */ | 1376 | run until the child exits. Truncate the diagnostic instead. */ |
| 1375 | emacs_perror ("child process"); | 1377 | fcntl (STDERR_FILENO, F_SETFL, O_NONBLOCK); |
| 1376 | 1378 | ||
| 1377 | _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); | 1379 | errno = exec_errno; |
| 1380 | emacs_perror (new_argv[0]); | ||
| 1381 | _exit (exec_errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); | ||
| 1378 | 1382 | ||
| 1379 | #else /* MSDOS */ | 1383 | #else /* MSDOS */ |
| 1380 | pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); | 1384 | pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); |