1 /* Copyright (C) 1991-2000,2002,2003,2005,2007 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
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.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
23 #include <sys/types.h>
25 #include <bits/libc-lock.h>
26 #include <sysdep-cancel.h>
29 #define SHELL_PATH "/bin/sh" /* Path of the shell. */
30 #define SHELL_NAME "sh" /* Name to give it. */
33 #ifdef _LIBC_REENTRANT
34 static struct sigaction intr
, quit
;
35 static int sa_refcntr
;
36 __libc_lock_define_initialized (static, lock
);
38 # define DO_LOCK() __libc_lock_lock (lock)
39 # define DO_UNLOCK() __libc_lock_unlock (lock)
40 # define INIT_LOCK() ({ __libc_lock_init (lock); sa_refcntr = 0; })
41 # define ADD_REF() sa_refcntr++
42 # define SUB_REF() --sa_refcntr
52 /* Execute LINE as a shell command, returning its status. */
54 do_system (const char *line
)
59 #ifndef _LIBC_REENTRANT
60 struct sigaction intr
, quit
;
64 sa
.sa_handler
= SIG_IGN
;
66 __sigemptyset (&sa
.sa_mask
);
71 if (__sigaction (SIGINT
, &sa
, &intr
) < 0)
76 if (__sigaction (SIGQUIT
, &sa
, &quit
) < 0)
80 goto out_restore_sigint
;
85 /* We reuse the bitmap in the 'sa' structure. */
86 __sigaddset (&sa
.sa_mask
, SIGCHLD
);
88 if (__sigprocmask (SIG_BLOCK
, &sa
.sa_mask
, &omask
) < 0)
100 (void) __sigaction (SIGQUIT
, &quit
, (struct sigaction
*) NULL
);
102 (void) __sigaction (SIGINT
, &intr
, (struct sigaction
*) NULL
);
111 #ifdef CLEANUP_HANDLER
120 if (pid
== (pid_t
) 0)
123 const char *new_argv
[4];
124 new_argv
[0] = SHELL_NAME
;
129 /* Restore the signals. */
130 (void) __sigaction (SIGINT
, &intr
, (struct sigaction
*) NULL
);
131 (void) __sigaction (SIGQUIT
, &quit
, (struct sigaction
*) NULL
);
132 (void) __sigprocmask (SIG_SETMASK
, &omask
, (sigset_t
*) NULL
);
135 /* Exec the shell. */
136 (void) __execve (SHELL_PATH
, (char *const *) new_argv
, __environ
);
139 else if (pid
< (pid_t
) 0)
140 /* The fork failed. */
145 /* Note the system() is a cancellation point. But since we call
146 waitpid() which itself is a cancellation point we do not
147 have to do anything here. */
148 if (TEMP_FAILURE_RETRY (__waitpid (pid
, &status
, 0)) != pid
)
152 #ifdef CLEANUP_HANDLER
159 && (__sigaction (SIGINT
, &intr
, (struct sigaction
*) NULL
)
160 | __sigaction (SIGQUIT
, &quit
, (struct sigaction
*) NULL
)) != 0)
161 || __sigprocmask (SIG_SETMASK
, &omask
, (sigset_t
*) NULL
) != 0)
164 /* glibc cannot be used on systems without waitpid. */
177 __libc_system (const char *line
)
180 /* Check that we have a command processor available. It might
181 not be available after a chroot(), for example. */
182 return do_system ("exit 0") == 0;
185 return do_system (line
);
187 int oldtype
= LIBC_CANCEL_ASYNC ();
189 int result
= do_system (line
);
191 LIBC_CANCEL_RESET (oldtype
);
195 weak_alias (__libc_system
, system
)