This is an implementation of dup3 for FreeBSD:
man page here (with a FreeBSD patch coming soon):
https://www.kernel.org/doc/man-pages/online/pages/man2/dup.2.html

Is this implementation correct? If so any objection to adding this as
a supported syscall?


Index: sys/kern/kern_descrip.c
===================================================================
--- sys/kern/kern_descrip.c     (revision 229830)
+++ sys/kern/kern_descrip.c     (working copy)
@@ -110,6 +110,7 @@
 /* Flags for do_dup() */
 #define DUP_FIXED      0x1     /* Force fixed allocation */
 #define DUP_FCNTL      0x2     /* fcntl()-style errors */
+#define DUP_CLOEXEC    0x4     /* Enable O_CLOEXEC on the new fs */

 static int do_dup(struct thread *td, int flags, int old, int new,
     register_t *retval);
@@ -307,7 +308,39 @@
        return (0);
 }

+#ifndef _SYS_SYSPROTO_H_
+struct dup3_args {
+       u_int   from;
+       u_int   to;
+       int     flags;
+};
+#endif
+
 /*
+ * Duplicate a file descriptor and allow for O_CLOEXEC
+ */
+
+/* ARGSUSED */
+int
+sys_dup3(struct thread * const td, struct dup3_args * const uap) {
+
+       KASSERT(td != NULL, ("%s: td == NULL", __func__));
+       KASSERT(uap != NULL, ("%s: uap == NULL", __func__));
+
+       if (uap->from == uap->to)
+               return EINVAL;
+
+       if (uap->flags & ~O_CLOEXEC)
+               return EINVAL;
+
+       const int dupflags = (uap->flags == O_CLOEXEC) ?
DUP_FIXED|DUP_CLOEXEC : DUP_FIXED;
+
+       return (do_dup(td, dupflags, (int)uap->from, (int)uap->to,
+                   td->td_retval));
+       return (0);
+}
+
+/*
  * Duplicate a file descriptor to a particular value.
  *
  * Note: keep in mind that a potential race condition exists when closing
@@ -912,6 +945,9 @@
                fdp->fd_lastfile = new;
        *retval = new;

+       if (flags & DUP_CLOEXEC)
+               fdp->fd_ofileflags[new] |= UF_EXCLOSE;
+
        /*
         * If we dup'd over a valid file, we now own the reference to it
         * and must dispose of it using closef() semantics (as if a
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master    (revision 229830)
+++ sys/kern/syscalls.master    (working copy)
@@ -951,5 +951,6 @@
                                    off_t offset, off_t len); }
 531    AUE_NULL        STD     { int posix_fadvise(int fd, off_t offset, \
                                    off_t len, int advice); }
+532    AUE_NULL        STD     { int dup3(u_int from, u_int to, int flags); }
 ; Please copy any additions and changes to the following compatability tables:
 ; sys/compat/freebsd32/syscalls.master
Index: sys/compat/freebsd32/syscalls.master
===================================================================
--- sys/compat/freebsd32/syscalls.master        (revision 229830)
+++ sys/compat/freebsd32/syscalls.master        (working copy)
@@ -997,3 +997,4 @@
                                    uint32_t offset1, uint32_t offset2,\
                                    uint32_t len1, uint32_t len2, \
                                    int advice); }
+532    AUE_NULL        STD     { int dup3(u_int from, u_int to, int flags); }


-- 
Eitan Adler
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to