# HG changeset patch # User Jim Blandy # Date 732664437 0 # Node ID 7f66b40a0192c14fc635dacbc1ce46a02a2136b5 # Parent f0a979beceab9089d39562f7f11d542e47176e1b * callproc.c (child_setup): Make sure that in, out, and err are not less than three. (relocate_fd): New function. diff -r f0a979beceab -r 7f66b40a0192 src/callproc.c --- a/src/callproc.c Sat Mar 20 21:07:59 1993 +0000 +++ b/src/callproc.c Sat Mar 20 21:53:57 1993 +0000 @@ -23,6 +23,11 @@ #include "config.h" +extern int errno; +#ifndef VMS +extern char *sys_errlist[]; +#endif + /* Define SIGCHLD as an alias for SIGCLD. */ #if !defined (SIGCHLD) && defined (SIGCLD) @@ -474,6 +479,14 @@ *new_env = 0; } + /* Make sure that in, out, and err are not actually already in + descriptors zero, one, or two; this could happen if Emacs is + started with its standard in, our, or error closed, as might + happen under X. */ + in = relocate_fd (in, 3); + out = relocate_fd (out, 3); + err = relocate_fd (err, 3); + close (0); close (1); close (2); @@ -507,6 +520,35 @@ _exit (1); } +/* Move the file descriptor FD so that its number is not less than MIN. + If the file descriptor is moved at all, the original is freed. */ +int +relocate_fd (fd, min) + int fd, min; +{ + if (fd >= min) + return fd; + else + { + int new = dup (fd); + if (new == -1) + { + char message1[] = + "Error while setting up child: "; + char message2[] = "\n"; + write (2, message1, sizeof (message1) - 1); + write (2, sys_errlist[errno], strlen (sys_errlist[errno])); + write (2, message2, sizeof (message2) - 1); + _exit (1); + } + /* Note that we hold the original FD open while we recurse, + to guarantee we'll get a new FD if we need it. */ + new = relocate_fd (new, min); + close (fd); + return new; + } +} + static int getenv_internal (var, varlen, value, valuelen) char *var;