home *** CD-ROM | disk | FTP | other *** search
/ Serving the Web / ServingTheWeb1995.disc1of1.iso / linux / slacksrce / d / libc / libc-4.6 / libc-4 / libc-linux / posix / system.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-25  |  3.3 KB  |  137 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. #if !defined(HAVE_GNU_LD) && !defined (__ELF__)
  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. #ifndef    FORK
  36. #define    FORK    __fork
  37. #endif
  38.  
  39. /* Execute LINE as a shell command, returning its status.  */
  40. int
  41. DEFUN(system, (line), register CONST char *line)
  42. {
  43.   int status, save;
  44.   pid_t pid;
  45.   struct sigaction sa, intr, quit;
  46.   sigset_t block, omask;
  47.  
  48.   if (line == NULL)
  49.     return 1;
  50.  
  51.   sa.sa_handler = SIG_IGN;
  52.   sa.sa_flags = 0;
  53.   __sigemptyset (&sa.sa_mask);
  54.  
  55.   if (__sigaction (SIGINT, &sa, &intr) < 0)
  56.     return -1;
  57.   if (__sigaction (SIGQUIT, &sa, &quit) < 0)
  58.     {
  59.       save = errno;
  60.       (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
  61.       errno = save;
  62.       return -1;
  63.     }
  64.  
  65.   __sigemptyset (&block);
  66.   __sigaddset (&block, SIGCHLD);
  67.   save = errno;
  68.   if (__sigprocmask(SIG_BLOCK, &block, &omask) < 0)
  69.     {
  70.       if (errno == ENOSYS)
  71.     errno = save;
  72.       else
  73.     {
  74.       save = errno;
  75.       (void) __sigaction(SIGINT, &intr, (struct sigaction *) NULL);
  76.       (void) __sigaction(SIGQUIT, &quit, (struct sigaction *) NULL);
  77.       errno = save;
  78.       return -1;
  79.     }
  80.     }
  81.  
  82.   pid = FORK ();
  83.   if (pid == (pid_t) 0)
  84.     {
  85.       /* Child side.  */
  86.       CONST char *new_argv[4];
  87.       new_argv[0] = SHELL_NAME;
  88.       new_argv[1] = "-c";
  89.       new_argv[2] = line;
  90.       new_argv[3] = NULL;
  91.  
  92.       /* Restore the signals.  */
  93.       (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
  94.       (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
  95.       (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
  96.  
  97.       /* Exec the shell.  */
  98.       (void) __execve (SHELL_PATH, (char *CONST *) new_argv, __environ);
  99.       _exit (127);
  100.     }
  101.   else if (pid < (pid_t) 0)
  102.     /* The fork failed.  */
  103.     status = -1;
  104.   else
  105.     /* Parent side.  */
  106. #ifdef    NO_WAITPID
  107.     {
  108.       pid_t child;
  109.       do
  110.     {
  111.       child = __wait (&status);
  112.       if (child <= -1)
  113.         {
  114.           status = -1;
  115.           break;
  116.         }
  117.     } while (child != pid);
  118.     }
  119. #else
  120.     if (__waitpid (pid, &status, 0) != pid)
  121.       status = -1;
  122. #endif
  123.  
  124.   save = errno;
  125.   if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL) |
  126.        __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) |
  127.        __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)) != 0)
  128.     {
  129.       if (errno == ENOSYS)
  130.     errno = save;
  131.       else
  132.     return -1;
  133.     }
  134.  
  135.   return status;
  136. }
  137.