git: 1a581d16e268 - stable/12 - libthr: wrap pdfork(2), same as fork(2).

Konstantin Belousov kib at FreeBSD.org
Mon Jan 18 05:40:32 UTC 2021


The branch stable/12 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=1a581d16e268f21c25a7cfa0bcdc3b35f25ff6e1

commit 1a581d16e268f21c25a7cfa0bcdc3b35f25ff6e1
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-01-10 19:22:49 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-01-18 05:09:04 +0000

    libthr: wrap pdfork(2), same as fork(2).
    
    (cherry picked from commit 21f749da82e755aafab127618affeffb86cff9a5)
---
 lib/libc/include/libc_private.h  |  2 ++
 lib/libc/sys/Symbol.map          |  1 +
 lib/libc/sys/interposing_table.c |  1 +
 lib/libc/sys/pdfork.c            | 46 ++++++++++++++++++++++++++++
 lib/libthr/thread/thr_fork.c     | 66 +++++++++++++++++++++++++++++++++++-----
 lib/libthr/thread/thr_private.h  |  1 +
 lib/libthr/thread/thr_syscalls.c |  1 +
 7 files changed, 111 insertions(+), 7 deletions(-)

diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h
index d3fe788e9654..8517899f56ef 100644
--- a/lib/libc/include/libc_private.h
+++ b/lib/libc/include/libc_private.h
@@ -238,6 +238,7 @@ enum {
 	INTERPOS_fdatasync,
 	INTERPOS_clock_nanosleep,
 	INTERPOS_distribute_static_tls,
+	INTERPOS_pdfork,
 	INTERPOS_MAX
 };
 
@@ -352,6 +353,7 @@ int		__sys_msync(void *, __size_t, int);
 int		__sys_nanosleep(const struct timespec *, struct timespec *);
 int		__sys_open(const char *, int, ...);
 int		__sys_openat(int, const char *, int, ...);
+int		__sys_pdfork(int *, int);
 int		__sys_pselect(int, struct fd_set *, struct fd_set *,
 		    struct fd_set *, const struct timespec *,
 		    const __sigset_t *);
diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map
index 353786343b54..ba4ea515c93d 100644
--- a/lib/libc/sys/Symbol.map
+++ b/lib/libc/sys/Symbol.map
@@ -797,6 +797,7 @@ FBSDprivate_1.0 {
 	__sys_openat;
 	_pathconf;
 	__sys_pathconf;
+	__sys_pdfork;
 	_pipe;
 	__sys_pipe;
 	_poll;
diff --git a/lib/libc/sys/interposing_table.c b/lib/libc/sys/interposing_table.c
index 670e9fd7dd0f..b2cfb3250cd9 100644
--- a/lib/libc/sys/interposing_table.c
+++ b/lib/libc/sys/interposing_table.c
@@ -82,6 +82,7 @@ interpos_func_t __libc_interposing[INTERPOS_MAX] = {
 	SLOT(fdatasync, __sys_fdatasync),
 	SLOT(clock_nanosleep, __sys_clock_nanosleep),
 	SLOT(distribute_static_tls, __libc_distribute_static_tls),
+	SLOT(pdfork, __sys_pdfork),
 };
 #undef SLOT
 
diff --git a/lib/libc/sys/pdfork.c b/lib/libc/sys/pdfork.c
new file mode 100644
index 000000000000..003262d1237d
--- /dev/null
+++ b/lib/libc/sys/pdfork.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021 The FreeBSD Foundation.
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <unistd.h>
+#include "libc_private.h"
+
+#pragma weak pdfork
+pid_t
+pdfork(int *fdp, int flags)
+{
+	return (((pid_t (*)(int *, int))__libc_interposing[
+	    INTERPOS_pdfork])(fdp, flags));
+}
diff --git a/lib/libthr/thread/thr_fork.c b/lib/libthr/thread/thr_fork.c
index c82342010a3e..a70ea8b2b696 100644
--- a/lib/libthr/thread/thr_fork.c
+++ b/lib/libthr/thread/thr_fork.c
@@ -132,10 +132,19 @@ __pthread_cxa_finalize(struct dl_phdr_info *phdr_info)
 	_thr_sigact_unload(phdr_info);
 }
 
