1 /* Copyright (C) 1991-2000, 2002, 2003 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>
31 #define __environ environ
34 #define SHELL_PATH "/bin/sh" /* Path of the shell. */
35 #define SHELL_NAME "sh" /* Name to give it. */
38 #ifdef _LIBC_REENTRANT
39 static struct sigaction intr
, quit
;
40 static int sa_refcntr
;
41 __libc_lock_define_initialized (static, lock
);
43 # define DO_LOCK() __libc_lock_lock (lock)
44 # define DO_UNLOCK() __libc_lock_unlock (lock)
45 # define INIT_LOCK() ({ __libc_lock_init (lock); sa_refcntr = 0; })
46 # define ADD_REF() sa_refcntr++
47 # define SUB_REF() --sa_refcntr
57 /* Execute LINE as a shell command, returning its status. */
59 do_system (const char *line
)
64 #ifndef _LIBC_REENTRANT
65 struct sigaction intr
, quit
;
69 sa
.sa_handler
= SIG_IGN
;
71 __sigemptyset (&sa
.sa_mask
);
76 if (__sigaction (SIGINT
, &sa
, &intr
) < 0)
81 if (__sigaction (SIGQUIT
, &sa
, &quit
) < 0)
85 goto out_restore_sigint
;
90 /* We reuse the bitmap in the 'sa' structure. */
91 __sigaddset (&sa
.sa_mask
, SIGCHLD
);
93 if (__sigprocmask (SIG_BLOCK
, &sa
.sa_mask
, &omask
) < 0)
105 (void) __sigaction (SIGQUIT
, &quit
, (struct sigaction
*) NULL
);
107 (void) __sigaction (SIGINT
, &intr
, (struct sigaction
*) NULL
);
116 #ifdef CLEANUP_HANDLER
125 if (pid
== (pid_t
) 0)
128 const char *new_argv
[4];
129 new_argv
[0] = SHELL_NAME
;
134 /* Restore the signals. */
135 (void) __sigaction (SIGINT
, &intr
, (struct sigaction
*) NULL
);
136 (void) __sigaction (SIGQUIT
, &quit
, (struct sigaction
*) NULL
);
137 (void) __sigprocmask (SIG_SETMASK
, &omask
, (sigset_t
*) NULL
);
140 /* Exec the shell. */
141 (void) __execve (SHELL_PATH
, (char *const *) new_argv
, __environ
);
144 else if (pid
< (pid_t
) 0)
145 /* The fork failed. */
154 child
= __wait (&status
);
155 if (child
<= -1 && errno
!= EINTR
)
160 /* Note that pid cannot be <= -1 and therefore the loop continues
161 when __wait returned with EINTR. */
163 while (child
!= pid
);
165 /* Note the system() is a cancellation point. But since we call
166 waitpid() which itself is a cancellation point we do not
167 have to do anything here. */
168 if (TEMP_FAILURE_RETRY (__waitpid (pid
, &status
, 0)) != pid
)
173 #ifdef CLEANUP_HANDLER
180 && (__sigaction (SIGINT
, &intr
, (struct sigaction
*) NULL
)
181 | __sigaction (SIGQUIT
, &quit
, (struct sigaction
*) NULL
)) != 0)
182 || __sigprocmask (SIG_SETMASK
, &omask
, (sigset_t
*) NULL
) != 0)
185 /* glibc cannot be used on systems without waitpid. */
198 __libc_system (const char *line
)
201 /* Check that we have a command processor available. It might
202 not be available after a chroot(), for example. */
203 return do_system ("exit 0") == 0;
206 return do_system (line
);
208 int oldtype
= LIBC_CANCEL_ASYNC ();
210 int result
= do_system (line
);
212 LIBC_CANCEL_RESET (oldtype
);
216 weak_alias (__libc_system
, system
)