Updated from GMP 1.906.7
[kopensolaris-gnu/glibc.git] / sysdeps / posix / system.c
index 69336f0..da58be5 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -23,6 +23,7 @@ Cambridge, MA 02139, USA.  */
 #include <sys/wait.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <errno.h>
 
 
 #ifndef        HAVE_GNU_LD
@@ -32,10 +33,6 @@ Cambridge, MA 02139, USA.  */
 #define        SHELL_PATH      "/bin/sh"       /* Path of the shell.  */
 #define        SHELL_NAME      "sh"            /* Name to give it.  */
 
-#ifndef        FORK
-#define        FORK    __fork
-#endif
-
 /* Execute LINE as a shell command, returning its status.  */
 int
 DEFUN(system, (line), register CONST char *line)
@@ -43,7 +40,9 @@ DEFUN(system, (line), register CONST char *line)
   int status, save;
   pid_t pid;
   struct sigaction sa, intr, quit;
+#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD
   sigset_t block, omask;
+#endif
 
   if (line == NULL)
     return 1;
@@ -62,24 +61,35 @@ DEFUN(system, (line), register CONST char *line)
       return -1;
     }
 
+#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD
+
+/* SCO 3.2v4 has a bug where `waitpid' will never return if SIGCHLD is
+   blocked.  This makes it impossible for `system' to be implemented in
+   compliance with POSIX.2-1992.  They have acknowledged that this is a bug
+   but I have not seen nor heard of any forthcoming fix.  */
+
   __sigemptyset (&block);
   __sigaddset (&block, SIGCHLD);
   save = errno;
-  if (__sigprocmask(SIG_BLOCK, &block, &omask) < 0)
+  if (__sigprocmask (SIG_BLOCK, &block, &omask) < 0)
     {
       if (errno == ENOSYS)
        errno = save;
       else
        {
          save = errno;
-         (void) __sigaction(SIGINT, &intr, (struct sigaction *) NULL);
-         (void) __sigaction(SIGQUIT, &quit, (struct sigaction *) NULL);
+         (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+         (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
          errno = save;
          return -1;
        }
     }
+#define UNBLOCK        __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)
+#else
+#define UNBLOCK 0
+#endif
 
-  pid = FORK ();
+  pid = __vfork ();
   if (pid == (pid_t) 0)
     {
       /* Child side.  */
@@ -92,7 +102,7 @@ DEFUN(system, (line), register CONST char *line)
       /* Restore the signals.  */
       (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
       (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
-      (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
+      (void) UNBLOCK;
 
       /* Exec the shell.  */
       (void) __execve (SHELL_PATH, (char *CONST *) new_argv, __environ);
@@ -124,7 +134,7 @@ DEFUN(system, (line), register CONST char *line)
   save = errno;
   if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL) |
        __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) |
-       __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)) != 0)
+       UNBLOCK) != 0)
     {
       if (errno == ENOSYS)
        errno = save;