root/glibcsystem.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_system

   1 /* Copyright (C) 1991-2000,2002,2003,2005,2007 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 Lesser General Public
   6    License as published by the Free Software Foundation; either
   7    version 2.1 of the 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    Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser General Public
  15    License along with DMTCP:dmtcp/src.  If not, see
  16    <http://www.gnu.org/licenses/>.  */
  17 
  18 /*
  19  * This code is a simplified version of do_system() from glibc-2.9.
  20  * Its primary use is to be called by the wrapper, execwrappers.cpp:system().
  21  * This way, calls to system() go to our do_system(), which inherits our
  22  * wrappers around fork/exec.
  23  *   Without this, any call to system() would go directly to glibc, where
  24  * it would pick up the _unwrapped_ versions of fork/exec already defined
  25  * in glibc.  If you really want an unwrapped version of glibc's system(),
  26  * then call execwrappers.cpp:_real_system().
  27  */
  28 #include <errno.h>
  29 #include <unistd.h>
  30 #include <sys/types.h>
  31 #include <sys/wait.h>
  32 
  33 #define  SHELL_PATH  "/bin/sh"  /* Path of the shell.  */
  34 #define  SHELL_NAME  "sh"    /* Name to give it.  */
  35 
  36 /* Execute LINE as a shell command, returning its status.  */
  37 __attribute__ ((visibility ("hidden")))
  38 int do_system (const char *line)
  39 {
  40   int status, save;
  41   pid_t pid;
  42   struct sigaction sa;
  43   struct sigaction intr, quit;
  44   sigset_t omask;
  45 
  46   sa.sa_handler = SIG_IGN;
  47   sa.sa_flags = 0;
  48   sigemptyset (&sa.sa_mask);
  49 
  50   if (sigaction (SIGINT, &sa, &intr) < 0) {
  51     goto out;
  52   }
  53   if (sigaction (SIGQUIT, &sa, &quit) < 0) {
  54     save = errno;
  55     goto out_restore_sigint;
  56   }
  57 
  58   /* We reuse the bitmap in the 'sa' structure.  */
  59   sigaddset (&sa.sa_mask, SIGCHLD);
  60   save = errno;
  61   if (sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0) {
  62     if (errno == ENOSYS) {
  63       errno = save;
  64     } else {
  65       save = errno;
  66       (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
  67 out_restore_sigint:
  68       (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
  69       errno = save;
  70       //set_errno (save);
  71 out:
  72       return -1;
  73     }
  74   }
  75 
  76   pid = fork ();
  77   if (pid == (pid_t) 0) {
  78     /* Child side.  */
  79     const char *new_argv[4];
  80     new_argv[0] = SHELL_NAME;
  81     new_argv[1] = "-c";
  82     new_argv[2] = line;
  83     new_argv[3] = NULL;
  84 
  85     /* Restore the signals.  */
  86     (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
  87     (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
  88     (void) sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
  89 
  90     /* Exec the shell.  */
  91     (void) execve (SHELL_PATH, (char *const *) new_argv, __environ);
  92     _exit (127);
  93   } else if (pid < (pid_t) 0) {
  94     /* The fork failed.  */
  95     status = -1;
  96   } else {
  97     /* Parent side.  */
  98     /* Note that system() is a cancellation point.  But since we call
  99        waitpid() which itself is a cancellation point we do not
 100        have to do anything here.  */
 101     do {
 102       if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
 103         status = -1;
 104     }
 105     while (WIFEXITED(status) == 0);
 106   }
 107 
 108   save = errno;
 109   if (((sigaction (SIGINT, &intr, (struct sigaction *) NULL)
 110         | sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
 111       || sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0) {
 112     /* glibc cannot be used on systems without waitpid.  */
 113     if (errno == ENOSYS)
 114       errno = save;
 115     else
 116       status = -1;
 117   }
 118 
 119   return status;
 120 }
 121 

/* [<][>][^][v][top][bottom][index][help] */