From nobody@FreeBSD.org  Mon Feb 18 09:54:40 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115])
	by hub.freebsd.org (Postfix) with ESMTP id 25DBAE90
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 18 Feb 2013 09:54:40 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id F2F91882
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 18 Feb 2013 09:54:39 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.5/8.14.5) with ESMTP id r1I9sdec061016
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 18 Feb 2013 09:54:39 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.5/8.14.5/Submit) id r1I9sdkr061015;
	Mon, 18 Feb 2013 09:54:39 GMT
	(envelope-from nobody)
Message-Id: <201302180954.r1I9sdkr061015@red.freebsd.org>
Date: Mon, 18 Feb 2013 09:54:39 GMT
From: Jukka Ukkonen <jau@iki.fi>
To: freebsd-gnats-submit@FreeBSD.org
Subject: New dup3() implementation for FreeBSD
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         176233
>Category:       kern
>Synopsis:       [libc] [patch] New dup3() implementation for FreeBSD
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    jilles
>State:          patched
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 18 10:00:00 UTC 2013
>Closed-Date:    
>Last-Modified:  Fri Aug 16 13:21:54 UTC 2013
>Originator:     Jukka Ukkonen
>Release:        9.1-STABLE
>Organization:
-----
>Environment:
FreeBSD sleipnir 9.1-STABLE FreeBSD 9.1-STABLE #0 r246937M: Mon Feb 18 08:44:50 EET 2013     root@sleipnir:/usr/obj/usr/src/sys/Sleipnir  amd64
>Description:
Because dup3() with the additional flags argument would be useful in general,
here is an implementation for FreeBSD.
Some other UNIX style systems (at least NetBSD and Linux) already have a similar
function. So, there is also the enhanced portability point of view driving this.
>How-To-Repeat:
No actual problem.
Only a nifty add-on feature and enhanced portability.

>Fix:
Find a patch attached.


Patch attached with submission follows:

--- ./lib/libc/gen/Makefile.inc.orig	2013-02-16 09:50:42.000000000 +0200
+++ ./lib/libc/gen/Makefile.inc	2013-02-16 09:50:59.000000000 +0200
@@ -10,7 +10,8 @@
 	alarm.c arc4random.c assert.c aux.c basename.c check_utility_compat.c \
 	clock.c closedir.c confstr.c \
 	crypt.c ctermid.c daemon.c devname.c dirname.c disklabel.c \
-	dlfcn.c drand48.c elf_utils.c erand48.c err.c errlst.c errno.c \
+	dlfcn.c drand48.c dup3.c \
+	elf_utils.c erand48.c err.c errlst.c errno.c \
 	exec.c fdevname.c feature_present.c fmtcheck.c fmtmsg.c fnmatch.c \
 	fpclassify.c frexp.c fstab.c ftok.c fts.c fts-compat.c ftw.c \
 	getbootfile.c getbsize.c \
