diff src/callproc.c @ 2286:7f66b40a0192

* callproc.c (child_setup): Make sure that in, out, and err are not less than three. (relocate_fd): New function.
author Jim Blandy <jimb@redhat.com>
date Sat, 20 Mar 1993 21:53:57 +0000
parents f0d4fb2b9157
children 17a84e60603b
line wrap: on
line diff
--- 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;