The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=971f738679e2e57114366c0f69af99e07150f1ff

commit 971f738679e2e57114366c0f69af99e07150f1ff
Author:     Ricardo Branco <rbra...@suse.de>
AuthorDate: 2025-05-17 09:53:10 +0000
Commit:     Mark Johnston <ma...@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 */

Reply via email to