--- ./lib/libc/gen/Symbol.map.orig	2013-02-16 09:52:41.000000000 +0200
+++ ./lib/libc/gen/Symbol.map	2013-02-16 09:53:25.000000000 +0200
@@ -382,6 +382,7 @@
 FBSD_1.3 {
 	 fdlopen;
 	__FreeBSD_libc_enter_restricted_mode;
+	dup3;
 	getcontextx;
 	gid_from_group;
 	nvis;
--- ./include/unistd.h.orig	2013-02-16 10:02:01.000000000 +0200
+++ ./include/unistd.h	2013-02-16 10:03:13.000000000 +0200
@@ -326,6 +326,9 @@
 void	 closefrom(int);
 int	 dup(int);
 int	 dup2(int, int);
+#if __BSD_VISIBLE
+int	 dup3(int, int, int);
+#endif
 int	 execl(const char *, const char *, ...);
 int	 execle(const char *, const char *, ...);
 int	 execlp(const char *, const char *, ...);
--- lib/libc/sys/Makefile.inc.orig	2013-02-16 10:34:41.000000000 +0200
+++ lib/libc/sys/Makefile.inc	2013-02-16 22:09:12.000000000 +0200
@@ -132,7 +132,7 @@
 MLINKS+=clock_gettime.2 clock_getres.2 clock_gettime.2 clock_settime.2
 MLINKS+=cpuset.2 cpuset_getid.2 cpuset.2 cpuset_setid.2
 MLINKS+=cpuset_getaffinity.2 cpuset_setaffinity.2
-MLINKS+=dup.2 dup2.2
+MLINKS+=dup.2 dup2.2 dup3.2
 MLINKS+=execve.2 fexecve.2
 MLINKS+=extattr_get_file.2 extattr.2 \
 	extattr_get_file.2 extattr_delete_fd.2 \
--- lib/libc/sys/dup.2.orig	2013-02-16 09:59:09.000000000 +0200
+++ lib/libc/sys/dup.2	2013-02-18 11:28:21.000000000 +0200
@@ -43,6 +43,9 @@
 .Fn dup "int oldd"
 .Ft int
 .Fn dup2 "int oldd" "int newd"
+.In fcntl.h
+.Ft int
+.Fn dup3 "int oldd" "int newd" "int flags"
 .Sh DESCRIPTION
 The
 .Fn dup
@@ -116,6 +119,72 @@
 .Fn dup2
 is successful, and does nothing.
 .Pp
+The
+.Fn dup3
+function is otherwise much the same as
+.Fn dup2
+with the added ability to automatically set certain
+important flags to the resulting new file descriptor.
+.br
+By setting the bit
+.Dv O_CLOEXEC
+in the flags one can mark the resulting file descriptor be
+automatically closed during
+.Fn execve
+and other functions in the
+.Fn exec*
+family.
+Since this feature is activated atomically inside the kernel
+there is no risk that even in a threaded code another thread
+could call any of the
+.Fn exec*
+functions before the descriptor has been marked to be closed.
+.br
+Setting the bit
+.Dv O_NONBLOCK
+in the flags marks the resulting file descriptor for non-blocking I/O.
+.sp
+There a couple of features in
+.Fn dup3
+which can have an impact on portability.
+.br
+Currently this implementation of
+.Fn dup3
+does not support the
+.Nx
+feature
+.Dv O_NOSIGPIPE .
+.br
+Because the
+.Fx
+kernel can properly handle the case when
+.Fa oldd
+==
+.Fa newd
+this implementation of
+.Fn dup3 
+will not return an error like 
+.Fn dup3 
+on Linux when it receives two equal file descriptors as arguments.
+Instead this implementation intentionally behaves like
+.Fn dup3
+in
+.Nx
+and sets the flags on the resulting file descriptor.
+Thus any code that has worked on Linux should
+work fine also on
+.Fx
+and/or
+.Nx ,
+but porting to the other direction may cause hiccups.
+.Pp
+Unlike the other two functions
+.Fn dup3
+is not implemented as a genuine system call but as a normal library function
+depending on the features provided by the
+.Fn fcntl
+system call.
+.Pp
 The related
 .Xr cap_new 2
 system call allows file descriptors to be duplicated with restrictions on
@@ -138,6 +207,7 @@
 .It Bq Er EMFILE
 Too many descriptors are active.
 .El
+.sp
 The
 .Fn dup2
 system call fails if:
@@ -149,6 +219,26 @@
 .Fa newd
 argument is negative or exceeds the maximum allowable descriptor number
 .El
+.sp
+The 
+.Fn dup3
+function fails if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa oldd
+argument is not a valid active descriptor or the
+.Fa newd
+argument is negative or exceeds the maximum allowable descriptor number
+.It Bq Er EINVAL
+The
+.Fa flags
+argument containes unsupported bits.
+Currently the only accepted bits are
+.Dv O_CLOEXEC 
+and
+.Dv O_NONBLOCK .
+.El
 .Sh SEE ALSO
 .Xr accept 2 ,
 .Xr cap_new 2 ,
@@ -166,6 +256,13 @@
 .Fn dup2
 system calls are expected to conform to
 .St -p1003.1-90 .
+.br
+Currently the
+.Fn dup3
+entry is not dictated by any standard.
+It is simply a natural extension the other two variants and
+a compatibility feature to match a similar extension in other
+UNIX like systems.
 .Sh HISTORY
 The
 .Fn dup
@@ -173,3 +270,9 @@
 .Fn dup2
 functions appeared in
 .At v7 .
+.br
+The
+.Fn dup3
+function appeared in
+.Fx 9.1
+STABLE branch.
--- /dev/null	2013-02-16 22:00:01.000000000 +0200
+++ lib/libc/gen/dup3.c	2013-02-16 22:03:55.000000000 +0200
@@ -0,0 +1,123 @@
+/*-
+ * Copyright (c) 2012 Jukka A. Ukkonen
+ * All rights reserved.
+ *
+ * This software was developed by Jukka Ukkonen for FreeBSD.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "un-namespace.h"
+
+/*
+ * A bunch of checks just in case someone
+ * tries to compile this on a too old system.
+ */
+
+#if !defined(F_DUP2FD_CLOEXEC) && defined(_F_DUP2FD_CLOEXEC)
+#  define F_DUP2FD_CLOEXEC  _F_DUP2FD_CLOEXEC
+#endif
+
+#if !defined(F_DUP2FD_CLOEXEC)
+#  error Neither F_DUP2FD_CLOEXEC nor _F_DUP2FD_CLOEXEC defined!
+#endif
+
+#if !defined(F_DUP2FD)
+#  error F_DUP2FD not defined!
+#endif
+
+#if !defined(O_CLOEXEC)
+#  error O_CLOEXEC not defined!
+#endif
+
+/*
+ * In case FreeBSD ever becomes O_NOSIGPIPE aware,
+ * we will instantly start using it.
+ */
+
+#if !defined(O_NOSIGPIPE)
+#  define O_NOSIGPIPE	0
+#endif
+
+int
+__dup3 (oldfd, newfd, flags)
+	int oldfd;
+	int newfd;
+	int flags;
+{
+	int how;
+	int ret;
+
+#if 0
+	/*
+	 * This would be how Linux does it
+	 * in pointlessly restrictive style.
+	 * NetBSD does not do this.
+	 * FreeBSD can also handle this case
+	 * properly.
+	 * ==> Anything which works on Linux
+	 * will work also on {Free,Net}BSD.
+	 * BSD code on Linux may experience
+	 * hiccups, if someone relies on
+	 * oldfd == newfd.
+	 */
+
+	if (oldfd == newfd) {
+		errno = EINVAL;
+		return (-1);
+	}
+#endif
+
+	if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_NOSIGPIPE)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	how = (flags & O_CLOEXEC) ? F_DUP2FD_CLOEXEC : F_DUP2FD;
+
+	ret = _fcntl (oldfd, how, newfd);
+
+	if (ret < 0)
+		return (-1);
+
+	newfd = ret;
+
+	if (flags & (O_NONBLOCK | O_NOSIGPIPE)) {
+		int flags2;
+
+		flags2 = _fcntl (newfd, F_GETFL, 0);
+		flags2 |= (flags & (O_NONBLOCK | O_NOSIGPIPE));
+		(void) _fcntl (newfd, F_SETFL, flags2);
+	}
+
+	return (newfd);
+}
+
+__weak_reference(__dup3, dup3);
+__weak_reference(__dup3, _dup3);


