aboutsummaryrefslogtreecommitdiff
path: root/lib/libsys
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libsys')
-rw-r--r--lib/libsys/Makefile.sys10
-rw-r--r--lib/libsys/Symbol.sys.map7
-rw-r--r--lib/libsys/_libsys.h6
-rw-r--r--lib/libsys/aarch64/Makefile.sys2
-rw-r--r--lib/libsys/amd64/Makefile.sys3
-rw-r--r--lib/libsys/amd64/Symbol.sys.map1
-rw-r--r--lib/libsys/amd64/pdrfork_thread.S83
-rw-r--r--lib/libsys/arm/Makefile.sys7
-rw-r--r--lib/libsys/i386/Makefile.sys2
-rw-r--r--lib/libsys/i386/Symbol.sys.map1
-rw-r--r--lib/libsys/i386/pdrfork_thread.S101
-rw-r--r--lib/libsys/interposing_table.c1
-rw-r--r--lib/libsys/kqueue.28
-rw-r--r--lib/libsys/open.223
-rw-r--r--lib/libsys/pdfork.2109
-rw-r--r--lib/libsys/pdrfork_thread_gen.c34
-rw-r--r--lib/libsys/powerpc/Makefile.sys2
-rw-r--r--lib/libsys/powerpc64/Makefile.sys2
-rw-r--r--lib/libsys/powerpcspe/Makefile.sys5
-rw-r--r--lib/libsys/rename.291
-rw-r--r--lib/libsys/rfork.21
-rw-r--r--lib/libsys/rfork_thread_gen.c40
-rw-r--r--lib/libsys/riscv/Makefile.sys2
-rw-r--r--lib/libsys/sigreturn.224
-rw-r--r--lib/libsys/socket.2138
-rw-r--r--lib/libsys/syscalls.map6
-rw-r--r--lib/libsys/wait.21
27 files changed, 622 insertions, 88 deletions
diff --git a/lib/libsys/Makefile.sys b/lib/libsys/Makefile.sys
index 5f149170b974..76855e0ae54d 100644
--- a/lib/libsys/Makefile.sys
+++ b/lib/libsys/Makefile.sys
@@ -73,6 +73,7 @@ INTERPOSED = \
open \
openat \
pdfork \
+ pdwait \
poll \
ppoll \
pselect \
@@ -495,8 +496,10 @@ MLINKS+=ntp_adjtime.2 ntp_gettime.2
MLINKS+=open.2 openat.2
MLINKS+=pathconf.2 fpathconf.2
MLINKS+=pathconf.2 lpathconf.2
-MLINKS+=pdfork.2 pdgetpid.2\
- pdfork.2 pdkill.2
+MLINKS+=pdfork.2 pdgetpid.2 \
+ pdfork.2 pdkill.2 \
+ pdfork.2 pdrfork.2 \
+ pdfork.2 pdwait.2
MLINKS+=pipe.2 pipe2.2
MLINKS+=poll.2 ppoll.2
MLINKS+=rctl_add_rule.2 rctl_get_limits.2 \
@@ -510,7 +513,8 @@ MLINKS+=readlink.2 readlinkat.2
MLINKS+=recv.2 recvfrom.2 \
recv.2 recvmmsg.2 \
recv.2 recvmsg.2
-MLINKS+=rename.2 renameat.2
+MLINKS+=rename.2 renameat.2 \
+ rename.2 renameat2.2
MLINKS+=rtprio.2 rtprio_thread.2
MLINKS+=sched_get_priority_max.2 sched_get_priority_min.2 \
sched_get_priority_max.2 sched_rr_get_interval.2
diff --git a/lib/libsys/Symbol.sys.map b/lib/libsys/Symbol.sys.map
index e3fd8ac10621..7f5c252af91b 100644
--- a/lib/libsys/Symbol.sys.map
+++ b/lib/libsys/Symbol.sys.map
@@ -182,6 +182,7 @@ FBSD_1.0 {
rename;
revoke;
rfork;
+ rfork_thread;
rmdir;
rtprio;
rtprio_thread;
@@ -389,6 +390,12 @@ FBSD_1.8 {
setgroups;
};
+FBSD_1.9 {
+ pdrfork;
+ pdrfork_thread;
+ renameat2;
+};
+
FBSDprivate_1.0 {
/* Add entries in sort(1) order */
__set_error_selector;
diff --git a/lib/libsys/_libsys.h b/lib/libsys/_libsys.h
index 12417b572a60..c454fc3fece9 100644
--- a/lib/libsys/_libsys.h
+++ b/lib/libsys/_libsys.h
@@ -472,6 +472,9 @@ typedef int (__sys_setgroups_t)(int, const gid_t *);
typedef int (__sys_jail_attach_jd_t)(int);
typedef int (__sys_jail_remove_jd_t)(int);
typedef int (__sys_kexec_load_t)(uint64_t, u_long, struct kexec_segment *, u_long);
+typedef int (__sys_pdrfork_t)(int *, int, int);
+typedef int (__sys_pdwait_t)(int, int *, int, struct __wrusage *, struct __siginfo *);
+typedef int (__sys_renameat2_t)(int, const char *, int, const char *, int);
_Noreturn void __sys__exit(int rval);
int __sys_fork(void);
@@ -879,6 +882,9 @@ int __sys_setgroups(int gidsetsize, const gid_t * gidset);
int __sys_jail_attach_jd(int fd);
int __sys_jail_remove_jd(int fd);
int __sys_kexec_load(uint64_t entry, u_long nseg, struct kexec_segment * segments, u_long flags);
+int __sys_pdrfork(int * fdp, int pdflags, int rfflags);
+int __sys_pdwait(int fd, int * status, int options, struct __wrusage * wrusage, struct __siginfo * info);
+int __sys_renameat2(int oldfd, const char * old, int newfd, const char * new, int flags);
__END_DECLS
#endif /* __LIBSYS_H_ */
diff --git a/lib/libsys/aarch64/Makefile.sys b/lib/libsys/aarch64/Makefile.sys
index 04b95602c580..c7aaf52d535a 100644
--- a/lib/libsys/aarch64/Makefile.sys
+++ b/lib/libsys/aarch64/Makefile.sys
@@ -1,6 +1,8 @@
MIASM:= ${MIASM:Nfreebsd[467]_*}
SRCS+= __vdso_gettc.c \
+ pdrfork_thread_gen.c \
+ rfork_thread_gen.c \
sched_getcpu_gen.c
MDASM= cerror.S \
diff --git a/lib/libsys/amd64/Makefile.sys b/lib/libsys/amd64/Makefile.sys
index 8134bdc422a6..fc8ebe796081 100644
--- a/lib/libsys/amd64/Makefile.sys
+++ b/lib/libsys/amd64/Makefile.sys
@@ -4,6 +4,7 @@ SRCS+= \
amd64_set_fsbase.c \
amd64_set_gsbase.c \
amd64_set_tlsbase.c \
- rfork_thread.S
+ rfork_thread.S \
+ pdrfork_thread.S
MDASM= vfork.S cerror.S getcontext.S
diff --git a/lib/libsys/amd64/Symbol.sys.map b/lib/libsys/amd64/Symbol.sys.map
index 11e0507b6613..67a8df7d2a8c 100644
--- a/lib/libsys/amd64/Symbol.sys.map
+++ b/lib/libsys/amd64/Symbol.sys.map
@@ -1,5 +1,4 @@
FBSD_1.0 {
- rfork_thread;
amd64_get_fsbase;
amd64_get_gsbase;
amd64_set_fsbase;
diff --git a/lib/libsys/amd64/pdrfork_thread.S b/lib/libsys/amd64/pdrfork_thread.S
new file mode 100644
index 000000000000..cd187ae456ae
--- /dev/null
+++ b/lib/libsys/amd64/pdrfork_thread.S
@@ -0,0 +1,83 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2000 Peter Wemm <peter@FreeBSD.org>
+ * Copyright 2003 Alan L. Cox <alc@cs.rice.edu>
+ * Copyright 2026 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by
+ * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from
+ * the FreeBSD Foundation.
+ */
+
+#include <machine/asm.h>
+/*
+ * With thanks to John Dyson for the original version of this.
+ */
+
+#include <SYS.h>
+
+/*
+ * %rdi %esi %rdx %rcx %r8 %r9
+ * pdrfork_thread(fdp, pdflags, rfflags, stack_addr, start_fnc, start_arg);
+ *
+ * fdp Pointer for the resulting fd location
+ * pdflags Flags as to pdfork.
+ * rfflags: Flags as to rfork.
+ * stack_addr: Top of stack for thread.
+ * start_fnc: Address of thread function to call in child.
+ * start_arg: Argument to pass to the thread function in child.
+ */
+
+ENTRY(pdrfork_thread)
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ movq %r8, %rbx
+ movq %r9, %r12
+ movq %rcx, %r13
+
+ /*
+ * Prepare and execute the thread creation syscall
+ */
+ _SYSCALL(pdrfork)
+ jb 2f
+
+ /*
+ * Check to see if we are in the parent or child
+ */
+ cmpl $0, %edx
+ jnz 1f
+ popq %r13
+ popq %r12
+ popq %rbx
+ ret
+
+ /*
+ * If we are in the child (new thread), then
+ * set-up the call to the internal subroutine. If it
+ * returns, then call __exit.
+ */
+1:
+ movq %r13, %rsp
+ movq %r12, %rdi
+ call *%rbx
+ movl %eax, %edi
+
+ /*
+ * Exit system call
+ */
+ _SYSCALL(exit)
+
+ /*
+ * Branch here if the thread creation fails:
+ */
+2:
+ popq %r13
+ popq %r12
+ popq %rbx
+ jmp HIDENAME(cerror)
+END(pdrfork_thread)
+
+ .section .note.GNU-stack,"",%progbits
diff --git a/lib/libsys/arm/Makefile.sys b/lib/libsys/arm/Makefile.sys
index 27d78978a2f4..e8b420932031 100644
--- a/lib/libsys/arm/Makefile.sys
+++ b/lib/libsys/arm/Makefile.sys
@@ -1,6 +1,13 @@
SRCS+= __vdso_gettc.c \
+ pdrfork_thread_gen.c \
+ rfork_thread_gen.c \
sched_getcpu_gen.c
MDASM= \
cerror.S \
vfork.S
+
+.if ${LIB} == "sys"
+.PATH: ${LIBSYS_SRCTOP}/../libc/arm/aeabi
+SRCS+= aeabi_unwind_cpp.c
+.endif
diff --git a/lib/libsys/i386/Makefile.sys b/lib/libsys/i386/Makefile.sys
index 2957dc548cf8..69507d930f25 100644
--- a/lib/libsys/i386/Makefile.sys
+++ b/lib/libsys/i386/Makefile.sys
@@ -1,7 +1,7 @@
SRCS+= i386_get_fsbase.c i386_get_gsbase.c i386_get_ioperm.c i386_get_ldt.c \
i386_set_fsbase.c i386_set_gsbase.c i386_set_ioperm.c i386_set_ldt.c \
i386_clr_watch.c i386_set_watch.c i386_vm86.c \
- rfork_thread.S
+ rfork_thread.S pdrfork_thread.S
MDASM= vfork.S cerror.S getcontext.S syscall.S
diff --git a/lib/libsys/i386/Symbol.sys.map b/lib/libsys/i386/Symbol.sys.map
index 6b3169336a3f..03a28f9e486c 100644
--- a/lib/libsys/i386/Symbol.sys.map
+++ b/lib/libsys/i386/Symbol.sys.map
@@ -10,7 +10,6 @@ FBSD_1.0 {
i386_set_ldt;
i386_set_watch;
i386_vm86;
- rfork_thread;
};
FBSD_1.6 {
diff --git a/lib/libsys/i386/pdrfork_thread.S b/lib/libsys/i386/pdrfork_thread.S
new file mode 100644
index 000000000000..92a45fc4783f
--- /dev/null
+++ b/lib/libsys/i386/pdrfork_thread.S
@@ -0,0 +1,101 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2000 Peter Wemm <peter@FreeBSD.org>
+ * Copyright 2026 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by
+ * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from
+ * the FreeBSD Foundation.
+ */
+
+#include <machine/asm.h>
+/*
+ * With thanks to John Dyson for the original version of this.
+ */
+
+#include <SYS.h>
+
+/*
+ * 8 12 16 20 24 28
+ * rfork_thread(fdp, pdflags rfflags, stack_addr, start_fnc, start_arg);
+ *
+ * fdp Pointer for the resulting fd location
+ * pdflags Flags as to pdfork.
+ * rfflags: Flags as to rfork.
+ * stack_addr: Top of stack for thread.
+ * start_fnc: Address of thread function to call in child.
+ * start_arg: Argument to pass to the thread function in child.
+ */
+
+ENTRY(pdrfork_thread)
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %esi
+
+ /*
+ * Push thread info onto the new thread's stack
+ */
+ movl 20(%ebp), %esi # get stack addr
+
+ subl $4, %esi
+ movl 28(%ebp), %eax # get start argument
+ movl %eax, (%esi)
+
+ subl $4, %esi
+ movl 24(%ebp), %eax # get start thread address
+ movl %eax, (%esi)
+
+ /*
+ * Prepare and execute the thread creation syscall
+ */
+ pushl 16(%ebp)
+ pushl 12(%ebp)
+ pushl 8(%ebp)
+ pushl $0
+ _SYSCALL(pdrfork)
+ jb 2f
+
+ /*
+ * Check to see if we are in the parent or child
+ */
+ cmpl $0, %edx
+ jnz 1f
+ addl $16, %esp
+ popl %esi
+ movl %ebp, %esp
+ popl %ebp
+ ret
+ .p2align 2
+
+ /*
+ * If we are in the child (new thread), then
+ * set-up the call to the internal subroutine. If it
+ * returns, then call __exit.
+ */
+1:
+ movl %esi,%esp
+ popl %eax
+ call *%eax
+ addl $4, %esp
+
+ /*
+ * Exit system call
+ */
+ pushl %eax
+ pushl $0
+ _SYSCALL(exit)
+
+ /*
+ * Branch here if the thread creation fails:
+ */
+2:
+ addl $16, %esp
+ popl %esi
+ movl %ebp, %esp
+ popl %ebp
+ jmp HIDENAME(cerror)
+END(pdrfork_thread)
+
+ .section .note.GNU-stack,"",%progbits
diff --git a/lib/libsys/interposing_table.c b/lib/libsys/interposing_table.c
index 31cdb1511ab8..0151364f89d2 100644
--- a/lib/libsys/interposing_table.c
+++ b/lib/libsys/interposing_table.c
@@ -72,6 +72,7 @@ static interpos_func_t __libsys_interposing[INTERPOS_MAX] = {
SLOT(fdatasync, __sys_fdatasync),
SLOT(clock_nanosleep, __sys_clock_nanosleep),
SLOT(pdfork, __sys_pdfork),
+ SLOT(pdwait, __sys_pdwait),
};
#undef SLOT
diff --git a/lib/libsys/kqueue.2 b/lib/libsys/kqueue.2
index a8ebabf02cf7..97532c530b20 100644
--- a/lib/libsys/kqueue.2
+++ b/lib/libsys/kqueue.2
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 12, 2025
+.Dd January 24, 2026
.Dt KQUEUE 2
.Os
.Sh NAME
@@ -971,13 +971,13 @@ The
.Fn kqueuex
system call
and
-.Fn kevent1
+.Fn kqueue1
function first appeared in
.Fx 14.0 .
.Sh AUTHORS
The
-.Fn kqueue
-system and this manual page were written by
+.Em kqueue
+subsystem and this manual page were written by
.An Jonathan Lemon Aq Mt jlemon@FreeBSD.org .
.Sh BUGS
.Pp
diff --git a/lib/libsys/open.2 b/lib/libsys/open.2
index a0e905a8f375..4527100252eb 100644
--- a/lib/libsys/open.2
+++ b/lib/libsys/open.2
@@ -72,11 +72,18 @@ function is equivalent to the
.Fn open
function except in the case where the
.Fa path
-specifies a relative path.
+specifies a relative path or the
+.Va O_EMPTY_PATH
+flag is specified.
For
.Fn openat
and relative
.Fa path ,
+when
+.Fa fd
+references a directory, and the
+.Va O_EMPTY_PATH
+flag is not specified,
the file to be opened is determined relative to the directory
associated with the file descriptor
.Fa fd
@@ -104,6 +111,14 @@ it ignores the
.Fa fd
argument.
.Pp
+When
+.Fn openat
+is called with the
+.Fa fd
+argument that does not reference a directory, the call fails unless
+.Va O_EMPTY_PATH
+flag is specified, see below.
+.Pp
In
.Xr capsicum 4
capability mode,
@@ -421,9 +436,11 @@ by the descriptor at the time of the
call.
.Pp
.Dv O_PATH
-returns a file descriptor that can be used as a directory file descriptor for
+returns a file descriptor that can be used as the first argument for
.Fn openat
-and other system calls taking a file descriptor argument, like
+and other filesystem-related system calls collectively named
+.Fn *at
+taking a file descriptor argument, like
.Xr fstatat 2
and others.
The other functionality of the returned file descriptor is limited to
diff --git a/lib/libsys/pdfork.2 b/lib/libsys/pdfork.2
index c5319177f90f..49226cf069de 100644
--- a/lib/libsys/pdfork.2
+++ b/lib/libsys/pdfork.2
@@ -30,24 +30,36 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 14, 2018
+.Dd January 20, 2026
.Dt PDFORK 2
.Os
.Sh NAME
.Nm pdfork ,
+.Nm pdrfork ,
.Nm pdgetpid ,
-.Nm pdkill
+.Nm pdkill ,
+.Nm pdwait
.Nd System calls to manage process descriptors
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In sys/procdesc.h
.Ft pid_t
-.Fn pdfork "int *fdp" "int flags"
+.Fn pdfork "int *fdp" "int pdflags"
+.Ft pid_t
+.Fn pdrfork "int *fdp" "int pdflags" "int rfflags"
.Ft int
.Fn pdgetpid "int fd" "pid_t *pidp"
.Ft int
.Fn pdkill "int fd" "int signum"
+.Ft int
+.Fo pdwait
+.Fa "int fd"
+.Fa "int *status"
+.Fa "int options"
+.Fa "struct __wrusage *wrusage"
+.Fa "struct __siginfo *info"
+.Fc
.Sh DESCRIPTION
Process descriptors are special file descriptors that represent processes,
and are created using
@@ -63,8 +75,9 @@ will not cause
.Dv SIGCHLD
on termination.
.Fn pdfork
-can accept the flags:
-.Bl -tag -width ".Dv PD_DAEMON"
+can accept the
+.Fa pdflags:
+.Bl -tag -width PD_CLOEXEC
.It Dv PD_DAEMON
Instead of the default terminate-on-close behaviour, allow the process to
live until it is explicitly killed with
@@ -80,6 +93,35 @@ capability mode (see
Set close-on-exec on process descriptor.
.El
.Pp
+The
+.Fn pdrfork
+system call is a variant of
+.Fn pdfork
+that also takes the
+.Fa rfflags
+argument to control sharing of process resources between the caller
+and the new process.
+Like
+.Fn pdfork ,
+the function writes the process descriptor referencing the created
+process into the location pointed to by the
+.Fa fdp
+argument.
+See
+.Xr rfork 2
+for a description of the possible
+.Fa rfflag
+flags.
+The
+.Fn pdrfork
+system call requires that both the
+.Va RFPROC
+and
+.Va RFPROCDESC
+flags, or
+.Va RFSPAWN
+flag are specified.
+.Pp
.Fn pdgetpid
queries the process ID (PID) in the process descriptor
.Fa fd .
@@ -91,6 +133,16 @@ except that it accepts a process descriptor,
.Fa fd ,
rather than a PID.
.Pp
+The
+.Fn pdwait
+system call allows the calling thread to wait and retrieve
+the status information on the process referenced by the
+.Fa fd
+process descriptor.
+See the description of the
+.Xr wait6
+system call for the behavior specification.
+.Pp
The following system calls also have effects specific to process descriptors:
.Pp
.Xr fstat 2
@@ -126,15 +178,24 @@ is set; if the process is still alive and this is
the last reference to the process descriptor, the process will be terminated
with the signal
.Dv SIGKILL .
+The PID of the referenced process is not reused until the process
+descriptor is closed,
+whether or not the zombie process is reaped by
+.Fn pdwait ,
+.Xr wait6 ,
+or similar system calls.
.Sh RETURN VALUES
.Fn pdfork
-returns a PID, 0 or -1, as
+and
+.Fn pdrfork
+return a PID, 0 or -1, as
.Xr fork 2
does.
.Pp
-.Fn pdgetpid
+.Fn pdgetpid ,
+.Fn pdkill ,
and
-.Fn pdkill
+.Fn pdwait
return 0 on success and -1 on failure.
.Sh ERRORS
These functions may return the same error numbers as their PID-based equivalents
@@ -144,6 +205,24 @@ may return the same error numbers as
.Xr fork 2 ) ,
with the following additions:
.Bl -tag -width Er
+.It Bq Er EFAULT
+The copyout of the resulting file descriptor value to the memory pointed
+to by
+.Fa fdp
+failed.
+.Pp
+Note that the child process was already created when this condition
+is detected,
+and the child continues execution, same as the parent.
+If this error must be handled, it is advisable to memoize the
+.Fn getpid
+result before the call to
+.Fn pdfork
+or
+.Fn pdrfork ,
+and compare it to the value returned by
+.Fn getpid
+after, to see if code is executing in parent or child.
.It Bq Er EINVAL
The signal number given to
.Fn pdkill
@@ -172,6 +251,12 @@ and
.Fn pdkill
system calls first appeared in
.Fx 9.0 .
+The
+.Fn pdrfork
+and
+.Fn pdwait
+system calls first appeared in
+.Fx 16.0 .
.Pp
Support for process descriptors mode was developed as part of the
.Tn TrustedBSD
@@ -184,3 +269,11 @@ and
.An Jonathan Anderson Aq Mt jonathan@FreeBSD.org
at the University of Cambridge Computer Laboratory with support from a grant
from Google, Inc.
+The
+.Fn pdrfork
+and
+.Fn pdwait
+functions were developed by
+.An Konstantin Belousov Aq Mt kib@FreeBSD.org
+with input from
+.An Alan Somers Aq Mt asomers@FreeBSD.org .
diff --git a/lib/libsys/pdrfork_thread_gen.c b/lib/libsys/pdrfork_thread_gen.c
new file mode 100644
index 000000000000..d36b2cc11993
--- /dev/null
+++ b/lib/libsys/pdrfork_thread_gen.c
@@ -0,0 +1,34 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2026 The FreeBSD Foundation
+ *
+ * This software were developed by
+ * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from
+ * the FreeBSD Foundation.
+ */
+
+#include <sys/types.h>
+#include <sys/procdesc.h>
+#include <errno.h>
+#include <unistd.h>
+
+pid_t
+pdrfork_thread(int *fdp, int pdflags, int rfflags, void *stack_addr,
+ int (*start_fn)(void *), void *arg)
+{
+ pid_t res;
+ int ret;
+
+ /* See comment in rfork_thread_gen.c. */
+ if (stack_addr != NULL) {
+ errno = EOPNOTSUPP;
+ return (-1);
+ }
+ res = pdrfork(fdp, pdflags, rfflags);
+ if (res == 0) {
+ ret = start_fn(arg);
+ _exit(ret);
+ }
+ return (res);
+}
diff --git a/lib/libsys/powerpc/Makefile.sys b/lib/libsys/powerpc/Makefile.sys
index 9979d5179f51..f066aae1a4fa 100644
--- a/lib/libsys/powerpc/Makefile.sys
+++ b/lib/libsys/powerpc/Makefile.sys
@@ -1,4 +1,6 @@
SRCS+= __vdso_gettc.c \
+ pdrfork_thread_gen.c \
+ rfork_thread_gen.c \
sched_getcpu_gen.c
MDASM+= cerror.S
diff --git a/lib/libsys/powerpc64/Makefile.sys b/lib/libsys/powerpc64/Makefile.sys
index 9979d5179f51..f066aae1a4fa 100644
--- a/lib/libsys/powerpc64/Makefile.sys
+++ b/lib/libsys/powerpc64/Makefile.sys
@@ -1,4 +1,6 @@
SRCS+= __vdso_gettc.c \
+ pdrfork_thread_gen.c \
+ rfork_thread_gen.c \
sched_getcpu_gen.c
MDASM+= cerror.S
diff --git a/lib/libsys/powerpcspe/Makefile.sys b/lib/libsys/powerpcspe/Makefile.sys
deleted file mode 100644
index 35909d68cd5e..000000000000
--- a/lib/libsys/powerpcspe/Makefile.sys
+++ /dev/null
@@ -1,5 +0,0 @@
-CFLAGS+= -I${LIBC_SRCTOP}/powerpc
-CFLAGS+= -I${LIBSYS_SRCTOP}/powerpc
-
-.PATH: ${LIBSYS_SRCTOP}/powerpc
-.include "${LIBSYS_SRCTOP}/powerpc/Makefile.sys"
diff --git a/lib/libsys/rename.2 b/lib/libsys/rename.2
index 4faba81ff509..dbad50edb9a9 100644
--- a/lib/libsys/rename.2
+++ b/lib/libsys/rename.2
@@ -39,6 +39,16 @@
.Fn rename "const char *from" "const char *to"
.Ft int
.Fn renameat "int fromfd" "const char *from" "int tofd" "const char *to"
+.In sys/fcntl.h
+.In stdio.h
+.Ft int
+.Fo renameat2
+.Fa "int fromfd"
+.Fa "const char *from"
+.Fa "int tofd"
+.Fa "const char *to"
+.Fa "unsigned int flags"
+.Fc
.Sh DESCRIPTION
The
.Fn rename
@@ -112,32 +122,28 @@ or
.Fa tofd
parameter, the current working directory is used in the determination
of the file for the respective path parameter.
-.\".Sh CAVEAT
-.\"The system can deadlock if a loop in the file system graph is present.
-.\"This loop takes the form of an entry in directory
-.\".Pa a ,
-.\"say
-.\".Pa a/foo ,
-.\"being a hard link to directory
-.\".Pa b ,
-.\"and an entry in
-.\"directory
-.\".Pa b ,
-.\"say
-.\".Pa b/bar ,
-.\"being a hard link
-.\"to directory
-.\".Pa a .
-.\"When such a loop exists and two separate processes attempt to
-.\"perform
-.\".Ql rename a/foo b/bar
-.\"and
-.\".Ql rename b/bar a/foo ,
-.\"respectively,
-.\"the system may deadlock attempting to lock
-.\"both directories for modification.
-.\"Hard links to directories should be
-.\"replaced by symbolic links by the system administrator.
+.Pp
+The
+.Fn renameat2
+system call takes an additional
+.Fa flags
+argument.
+If
+.Fa flags
+is zero, the
+.Fn renameat2
+call operates identically to
+.Fn renameat .
+Additionally, the following flags can be specified:
+.Bl -tag -width AT_RENAME_NOREPLACE
+.It Dv AT_RENAME_NOREPLACE
+If the path specified by
+.Fa tofd
+and
+.Fa to
+exists, the request fails with the error
+.Er EEXIST .
+.El
.Sh RETURN VALUES
.Rv -std rename
.Sh ERRORS
@@ -324,6 +330,35 @@ file descriptor lacks the
.Dv CAP_RENAMEAT_TARGET
right.
.El
+.Pp
+In addition to the errors returned by the
+.Fn renameat
+system call, the
+.Fn renameat2
+system call may fail if:
+.Bl -tag -width Er
+.It Bq Er EEXIST
+The
+.Dv AT_RENAME_NOREPLACE
+flag was provided, and a file exists at the path specified by
+.Fa to .
+.It Bq Er EOPNOTSUPP
+One of the
+.Fa flags
+specified is not supported by the filesystem where the to-be
+renamed file is located.
+.El
+.Sh CAVEATS
+If the filesystem which owns the file to be renamed does not
+implement the
+.Dv AT_RENAME_NOREPLACE
+flag, it is possible that due to race with target file creation,
+the error returned by the
+.Fn renameat2
+system call would be non-deterministically either
+.Er EEXIST
+or
+.Er EOPNOTSUPP .
.Sh SEE ALSO
.Xr chflags 2 ,
.Xr open 2 ,
@@ -341,3 +376,7 @@ The
.Fn renameat
system call appeared in
.Fx 8.0 .
+The
+.Fn renameat2
+system call appeared in
+.Fx 16.0 .
diff --git a/lib/libsys/rfork.2 b/lib/libsys/rfork.2
index 649b2acae6ce..bf6db7531126 100644
--- a/lib/libsys/rfork.2
+++ b/lib/libsys/rfork.2
@@ -194,6 +194,7 @@ There is insufficient swap space for the new process.
.Xr fork 2 ,
.Xr intro 2 ,
.Xr minherit 2 ,
+.Xr pdrfork 2 ,
.Xr vfork 2 ,
.Xr pthread_create 3 ,
.Xr rfork_thread 3
diff --git a/lib/libsys/rfork_thread_gen.c b/lib/libsys/rfork_thread_gen.c
new file mode 100644
index 000000000000..5a8f6e3f650f
--- /dev/null
+++ b/lib/libsys/rfork_thread_gen.c
@@ -0,0 +1,40 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2026 The FreeBSD Foundation
+ *
+ * This software were developed by
+ * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from
+ * the FreeBSD Foundation.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+
+pid_t
+rfork_thread(int flags, void *stack_addr, int (*start_fn)(void *), void *arg)
+{
+ pid_t res;
+ int ret;
+
+ /*
+ * Generic implementation cannot switch stacks. Only
+ * architecture-specific code knows how to do it. Require
+ * that caller knows that, and refuse to do operate if the
+ * stack was supplied.
+ *
+ * Note that implementations that do switch stack, would fault
+ * immediately if the passed stack is NULL. They do not need to
+ * specifically check for the NULL stack value.
+ */
+ if (stack_addr != NULL) {
+ errno = EOPNOTSUPP;
+ return (-1);
+ }
+ res = rfork(flags);
+ if (res == 0) {
+ ret = start_fn(arg);
+ _exit(ret);
+ }
+ return (res);
+}
diff --git a/lib/libsys/riscv/Makefile.sys b/lib/libsys/riscv/Makefile.sys
index 2ff84735f484..87181565f0be 100644
--- a/lib/libsys/riscv/Makefile.sys
+++ b/lib/libsys/riscv/Makefile.sys
@@ -1,4 +1,6 @@
SRCS+= __vdso_gettc.c \
+ pdrfork_thread_gen.c \
+ rfork_thread_gen.c \
sched_getcpu_gen.c
MDASM= cerror.S \
diff --git a/lib/libsys/sigreturn.2 b/lib/libsys/sigreturn.2
index 4effeaa5abc7..0e7bca507fc7 100644
--- a/lib/libsys/sigreturn.2
+++ b/lib/libsys/sigreturn.2
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 6, 2013
+.Dd March 11, 2026
.Dt SIGRETURN 2
.Os
.Sh NAME
@@ -47,17 +47,25 @@ The thread's signal mask and stack status are
restored from the context structure pointed to by
.Fa scp .
The system call does not return;
-the users stack pointer, frame pointer, argument pointer,
-and processor status longword are restored from the context.
-Execution resumes at the specified pc.
-This system call is used by the trampoline code and
-.Xr longjmp 3
+the whole userspace context as specified by
+.Fa scp ,
+including the userspace stack pointer, all general-purpose registers,
+coprocessor state, process status register, and program counter
+are restored from the context.
+Execution resumes at the program counter from the specified context.
+.Pp
+This system call is used by the kernel-provided signal trampoline code,
+located in the virtual DSO (VDSO) on some architectures or as raw code
+in the shared page if VDSO is not provided,
when returning from a signal to the previously executing program.
.Sh RETURN VALUES
If successful, the system call does not return.
-Otherwise, a value of -1 is returned and
+Otherwise, a value of -1 may be returned, with
.Va errno
-is set to indicate the error.
+set to indicate the error.
+Some conditions detected by hardware result in the delivery of
+a synchronous trap signal to the thread, in addition to or instead of
+setting the system call error code.
.Sh ERRORS
The
.Fn sigreturn
diff --git a/lib/libsys/socket.2 b/lib/libsys/socket.2
index 48b8f4e87489..3e4936b091be 100644
--- a/lib/libsys/socket.2
+++ b/lib/libsys/socket.2
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 28, 2025
+.Dd February 1, 2026
.Dt SOCKET 2
.Os
.Sh NAME
@@ -52,20 +52,66 @@ These families are defined in the include file
.In sys/socket.h .
The currently understood formats are:
.Pp
-.Bd -literal -offset indent -compact
-PF_LOCAL Host-internal protocols (alias for PF_UNIX),
-PF_UNIX Host-internal protocols,
-PF_INET Internet version 4 protocols,
-PF_INET6 Internet version 6 protocols,
-PF_DIVERT Firewall packet diversion/re-injection,
-PF_ROUTE Internal routing protocol,
-PF_KEY Internal key-management function,
-PF_NETGRAPH Netgraph sockets,
-PF_NETLINK Netlink protocols,
-PF_BLUETOOTH Bluetooth protocols,
-PF_INET_SDP OFED socket direct protocol (IPv4),
-PF_HYPERV HyperV sockets
-.Ed
+.Bl -tag -width "PF_BLUETOOTH"
+.It Dv PF_LOCAL
+Host-internal protocols (alias for
+.Dv PF_UNIX ) .
+.It Dv PF_UNIX
+Host-internal protocols.
+See
+.Xr unix 4 .
+.It Dv PF_INET
+Internet version 4 protocols.
+See
+.Xr icmp 4 ,
+.Xr igmp 4 ,
+.Xr ip 4 ,
+.Xr sctp 4 ,
+.Xr tcp 4 ,
+.Xr udp 4 ,
+.Xr udplite 4 .
+.It Dv PF_INET6
+Internet version 6 protocols.
+See
+.Xr icmp6 4 ,
+.Xr ip6 4 ,
+.Xr mld 4 .
+.It Dv PF_DIVERT
+Firewall packet diversion/re-injection.
+See
+.Xr divert 4 .
+.It Dv PF_ROUTE
+Legacy protocol to control routing tables and receive network
+configuration events from the kernel.
+New applications should prefer
+.Xr rtnetlink 4
+over
+.Xr route 4 .
+.It Dv PF_KEY
+Internal key-management function.
+See
+.Xr ipsec 4 .
+.It Dv PF_NETGRAPH
+Netgraph sockets.
+See
+.Xr netgraph 3
+and
+.Xr ng_socket 4 .
+.It Dv PF_NETLINK
+Netlink protocols.
+See
+.Xr genetlink 4 ,
+.Xr netlink 4 ,
+.Xr rtnetlink 4 .
+.It Dv PF_BLUETOOTH
+Bluetooth protocols.
+See
+.Xr ng_btsocket 4 .
+.It Dv PF_INET_SDP
+OFED socket direct protocol (IPv4).
+.It Dv PF_HYPERV
+HyperV sockets.
+.El
.Pp
Each protocol family is connected to an address family, which has the
same name except that the prefix is
@@ -82,22 +128,47 @@ which specifies the semantics of communication.
Currently
defined types are:
.Pp
-.Bd -literal -offset indent -compact
-SOCK_STREAM Stream socket,
-SOCK_DGRAM Datagram socket,
-SOCK_RAW Raw-protocol interface,
-SOCK_SEQPACKET Sequenced packet stream
-.Ed
+.Bl -tag -width "SOCK_SEQPACKET"
+.It Dv SOCK_STREAM
+Stream socket.
+.It Dv SOCK_DGRAM
+Datagram socket.
+.It Dv SOCK_RAW
+Raw-protocol interface.
+.It Dv SOCK_SEQPACKET
+Sequenced packet stream.
+.El
.Pp
Additionally, the following flags are allowed in the
.Fa type
argument:
.Pp
-.Bd -literal -offset indent -compact
-SOCK_CLOEXEC Set close-on-exec on the new descriptor,
-SOCK_CLOFORK Set close-on-fork on the new descriptor,
-SOCK_NONBLOCK Set non-blocking mode on the new socket
-.Ed
+.Bl -tag -width "SOCK_NONBLOCK"
+.It Dv SOCK_CLOEXEC
+Set close-on-exec on the new socket.
+See
+.Xr fcntl 2
+.Dv FD_CLOEXEC
+flag for
+.Dv F_GETFD
+command.
+.It Dv SOCK_CLOFORK
+Set close-on-fork on the new socket.
+See
+.Xr fcntl 2
+.Dv FD_CLOFORK
+flag for
+.Dv F_GETFD
+command.
+.It Dv SOCK_NONBLOCK
+Set non-blocking mode on the new socket.
+See
+.Xr fcntl 2
+.Dv O_NONBLOCK
+flag for
+.Dv F_SETFL
+command.
+.El
.Pp
The
.Fa protocol
@@ -423,10 +494,23 @@ The socket type is not supported by the protocol.
.Xr write 2 ,
.Xr CMSG_DATA 3 ,
.Xr getprotoent 3 ,
+.Xr netgraph 3 ,
.Xr divert 4 ,
+.Xr genetlink 4 ,
+.Xr icmp 4 ,
+.Xr icmp6 4 ,
+.Xr igmp 4 ,
.Xr ip 4 ,
.Xr ip6 4 ,
-.Xr netgraph 4 ,
+.Xr ipsec 4 ,
+.Xr netintro 4 ,
+.Xr netlink 4 ,
+.Xr ng_socket 4 ,
+.Xr route 4 ,
+.Xr rtnetlink 4 ,
+.Xr sctp 4 ,
+.Xr tcp 4 ,
+.Xr udp 4 ,
.Xr protocols 5
.Rs
.%T "An Introductory 4.3 BSD Interprocess Communication Tutorial"
diff --git a/lib/libsys/syscalls.map b/lib/libsys/syscalls.map
index d00c862eb462..928817e57b7c 100644
--- a/lib/libsys/syscalls.map
+++ b/lib/libsys/syscalls.map
@@ -819,4 +819,10 @@ FBSDprivate_1.0 {
__sys_jail_remove_jd;
_kexec_load;
__sys_kexec_load;
+ _pdrfork;
+ __sys_pdrfork;
+ _pdwait;
+ __sys_pdwait;
+ _renameat2;
+ __sys_renameat2;
};
diff --git a/lib/libsys/wait.2 b/lib/libsys/wait.2
index eeddf77aeac7..ca289c69f188 100644
--- a/lib/libsys/wait.2
+++ b/lib/libsys/wait.2
@@ -656,6 +656,7 @@ do not specify a valid set of processes.
.El
.Sh SEE ALSO
.Xr _exit 2 ,
+.Xr pdwait 2 ,
.Xr procctl 2 ,
.Xr ptrace 2 ,
.Xr sigaction 2 ,