Partially sync files.el from XEmacs 21.5 for wildcard support.
[sxemacs] / src / callproc.c
index 9d71d65..c652f17 100644 (file)
@@ -47,7 +47,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 #include "sysproc.h"
 #include "sysfile.h"           /* Always include after sysproc.h */
 #include "syssignal.h"         /* Always include before systty.h */
-#include "ui/systty.h"
+#include "ui/TTY/systty.h"
 
 
 
@@ -473,20 +473,61 @@ quit again.
        }
 }
 \f
+static int max_filedesc(void)
+{
+       /* Cache it to avoid calling getrlimit all the time.
+          It won't really change over time 
+       */
+       static int maxfd = -1;
+
+       if (maxfd >= 0)
+               return maxfd;
+       maxfd = MAXDESC;
+
+#  ifdef HAVE_GETRLIMIT64
+       struct rlimit64 rlim;
+       (void)getrlimit64(RLIMIT_NOFILE, &rlim);
+       maxfd = rlim.rlim_cur;
+#  elif  HAVE_GETRLIMIT
+       struct rlimit rlim;
+       (void)getrlimit(RLIMIT_NOFILE, &rlim);
+       maxfd = rlim.rlim_cur;
+#  endif
+
+       return maxfd;
+}
+
+
 /* Move the file descriptor FD so that its number is not less than MIN. *
    The original file descriptor remains open.  */
-static int relocate_fd(int fd, int min)
+static int relocate_fd(int fd, int minfd)
 {
-       if (fd >= min)
+       int newfd = -1;
+
+       if (minfd < 0) {
+               stderr_out("Bad relocated_fd minimum file descriptor: %d\n", 
+                          minfd);
+               _exit(1);
+       }
+       if (fd >= minfd)
                return fd;
+       
+       newfd = dup(fd);
+
+       if (newfd == -1) {
+               stderr_out("Error while setting up child: %s\n",
+                          strerror(errno));
+               _exit(1);
+       }
+       if (newfd >= minfd )
+               return newfd;
        else {
-               int newfd = dup(fd);
-               if (newfd == -1) {
-                       stderr_out("Error while setting up child: %s\n",
-                                  strerror(errno));
-                       _exit(1);
-               }
-               return relocate_fd(newfd, min);
+               int recurse_fd = relocate_fd(newfd, minfd);
+               /* Close all the previously recursivelly dup'ed
+                  file descriptors 
+               */
+               close(newfd);
+               return recurse_fd;
        }
 }
 
@@ -635,14 +676,26 @@ child_setup(int in, int out, int err, char **new_argv, const char *current_dir)
        out = relocate_fd(out, 3);
        err = relocate_fd(err, 3);
 
+
+#ifdef HAVE_DUP2
+       /* dup2 will automatically close STD* handles before duping
+          them 
+       */
+       dup2(in, STDIN_FILENO);
+       dup2(out, STDOUT_FILENO);
+       dup2(err, STDERR_FILENO);
+#else
        /* Set the standard input/output channels of the new process.  */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
 
-       dup2(in, STDIN_FILENO);
-       dup2(out, STDOUT_FILENO);
-       dup2(err, STDERR_FILENO);
+       /* Sub-optimally hoping that dup will use the just closed STD*
+          handles */
+       dup(in);
+       dup(out);
+       dup(err);
+#endif
 
        close(in);
        close(out);
@@ -655,7 +708,7 @@ child_setup(int in, int out, int err, char **new_argv, const char *current_dir)
        {
                int fd;
 
-               for (fd = 3; fd < MAXDESC; fd++)
+               for (fd = 3; fd < max_filedesc(); fd++)
                        close(fd);
        }