>Release-Note:
>Audit-Trail:

From: Jilles Tjoelker <jilles@stack.nl>
To: bug-followup@FreeBSD.org, jau@iki.fi
Cc:  
Subject: Re: kern/176233: [libc] [patch] New dup3() implementation for FreeBSD
Date: Wed, 20 Feb 2013 00:28:41 +0100

 PR kern/176233:
 > [dup3 implementation based on F_DUP2FD_CLOEXEC]
 
 The dup3() function appears to be used in the wild and there is a gnulib
 replacement for it, even though it seems of rather limited use compared
 to fcntl(F_DUPFD_CLOEXEC). Most uses of dup2() are for passing fd 0, 1
 or 2 to a process so that the close-on-exec flag should be clear.
 
 I think glibc's [EINVAL] on oldfd == newfd actually makes some sense as
 it forces the programmer to separate clearly the cases where oldfd !=
 newfd and oldfd == newfd. http://austingroupbugs.net/view.php?id=411
 also proposes requiring it.
 
 The O_NONBLOCK and O_NOSIGPIPE flags appear contrary to the idea of
 dup2/dup3 since they affect the underlying object and not just the new
 file descriptor like O_CLOEXEC does.
 
 Unknown/unsupported flags should indeed [EINVAL] so we have a chance to
 add new flags later.
 
 -- 
 Jilles Tjoelker

