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, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 #include <sys/types.h>
26 #include <bits/libc-lock.h>
27 #include <sysdep-cancel.h>
30 #define SHELL_PATH "/bin/sh" /* Path of the shell. */
31 #define SHELL_NAME "sh" /* Name to give it. */
34 #ifdef _LIBC_REENTRANT
35 static struct sigaction intr
, quit
;
36 static int sa_refcntr
;
37 __libc_lock_define_initialized (static, lock
);
39 # define DO_LOCK() __libc_lock_lock (lock)
40 # define DO_UNLOCK() __libc_lock_unlock (lock)
41 # define INIT_LOCK() ({ __libc_lock_init (lock); sa_refcntr = 0; })
42 # define ADD_REF() sa_refcntr++
43 # define SUB_REF() --sa_refcntr
53 /* Execute LINE as a shell command, returning its status. */
55 do_system (const char *line
)
60 #ifndef _LIBC_REENTRANT
61 struct sigaction intr
, quit
;
65 sa
.sa_handler
= SIG_IGN
;
67 __sigemptyset (&sa
.sa_mask
);
72 if (__sigaction (SIGINT
, &sa
, &intr
) < 0)
77 if (__sigaction (SIGQUIT
, &sa
, &quit
) < 0)
81 goto out_restore_sigint
;
86 /* We reuse the bitmap in the 'sa' structure. */
87 __sigaddset (&sa
.sa_mask
, SIGCHLD
);
89 if (__sigprocmask (SIG_BLOCK
, &sa
.sa_mask
, &omask
) < 0)
101 (void) __sigaction (SIGQUIT
, &quit
, (struct sigaction
*) NULL
);
103 (void) __sigaction (SIGINT
, &intr
, (struct sigaction
*) NULL
);
112 #ifdef CLEANUP_HANDLER
121 if (pid
== (pid_t
) 0)
124 const char *new_argv
[4];
125 new_argv
[0] = SHELL_NAME
;
130 /* Restore the signals. */
131 (void) __sigaction (SIGINT
, &intr
, (struct sigaction
*) NULL
);
132 (void) __sigaction (SIGQUIT
, &quit
, (struct sigaction
*) NULL
);
133 (void) __sigprocmask (SIG_SETMASK
, &omask
, (sigset_t
*) NULL
);
136 /* Exec the shell. */
137 (void) __execve (SHELL_PATH
, (char *const *) new_argv
, __environ
);
140 else if (pid
< (pid_t
) 0)
141 /* The fork failed. */
146 /* Note the system() is a cancellation point. But since we call
147 waitpid() which itself is a cancellation point we do not
148 have to do anything here. */
149 if (TEMP_FAILURE_RETRY (__waitpid (pid
, &status
, 0)) != pid
)
153 #ifdef CLEANUP_HANDLER
160 && (__sigaction (SIGINT
, &intr
, (struct sigaction
*) NULL
)
161 | __sigaction (SIGQUIT
, &quit
, (struct sigaction
*) NULL
)) != 0)
162 || __sigprocmask (SIG_SETMASK
, &omask
, (sigset_t
*) NULL
) != 0)
165 /* glibc cannot be used on systems without waitpid. */
178 __libc_system (const char *line
)
181 /* Check that we have a command processor available. It might
182 not be available after a chroot(), for example. */
183 return do_system ("exit 0") == 0;
186 return do_system (line
);
188 int oldtype
= LIBC_CANCEL_ASYNC ();
190 int result
= do_system (line
);
192 LIBC_CANCEL_RESET (oldtype
);
196 weak_alias (__libc_system
, system
)