-__weak_reference(__thr_fork, _fork);
-
-pid_t
-__thr_fork(void)
+enum thr_fork_mode {
+	MODE_FORK,
+	MODE_PDFORK,
+};
+
+struct thr_fork_args {
+	enum thr_fork_mode mode;
+	void *fdp;
+	int flags;
+};
+
+static pid_t
+thr_fork_impl(const struct thr_fork_args *a)
 {
 	struct pthread *curthread;
 	struct pthread_atfork *af;
@@ -144,8 +153,17 @@ __thr_fork(void)
 	int was_threaded;
 	int rtld_locks[MAX_RTLD_LOCKS];
 
-	if (!_thr_is_inited())
-		return (__sys_fork());
+	if (!_thr_is_inited()) {
+		switch (a->mode) {
+		case MODE_FORK:
+			return (__sys_fork());
+		case MODE_PDFORK:
+			return (__sys_pdfork(a->fdp, a->flags));
+		default:
+			errno = EDOOFUS;
+			return (-1);
+		}
+	}
 
 	curthread = _get_curthread();
 	cancelsave = curthread->no_cancel;
@@ -186,7 +204,19 @@ __thr_fork(void)
 	 * indirection, the syscall symbol is resolved in
 	 * _thr_rtld_init() with side-effect free call.
 	 */
-	ret = syscall(SYS_fork);
+	switch (a->mode) {
+	case MODE_FORK:
+		ret = syscall(SYS_fork);
+		break;
+	case MODE_PDFORK:
+		ret = syscall(SYS_pdfork, a->fdp, a->flags);
+		break;
+	default:
+		ret = -1;
+		errno = EDOOFUS;
+		break;
+	}
+
 	if (ret == 0) {
 		/* Child process */
 		errsave = errno;
@@ -272,3 +302,25 @@ __thr_fork(void)
 
 	return (ret);
 }
+
+__weak_reference(__thr_fork, _fork);
+
+pid_t
+__thr_fork(void)
+{
+	struct thr_fork_args a;
+
+	a.mode = MODE_FORK;
+	return (thr_fork_impl(&a));
+}
+
+pid_t
+__thr_pdfork(int *fdp, int flags)
+{
+	struct thr_fork_args a;
+
+	a.mode = MODE_PDFORK;
+	a.fdp = fdp;
+	a.flags = flags;
+	return (thr_fork_impl(&a));
+}
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
index 80ece7bdb1ee..e8a8492c0504 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -985,6 +985,7 @@ void __pthread_distribute_static_tls(size_t offset, void *src, size_t len,
 int *__error_threaded(void) __hidden;
 void __thr_interpose_libc(void) __hidden;
 pid_t __thr_fork(void);
+pid_t __thr_pdfork(int *, int);
 int __thr_setcontext(const ucontext_t *ucp);
 int __thr_sigaction(int sig, const struct sigaction *act,
     struct sigaction *oact) __hidden;
diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c
index 025dfc75fab6..c60308fcd1d2 100644
--- a/lib/libthr/thread/thr_syscalls.c
+++ b/lib/libthr/thread/thr_syscalls.c
@@ -687,6 +687,7 @@ __thr_interpose_libc(void)
 	SLOT(map_stacks_exec);
 	SLOT(fdatasync);
 	SLOT(clock_nanosleep);
+	SLOT(pdfork);
 #undef SLOT
 	*(__libc_interposing_slot(
 	    INTERPOS__pthread_mutex_init_calloc_cb)) =


More information about the dev-commits-src-all mailing list