From: jau@iki.fi (Jukka A. Ukkonen)
To: jilles@stack.nl (Jilles Tjoelker)
Cc: bug-followup@FreeBSD.org, jau@iki.fi
Subject: Re: kern/176233: [libc] [patch] New dup3() implementation for FreeBSD
Date: Wed, 20 Feb 2013 11:13:14 +0200 (EET)

 Quoting Jilles Tjoelker:
 > 
 > PR kern/176233:
 > > [dup3 implementation based on F_DUP2FD_CLOEXEC]
 > 
 > The dup3() function appears to be used in the wild and there is a gnulib
 > replacement for it, even though it seems of rather limited use compared
 > to fcntl(F_DUPFD_CLOEXEC). Most uses of dup2() are for passing fd 0, 1
 > or 2 to a process so that the close-on-exec flag should be clear.
 > 
 > I think glibc's [EINVAL] on oldfd == newfd actually makes some sense as
 > it forces the programmer to separate clearly the cases where oldfd !=
 > newfd and oldfd == newfd. http://austingroupbugs.net/view.php?id=411
 > also proposes requiring it.
 
 This is a kind of a philosophical choise.
 Do we expect the programmer to pass two equal file descriptors
 intentionally or not?
 The Linux community and the Austin group have taken the view in
 which they do not trust the programmer to do it intentionally.
 The NetBSD way is to rely on the programmer to use the trick
 by choise, not by accident. Personally I rather like the latter
 approach. ;-)
 Also simple good style favors sticking to similar behavior as the
 existing dup2() while the "big academic problem" Linux has been
 solving with their deviant behavior is in fact more of a paper tiger.
 
 Anyhow were the large majority to prefer the pointlessly restrictive
 (in my mind) Linux approach over the NetBSD approach and over
 consistency with the existing dup2(), you have the necessary check
 included in my patch between "#if 0/#endif".
 
 Any time this sort of discussion about which school of thought to
 follow breaks up I quite miss the old ConvexOS "warp" concept.
 It would allow us to choose both ways at the same time.
 In ConvexOS warp was part of the process features which were inherited
 by the children, and the setting allowed various parts of the system
 (system calls, library functions, etc.) to choose which tradition and
 which school of thouht to follow. One just had to set a warp variable
 on the command line and the shell set that for the child processes
 using the setwarp() system call just before exec*().
 
 In this case I would personally like to enclose the check against
 equal file descriptors within a special warp check and be over
 with it...
 
 if (getwarp() == WARP_LINUX) {
 	if (oldd == newd) {
 		return (EINVAL);
 	}
 }
 
 FreeBSD just does not support the warp concept - at least not yet.
 
 OTOH adding the warp feature might actually help with the linuxulator
 and other emulation efforts.
 
 > The O_NONBLOCK and O_NOSIGPIPE flags appear contrary to the idea of
 > dup2/dup3 since they affect the underlying object and not just the new
 > file descriptor like O_CLOEXEC does.
 
 Right, I checked the current FreeBSD implementations of O_NONBLOCK and
 SO_NOSIGPIPE, which is the closest thing FreeBSD has to O_NOSIGPIPE.
 They seem to be implemented as flags in the file pointer structure
 and in the socket structure, not as part of the descriptor.
 
 The first question of course is whether the flags really have to be
 implemented this way, if the interpretation gives raise to problems?
 
 The second equally obvious question is, what prevents the programmer
 from setting those flags on the resulting new descriptor anyhow right
 after calling the existing dup2() and still affecting also the old
 descriptor in the process?
 
 Since the most common action to the old descriptor after dup2() is
 anyhow close() in case (oldfd != newfd), the side effect to the old
 descriptor should be mostly irrelevant. At the same time the added
 convenience to the programmer might be quite beneficial in avoiding
 situations in which one simply forgets to set such flags when they
 would be needed.
 Compactness and readability of the code is also enhanced when one
 does not have to write separate function/system calls after dup2()
 to get the same effect.
 
 A technical limitation might simply not be the proper solution to
 something which would be better served by adding a serious warning
 in the manual page saying roughly...
 "Do not call dup*() and then expect calling lseek() or changing flags
 on one of the multiple descriptors to an object not to affect the
 behavior when using any of the other descriptors to the same object.
 The dup*() family only adds handles to an object. It does not make
 copies of the underlying object.
 Though you gain multiple descriptors you still have only one object.
 If you change an object through any of the descriptors, the change
 will be visible also when using the object through any of the other
 descriptors."
 
 > Unknown/unsupported flags should indeed [EINVAL] so we have a chance to
 > add new flags later.
 
 ;-)
 
 
 	Cheers,
 		// jau
 .---  ..-  -.-  -.-  .-    .-  .-.-.-    ..-  -.-  -.-  ---  -.  .  -.
   /    Jukka A. Ukkonen,                             Oxit Ltd, Finland
  /__   M.Sc. (sw-eng & cs)                    (Phone) +358-500-606-671
    /   Internet: Jukka.Ukkonen(a)Oxit.Fi
   /    Internet: jau(a)iki.fi
  v
         .---  .-  ..-  ...-.-  ..  -.-  ..  .-.-.-  ..-.  ..
 + + + + My opinions are mine and mine alone, not my employers. + + + +

