summaryrefslogtreecommitdiffstats
path: root/lib/libkse
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2004-09-26 06:50:15 +0000
committerdeischen <deischen@FreeBSD.org>2004-09-26 06:50:15 +0000
commite06ce725da02a436965fd3a72c115ec7dee8d28e (patch)
tree5c4e6bda003876da80684c748cc264b78b4795a2 /lib/libkse
parent266d410b93ab1a0dab23752b4186f15cf9d1d0f2 (diff)
downloadFreeBSD-src-e06ce725da02a436965fd3a72c115ec7dee8d28e.zip
FreeBSD-src-e06ce725da02a436965fd3a72c115ec7dee8d28e.tar.gz
Add a wrapper for execve(). The exec'd process must be started with
the signal mask and pending signals of the calling thread. These are stored in userland in libpthread. There is a small race condition in this patch which could cause problems if a signal arrives after setting the (kernel) signal mask and before exec'ing. The thread's set of pending signals also are not yet installed in the exec'd process. Both of these will be corrected with the addition of a special syscall. Reported & Tested by: Joost Bekkers <joost at jodocus dot org> Reviewed by: julian, davidxu
Diffstat (limited to 'lib/libkse')
-rw-r--r--lib/libkse/thread/Makefile.inc1
-rw-r--r--lib/libkse/thread/thr_execve.c68
2 files changed, 69 insertions, 0 deletions
diff --git a/lib/libkse/thread/Makefile.inc b/lib/libkse/thread/Makefile.inc
index 59fa21c..3ba361e 100644
--- a/lib/libkse/thread/Makefile.inc
+++ b/lib/libkse/thread/Makefile.inc
@@ -44,6 +44,7 @@ SRCS+= \
thr_create.c \
thr_detach.c \
thr_equal.c \
+ thr_execve.c \
thr_exit.c \
thr_fcntl.c \
thr_find_thread.c \
diff --git a/lib/libkse/thread/thr_execve.c b/lib/libkse/thread/thr_execve.c
new file mode 100644
index 0000000..db5b858
--- /dev/null
+++ b/lib/libkse/thread/thr_execve.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004 Daniel Eischen <deischen@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice(s), this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified other than the possible
+ * addition of one or more copyright notices.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice(s), this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+#include "thr_private.h"
+
+__weak_reference(_execve, execve);
+
+int
+_execve(const char *name, char *const *argv, char *const *envp)
+{
+ sigset_t omask;
+ struct pthread *curthread;
+ kse_critical_t crit;
+ int saved_errno;
+ int ret;
+
+ /*
+ * When exec'ing, set the kernel signal mask to the thread's
+ * signal mask to satisfy POSIX requirements. We have to enter
+ * a critical region so that the kernel thread doesn't get
+ * changed out from under us after setting the signal mask.
+ */
+ curthread = _get_curthread();
+ crit = _kse_critical_enter();
+ __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, &omask);
+ ret = __sys_execve(name, argv, envp);
+
+ /*
+ * If something went wrong, set the signal mask back but don't
+ * destroy errno.
+ */
+ saved_errno = errno;
+ __sys_sigprocmask(SIG_SETMASK, &omask, NULL);
+ errno = saved_errno;
+ _kse_critical_leave(crit);
+ return (ret);
+}
OpenPOWER on IntegriCloud