2 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include "pthread_private.h"
37 __weak_reference(_execve, execve);
40 _execve(const char *name, char *const * argv, char *const * envp)
42 struct pthread *curthread = _get_curthread();
47 struct sigaction oact;
48 struct itimerval itimer;
50 /* Disable the interval timer: */
51 itimer.it_interval.tv_sec = 0;
52 itimer.it_interval.tv_usec = 0;
53 itimer.it_value.tv_sec = 0;
54 itimer.it_value.tv_usec = 0;
55 setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL);
57 /* Close the pthread kernel pipe: */
58 __sys_close(_thread_kern_pipe[0]);
59 __sys_close(_thread_kern_pipe[1]);
62 * Enter a loop to set all file descriptors to blocking
63 * if they were not created as non-blocking:
65 for (i = 0; i < _thread_dtablesize; i++) {
66 /* Check if this file descriptor is in use: */
67 if (_thread_fd_table[i] != NULL &&
68 (_thread_fd_getflags(i) & O_NONBLOCK) == 0) {
69 /* Skip if the close-on-exec flag is set */
70 flags = __sys_fcntl(i, F_GETFD, NULL);
71 if ((flags & FD_CLOEXEC) != 0)
72 continue; /* don't bother, no point */
73 /* Get the current flags: */
74 flags = __sys_fcntl(i, F_GETFL, NULL);
75 /* Clear the nonblocking file descriptor flag: */
76 __sys_fcntl(i, F_SETFL, flags & ~O_NONBLOCK);
80 /* Enter a loop to adopt the signal actions for the running thread: */
81 for (i = 1; i < NSIG; i++) {
82 /* Check for signals which cannot be caught: */
83 if (i == SIGKILL || i == SIGSTOP) {
84 /* Don't do anything with these signals. */
86 /* Check if ignoring this signal: */
87 if (_thread_sigact[i - 1].sa_handler == SIG_IGN) {
88 /* Continue to ignore this signal: */
89 act.sa_handler = SIG_IGN;
91 /* Use the default handler for this signal: */
92 act.sa_handler = SIG_DFL;
95 /* Copy the mask and flags for this signal: */
96 act.sa_mask = _thread_sigact[i - 1].sa_mask;
97 act.sa_flags = _thread_sigact[i - 1].sa_flags;
99 /* Change the signal action for the process: */
100 __sys_sigaction(i, &act, &oact);
104 /* Set the signal mask: */
105 __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL);
107 /* Execute the process: */
108 ret = __sys_execve(name, argv, envp);
110 /* Return the completion status: */