From: Jilles Tjoelker <jilles@stack.nl>
To: "Jukka A. Ukkonen" <jau@iki.fi>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/176233: [libc] [patch] New dup3() implementation for FreeBSD
Date: Sat, 23 Feb 2013 17:30:32 +0100

 On Wed, Feb 20, 2013 at 11:13:14AM +0200, Jukka A. Ukkonen wrote:
 > Quoting Jilles Tjoelker:
 
 > > PR kern/176233:
 > > > [dup3 implementation based on F_DUP2FD_CLOEXEC]
 
 > > The dup3() function appears to be used in the wild and there is a gnulib
 > > replacement for it, even though it seems of rather limited use compared
 > > to fcntl(F_DUPFD_CLOEXEC). Most uses of dup2() are for passing fd 0, 1
 > > or 2 to a process so that the close-on-exec flag should be clear.
 
 > > I think glibc's [EINVAL] on oldfd == newfd actually makes some sense as
 > > it forces the programmer to separate clearly the cases where oldfd !=
 > > newfd and oldfd == newfd. http://austingroupbugs.net/view.php?id=411
 > > also proposes requiring it.
 
 > This is a kind of a philosophical choise.
 > Do we expect the programmer to pass two equal file descriptors
 > intentionally or not?
 > The Linux community and the Austin group have taken the view in
 > which they do not trust the programmer to do it intentionally.
 > The NetBSD way is to rely on the programmer to use the trick
 > by choise, not by accident. Personally I rather like the latter
 > approach. ;-)
 > Also simple good style favors sticking to similar behavior as the
 > existing dup2() while the "big academic problem" Linux has been
 > solving with their deviant behavior is in fact more of a paper tiger.
 
 > Anyhow were the large majority to prefer the pointlessly restrictive
 > (in my mind) Linux approach over the NetBSD approach and over
 > consistency with the existing dup2(), you have the necessary check
 > included in my patch between "#if 0/#endif".
 
 Some more rationale from the Linux/glibc side about this:
 http://www.cygwin.com/ml/libc-ports/2011-09/msg00009.html
 
 Basically, if x != y, dup3(x, y, O_CLOEXEC) ensures y is set CLOEXEC and
 dup3(x, y, 0) ensures y is set not CLOEXEC. This breaks down if x == y.
 
 -- 
 Jilles Tjoelker
