git: 971f738679e2 - main - kern: Make dup3() support O_CLOFORK
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 06 Jul 2025 23:18:39 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=971f738679e2e57114366c0f69af99e07150f1ff
commit 971f738679e2e57114366c0f69af99e07150f1ff
Author: Ricardo Branco <rbranco@suse.de>
AuthorDate: 2025-05-17 09:53:10 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-07-06 23:08:37 +0000
kern: Make dup3() support O_CLOFORK
Reviewed by: kib
MFC after: 1 month
Pull Request: https://github.com/freebsd/freebsd-src/pull/1698
---
lib/libc/gen/dup3.c | 9 +++++----
sys/kern/kern_descrip.c | 15 ++++++++++++++-
sys/sys/fcntl.h | 4 ++++
3 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/lib/libc/gen/dup3.c b/lib/libc/gen/dup3.c
index fca1e99fb47b..1401c1f5b607 100644
--- a/lib/libc/gen/dup3.c
+++ b/lib/libc/gen/dup3.c
@@ -39,21 +39,22 @@ int __dup3(int, int, int);
int
__dup3(int oldfd, int newfd, int flags)
{
- int how;
+ int fdflags;
if (oldfd == newfd) {
errno = EINVAL;
return (-1);
}
- if (flags & ~O_CLOEXEC) {
+ if ((flags & ~(O_CLOEXEC | O_CLOFORK)) != 0) {
errno = EINVAL;
return (-1);
}
- how = (flags & O_CLOEXEC) ? F_DUP2FD_CLOEXEC : F_DUP2FD;
+ fdflags = ((flags & O_CLOEXEC) != 0 ? FD_CLOEXEC : 0) |
+ ((flags & O_CLOFORK) != 0 ? FD_CLOFORK : 0);
- return (_fcntl(oldfd, how, newfd));
+ return (_fcntl(oldfd, F_DUP3FD | (fdflags << F_DUP3FD_SHIFT), newfd));
}
__weak_reference(__dup3, dup3);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index e432f33d810e..406236fc2723 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -38,9 +38,11 @@
#include "opt_ddb.h"
#include "opt_ktrace.h"
+#define EXTERR_CATEGORY EXTERR_CAT_FILEDESC
#include <sys/systm.h>
#include <sys/capsicum.h>
#include <sys/conf.h>
+#include <sys/exterrvar.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
@@ -492,6 +494,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
int error, flg, kif_sz, seals, tmp, got_set, got_cleared;
uint64_t bsize;
off_t foffset;
+ int flags;
error = 0;
flg = F_POSIX;
@@ -923,7 +926,17 @@ revert_f_setfl:
break;
default:
- error = EINVAL;
+ if ((cmd & ((1u << F_DUP3FD_SHIFT) - 1)) != F_DUP3FD)
+ return (EXTERROR(EINVAL, "invalid fcntl cmd"));
+ /* Handle F_DUP3FD */
+ flags = (cmd >> F_DUP3FD_SHIFT);
+ if ((flags & ~(FD_CLOEXEC | FD_CLOFORK)) != 0)
+ return (EXTERROR(EINVAL, "invalid flags for F_DUP3FD"));
+ tmp = arg;
+ error = kern_dup(td, FDDUP_FIXED,
+ ((flags & FD_CLOEXEC) != 0 ? FDDUP_FLAG_CLOEXEC : 0) |
+ ((flags & FD_CLOFORK) != 0 ? FDDUP_FLAG_CLOFORK : 0),
+ fd, tmp);
break;
}
return (error);
diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h
index 7234c9240c84..18d3928e91c7 100644
--- a/sys/sys/fcntl.h
+++ b/sys/sys/fcntl.h
@@ -291,6 +291,10 @@ typedef __pid_t pid_t;
#endif
#if __BSD_VISIBLE
+#define F_DUP3FD 24 /* Used with dup3() */
+
+#define F_DUP3FD_SHIFT 16 /* Shift used for F_DUP3FD */
+
/* Seals (F_ADD_SEALS, F_GET_SEALS). */
#define F_SEAL_SEAL 0x0001 /* Prevent adding sealings */
#define F_SEAL_SHRINK 0x0002 /* May not shrink */