Date: Thu, 12 Jan 2012 00:01:29 -0500 From: Eitan Adler <lists@eitanadler.com> To: FreeBSD Hackers <freebsd-hackers@freebsd.org> Cc: jilles@freebsd.org, Colin Percival <cperciva@freebsd.org> Subject: dup3 syscall - atomic set O_CLOEXEC with dup2 Message-ID: <CAF6rxg=EjkwFbXQt3i2Nnz6_dcZtdek-2YdqyZnAdVPxVaWR_Q@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAF6rxg=EjkwFbXQt3i2Nnz6_dcZtdek-2YdqyZnAdVPxVaWR_Q>