home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / glibc-1.06 / sysdeps / posix / system.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-27  |  3.3 KB  |  133 lines

  1. /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <stddef.h>
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <sys/wait.h>
  24. #include <signal.h>
  25. #include <sys/types.h>
  26.  
  27.  
  28. #ifndef    HAVE_GNU_LD
  29. #define    __environ    environ
  30. #endif
  31.  
  32. #define    SHELL_PATH    "/bin/sh"    /* Path of the shell.  */
  33. #define    SHELL_NAME    "sh"        /* Name to give it.  */
  34.  
  35. /* Execute LINE as a shell command, returning its status.  */
  36. int
  37. DEFUN(system, (line), register CONST char *line)
  38. {
  39.   int status, save;
  40.   pid_t pid;
  41.   struct sigaction sa, intr, quit;
  42.   sigset_t block, omask;
  43.  
  44.   if (line == NULL)
  45.     return 1;
  46.  
  47.   sa.sa_handler = SIG_IGN;
  48.   sa.sa_flags = 0;
  49.   __sigemptyset (&sa.sa_mask);
  50.  
  51.   if (__sigaction (SIGINT, &sa, &intr) < 0)
  52.     return -1;
  53.   if (__sigaction (SIGQUIT, &sa, &quit) < 0)
  54.     {
  55.       save = errno;
  56.       (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
  57.       errno = save;
  58.       return -1;
  59.     }
  60.  
  61.   __sigemptyset (&block);
  62.   __sigaddset (&block, SIGCHLD);
  63.   save = errno;
  64.   if (__sigprocmask(SIG_BLOCK, &block, &omask) < 0)
  65.     {
  66.       if (errno == ENOSYS)
  67.     errno = save;
  68.       else
  69.     {
  70.       save = errno;
  71.       (void) __sigaction(SIGINT, &intr, (struct sigaction *) NULL);
  72.       (void) __sigaction(SIGQUIT, &quit, (struct sigaction *) NULL);
  73.       errno = save;
  74.       return -1;
  75.     }
  76.     }
  77.  
  78.   pid = __vfork ();
  79.   if (pid == (pid_t) 0)
  80.     {
  81.       /* Child side.  */
  82.       CONST char *new_argv[4];
  83.       new_argv[0] = SHELL_NAME;
  84.       new_argv[1] = "-c";
  85.       new_argv[2] = line;
  86.       new_argv[3] = NULL;
  87.  
  88.       /* Restore the signals.  */
  89.       (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
  90.       (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
  91.       (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
  92.  
  93.       /* Exec the shell.  */
  94.       (void) __execve (SHELL_PATH, (char *CONST *) new_argv, __environ);
  95.       _exit (127);
  96.     }
  97.   else if (pid < (pid_t) 0)
  98.     /* The fork failed.  */
  99.     status = -1;
  100.   else
  101.     /* Parent side.  */
  102. #ifdef    NO_WAITPID
  103.     {
  104.       pid_t child;
  105.       do
  106.     {
  107.       child = __wait (&status);
  108.       if (child <= -1)
  109.         {
  110.           status = -1;
  111.           break;
  112.         }
  113.     } while (child != pid);
  114.     }
  115. #else
  116.     if (__waitpid (pid, &status, 0) != pid)
  117.       status = -1;
  118. #endif
  119.  
  120.   save = errno;
  121.   if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL) |
  122.        __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) |
  123.        __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)) != 0)
  124.     {
  125.       if (errno == ENOSYS)
  126.     errno = save;
  127.       else
  128.     return -1;
  129.     }
  130.  
  131.   return status;
  132. }
  133.