about summary refs log tree commit diff
path: root/sysdeps/posix/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/posix/system.c')
-rw-r--r--sysdeps/posix/system.c37
1 files changed, 11 insertions, 26 deletions
diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
index d7e0bcf254..6df7984889 100644
--- a/sysdeps/posix/system.c
+++ b/sysdeps/posix/system.c
@@ -52,18 +52,9 @@ do_system (const char *line)
   if (__sigaction (SIGQUIT, &sa, &quit) < 0)
     {
       save = errno;
-      (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
-      __set_errno (save);
-      return -1;
+      goto out_restore_sigint;
     }
 
-#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;
@@ -74,16 +65,13 @@ do_system (const char *line)
       else
 	{
 	  save = errno;
-	  (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
 	  (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+	out_restore_sigint:
+	  (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
 	  __set_errno (save);
 	  return -1;
 	}
     }
-# define UNBLOCK __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)
-#else
-# define UNBLOCK 0
-#endif
 
   pid = __fork ();
   if (pid == (pid_t) 0)
@@ -98,7 +86,7 @@ do_system (const char *line)
       /* Restore the signals.  */
       (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
       (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
-      (void) UNBLOCK;
+      (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
 
       /* Exec the shell.  */
       (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ);
@@ -125,25 +113,22 @@ do_system (const char *line)
 	}
       while (child != pid);
 #else
-      int n;
-
-      do
-	n = __waitpid (pid, &status, 0);
-      while (n == -1 && errno == EINTR);
-
-      if (n != pid)
+      if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid)
 	status = -1;
 #endif
     }
 
   save = errno;
-  if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL) |
-       __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) |
-       UNBLOCK) != 0)
+  if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
+       | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)
+       | __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)) != 0)
     {
+#ifndef _LIBC
+      /* glibc cannot be used on systems without waitpid.  */
       if (errno == ENOSYS)
 	__set_errno (save);
       else
+#endif
 	return -1;
     }