Responsible-Changed-From-To: freebsd-bugs->jilles 
Responsible-Changed-By: jilles 
Responsible-Changed-When: Sun Mar 17 21:02:20 UTC 2013 
Responsible-Changed-Why:  
I plan to commit this because it seems dup3() is a bit more 
popular than fcntl(F_DUP2FD_CLOEXEC). This may be after the 
other CLOEXEC changes. 

Regarding use, it appears that APR can use this, and I even used 
F_DUP2FD_CLOEXEC myself in freopen(). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=176233 

From: Jukka Ukkonen <jau789@gmail.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/176233: [libc] [patch] New dup3() implementation for FreeBSD
Date: Mon, 12 Aug 2013 14:43:05 +0300

 I just noticed that the patch included in this ticket
 is slightly in error when setting up the manual pages.
 This change...
 
 --- lib/libc/sys/Makefile.inc.orig    2013-02-16 10:34:41.000000000 +0200
 +++ lib/libc/sys/Makefile.inc       2013-02-16 22:09:12.000000000 +0200
 @@ -132,7 +132,7 @@
  MLINKS+=clock_gettime.2 clock_getres.2 clock_gettime.2 clock_settime.2
  MLINKS+=cpuset.2 cpuset_getid.2 cpuset.2 cpuset_setid.2
  MLINKS+=cpuset_getaffinity.2 cpuset_setaffinity.2
 -MLINKS+=dup.2 dup2.2
 +MLINKS+=dup.2 dup2.2 dup3.2
  MLINKS+=execve.2 fexecve.2
  MLINKS+=extattr_get_file.2 extattr.2 \
      extattr_get_file.2 extattr_delete_fd.2 \
 
 should be like this...
 
 --- lib/libc/sys/Makefile.inc.orig    2013-02-16 10:34:41.000000000 +0200
 +++ lib/libc/sys/Makefile.inc       2013-02-16 22:09:12.000000000 +0200
 @@ -132,7 +132,7 @@
  MLINKS+=clock_gettime.2 clock_getres.2 clock_gettime.2 clock_settime.2
  MLINKS+=cpuset.2 cpuset_getid.2 cpuset.2 cpuset_setid.2
  MLINKS+=cpuset_getaffinity.2 cpuset_setaffinity.2
 -MLINKS+=dup.2 dup2.2
 +MLINKS+=dup.2 dup2.2 dup.2 dup3.2
  MLINKS+=execve.2 fexecve.2
  MLINKS+=extattr_get_file.2 extattr.2 \
      extattr_get_file.2 extattr_delete_fd.2 \
 
 So, the new MLINKS setting was missing one instance of "dup.2"
 which will create a mess in the man2 directory, if applied as is.
 
 For some reason I had saved an older version of the patch file
 and when sending the change ticket I apparently managed to attach
 the older and broken file.
 
 Cheers,
 --jau

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/176233: commit references a PR
Date: Fri, 16 Aug 2013 13:10:38 +0000 (UTC)

 Author: jilles
 Date: Fri Aug 16 13:10:30 2013
 New Revision: 254409
 URL: http://svnweb.freebsd.org/changeset/base/254409
 
 Log:
   Add dup3(), based on F_DUP2FD and F_DUP2FD_CLOEXEC fcntls.
   
   I removed functionality not proposed for POSIX in Austin group issue #411.
   A man page (my own) and test cases will follow in later commits.
   
   PR:		176233
   Submitted by:	Jukka Ukkonen
 
 Added:
   head/lib/libc/gen/dup3.c   (contents, props changed)
 Modified:
   head/include/unistd.h
   head/lib/libc/gen/Makefile.inc
   head/lib/libc/gen/Symbol.map
 
 Modified: head/include/unistd.h
 ==============================================================================
 --- head/include/unistd.h	Fri Aug 16 12:25:02 2013	(r254408)
 +++ head/include/unistd.h	Fri Aug 16 13:10:30 2013	(r254409)
 @@ -493,6 +493,7 @@ const char *
  int	 crypt_set_format(const char *);
  int	 des_cipher(const char *, char *, long, int);
  int	 des_setkey(const char *key);
 +int	 dup3(int, int, int);
  int	 eaccess(const char *, int);
  void	 endusershell(void);
  int	 exect(const char *, char * const *, char * const *);
 
 Modified: head/lib/libc/gen/Makefile.inc
 ==============================================================================
 --- head/lib/libc/gen/Makefile.inc	Fri Aug 16 12:25:02 2013	(r254408)
 +++ head/lib/libc/gen/Makefile.inc	Fri Aug 16 13:10:30 2013	(r254409)
 @@ -31,6 +31,7 @@ SRCS+=	__getosreldate.c \
  	disklabel.c \
  	dlfcn.c \
  	drand48.c \
 +	dup3.c \
  	elf_utils.c \
  	erand48.c \
  	err.c \
 
 Modified: head/lib/libc/gen/Symbol.map
 ==============================================================================
 --- head/lib/libc/gen/Symbol.map	Fri Aug 16 12:25:02 2013	(r254408)
 +++ head/lib/libc/gen/Symbol.map	Fri Aug 16 13:10:30 2013	(r254409)
 @@ -383,6 +383,7 @@ FBSD_1.2 {
  FBSD_1.3 {
  	clock_getcpuclockid;
  	dirfd;
 +	dup3;
  	 fdlopen;
  	__FreeBSD_libc_enter_restricted_mode;
  	getcontextx;
 
 Added: head/lib/libc/gen/dup3.c
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/lib/libc/gen/dup3.c	Fri Aug 16 13:10:30 2013	(r254409)
 @@ -0,0 +1,59 @@
 +/*-
 + * Copyright (c) 2012 Jukka A. Ukkonen
 + * All rights reserved.
 + *
 + * This software was developed by Jukka Ukkonen for FreeBSD.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 + * SUCH DAMAGE.
 + */
 +
 +#include <sys/cdefs.h>
 +__FBSDID("$FreeBSD$");
 +
 +#include "namespace.h"
 +#include <unistd.h>
 +#include <fcntl.h>
 +#include <errno.h>
 +#include "un-namespace.h"
 +
 +int
 +__dup3(int oldfd, int newfd, int flags)
 +{
 +	int how;
 +
 +	if (oldfd == newfd) {
 +		errno = EINVAL;
 +		return (-1);
 +	}
 +
 +	if (flags & ~O_CLOEXEC) {
 +		errno = EINVAL;
 +		return (-1);
 +	}
 +
 +	how = (flags & O_CLOEXEC) ? F_DUP2FD_CLOEXEC : F_DUP2FD;
 +
 +	return (_fcntl(oldfd, how, newfd));
 +}
 +
 +__weak_reference(__dup3, dup3);
 +__weak_reference(__dup3, _dup3);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: jilles 
State-Changed-When: Fri Aug 16 13:21:37 UTC 2013 
State-Changed-Why:  
Added to 10-current, thanks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=176233 
>Unformatted:
