Back to index

glibc  2.9
Defines | Functions
system.c File Reference
#include <errno.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <bits/libc-lock.h>
#include <sysdep-cancel.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define SHELL_PATH   "/bin/sh" /* Path of the shell. */
#define SHELL_NAME   "sh" /* Name to give it. */
#define DO_LOCK()
#define DO_UNLOCK()
#define INIT_LOCK()
#define ADD_REF()   0
#define SUB_REF()   0

Functions

static int do_system (const char *line)
int __libc_system (const char *line)

Define Documentation

#define ADD_REF ( )    0

Definition at line 48 of file system.c.

#define DO_LOCK ( )

Definition at line 45 of file system.c.

#define DO_UNLOCK ( )

Definition at line 46 of file system.c.

#define INIT_LOCK ( )

Definition at line 47 of file system.c.

#define SHELL_NAME   "sh" /* Name to give it. */

Definition at line 31 of file system.c.

#define SHELL_PATH   "/bin/sh" /* Path of the shell. */

Definition at line 30 of file system.c.

#define SUB_REF ( )    0

Definition at line 49 of file system.c.


Function Documentation

int __libc_system ( const char *  line)

Definition at line 178 of file system.c.

{
  if (line == NULL)
    /* Check that we have a command processor available.  It might
       not be available after a chroot(), for example.  */
    return do_system ("exit 0") == 0;

  if (SINGLE_THREAD_P)
    return do_system (line);

  int oldtype = LIBC_CANCEL_ASYNC ();

  int result = do_system (line);

  LIBC_CANCEL_RESET (oldtype);

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int do_system ( const char *  line) [static]

Definition at line 55 of file system.c.

{
  int status, save;
  pid_t pid;
  struct sigaction sa;
#ifndef _LIBC_REENTRANT
  struct sigaction intr, quit;
#endif
  sigset_t omask;

  sa.sa_handler = SIG_IGN;
  sa.sa_flags = 0;
  __sigemptyset (&sa.sa_mask);

  DO_LOCK ();
  if (ADD_REF () == 0)
    {
      if (__sigaction (SIGINT, &sa, &intr) < 0)
       {
         SUB_REF ();
         goto out;
       }
      if (__sigaction (SIGQUIT, &sa, &quit) < 0)
       {
         save = errno;
         SUB_REF ();
         goto out_restore_sigint;
       }
    }
  DO_UNLOCK ();

  /* We reuse the bitmap in the 'sa' structure.  */
  __sigaddset (&sa.sa_mask, SIGCHLD);
  save = errno;
  if (__sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0)
    {
#ifndef _LIBC
      if (errno == ENOSYS)
       __set_errno (save);
      else
#endif
       {
         DO_LOCK ();
         if (SUB_REF () == 0)
           {
             save = errno;
             (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
           out_restore_sigint:
             (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
             __set_errno (save);
           }
       out:
         DO_UNLOCK ();
         return -1;
       }
    }

#ifdef CLEANUP_HANDLER
  CLEANUP_HANDLER;
#endif

#ifdef FORK
  pid = FORK ();
#else
  pid = __fork ();
#endif
  if (pid == (pid_t) 0)
    {
      /* Child side.  */
      const char *new_argv[4];
      new_argv[0] = SHELL_NAME;
      new_argv[1] = "-c";
      new_argv[2] = line;
      new_argv[3] = NULL;

      /* 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);
      INIT_LOCK ();

      /* Exec the shell.  */
      (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ);
      _exit (127);
    }
  else if (pid < (pid_t) 0)
    /* The fork failed.  */
    status = -1;
  else
    /* Parent side.  */
    {
      /* Note the system() is a cancellation point.  But since we call
        waitpid() which itself is a cancellation point we do not
        have to do anything here.  */
      if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid)
       status = -1;
    }

#ifdef CLEANUP_HANDLER
  CLEANUP_RESET;
#endif

  save = errno;
  DO_LOCK ();
  if ((SUB_REF () == 0
       && (__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
          | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
      || __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
       status = -1;
    }
  DO_UNLOCK ();

  return status;
}

Here is the call graph for this function:

Here is the caller graph for this function: