From 426b37aecf593645d44344ca7feace662ea3360d Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Sat, 20 Mar 1993 21:53:57 +0000 Subject: [PATCH] * callproc.c (child_setup): Make sure that in, out, and err are not less than three. (relocate_fd): New function. --- src/callproc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/callproc.c b/src/callproc.c index 383a1d74774..4b674eb9946 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -23,6 +23,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #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 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) *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 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) _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;