From nobody@FreeBSD.org  Sun Feb  3 07:14:34 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id BC80616A418
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  3 Feb 2008 07:14:34 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id A94BE13C46A
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  3 Feb 2008 07:14:34 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m137CbNE032767
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 3 Feb 2008 07:12:37 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.2/8.14.1/Submit) id m137CbA1032766;
	Sun, 3 Feb 2008 07:12:37 GMT
	(envelope-from nobody)
Message-Id: <200802030712.m137CbA1032766@www.freebsd.org>
Date: Sun, 3 Feb 2008 07:12:37 GMT
From: Jukka Ukkonen <jau@iki.fi>
To: freebsd-gnats-submit@FreeBSD.org
Subject: FreeBSD is missing fcntl() operation F_DUP2FD
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         120233
>Category:       kern
>Synopsis:       [libc] [patch] [request] FreeBSD is missing fcntl() operation F_DUP2FD
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    antoine
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Feb 03 07:20:00 UTC 2008
>Closed-Date:    Sun Apr 20 20:05:51 UTC 2008
>Last-Modified:  Sun Apr 20 20:05:51 UTC 2008
>Originator:     Jukka Ukkonen
>Release:        FreeBSD 6.3-STABLE
>Organization:
private person
>Environment:
FreeBSD mjolnir 6.3-STABLE FreeBSD 6.3-STABLE #0: Sat Feb  2 12:48:48 EET 2008     root@mjolnir:/usr/obj/usr/src/sys/Mjolnir  i386
>Description:
This is a compatibility issue.

At least SunOS/Solaris and AIX both have an fcntl() operation F_DUP2FD which is
to dup2() as F_DUPFD is to dup().
Having support to this fcntl() operation would improve software portability
between FreeBSD and other UNIX style systems.
Additionally it would allow both dup() and dup2() be implemented as library
functions narrowing down the system call API.

This PR supersedes the 3.5 years old kern/70798 which provided the same feature
for FreeBSD-4.10. The old ticket is still in the state open and nobody has
cared as much as to say a simple "no" since its introduction.

This PR contains an upgraded patch against FreeBSD-6.3 sources implementing
the F_DUP2FD operation and a test program to show F_DUP2FD in action,
if it is supported.

I have had this modification in my own environments for some 4 years starting
from FreeBSD-4.x with no ill effects.
In fact in my own C library I have both dup() and dup2() only as wrappers for
fcntl() and everything works just fine.

>How-To-Repeat:
Try the test program shown below before and after applying the patch and notice
the difference in its output.


#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

static void
dumpstat (st)
    struct stat	*st;
{
    printf ("st_dev   = %ld\n", (long) st->st_dev);
    printf ("st_ino   = %ld\n", (long) st->st_ino);
    printf ("st_nlink = %ld\n", (long) st->st_nlink);
    printf ("st_uid   = %ld\n", (long) st->st_uid);
    printf ("st_gid   = %ld\n", (long) st->st_gid);
    printf ("st_rdev  = %ld\n", (long) st->st_rdev);
}

static void
viewfdstat (fd)
    int	    fd;
{
    struct stat	st1;

    if (fstat (fd, &st1) < 0) {
	fprintf (stderr, "fstat(%d): %s\n", fd, strerror (errno));
    }
    else {
	printf ("fstat(%d):\n", fd);

	dumpstat (&st1);
    }
}

int
main (ac, av)
    int	    ac;
    char    *av[];
{
    int	    fd;

    viewfdstat (0);

    fd = open ("/dev/null", O_RDWR, 0);

    viewfdstat (fd);

#ifndef	F_DUP2FD
#define F_DUP2FD    F_DUPFD
#warning This system does not support F_DUP2FD.
#endif

    if (fcntl (fd, F_DUP2FD, 0) < 0) {
	fprintf (stderr,
		 "fcntl(%d, F_DUP2FD, 0): %s\n",
		 fd, strerror (errno));
    }

    viewfdstat (0);

    return (0);
}


>Fix:
Apply the attached patch.


Patch attached with submission follows:

--- sys/sys/fcntl.h.orig	2008-02-02 07:45:25.000000000 +0200
+++ sys/sys/fcntl.h	2008-02-02 07:47:21.000000000 +0200
@@ -176,6 +176,7 @@
 #define	F_GETLK		7		/* get record locking information */
 #define	F_SETLK		8		/* set record locking information */
 #define	F_SETLKW	9		/* F_SETLK; wait if blocked */
+#define	F_DUP2FD	10		/* duplicate file descriptor, fixed */
 
 /* file descriptor flags (F_GETFD, F_SETFD) */
 #define	FD_CLOEXEC	1		/* close-on-exec flag */
--- sys/kern/kern_descrip.c.orig	2008-02-02 07:39:50.000000000 +0200
+++ sys/kern/kern_descrip.c	2008-02-02 07:41:31.000000000 +0200
@@ -365,6 +365,7 @@
 	 */
 	switch (cmd) {
 	case F_DUPFD:
+	case F_DUP2FD:
 	case F_GETFD:
 	case F_SETFD:
 	case F_GETFL:
@@ -405,6 +406,21 @@
 		error = do_dup(td, DUP_VARIABLE, fd, newmin, td->td_retval);
 		break;
 
+	case F_DUP2FD:
+		/* mtx_assert(&Giant, MA_NOTOWNED); */
+		FILEDESC_UNLOCK(fdp);
+		newmin = arg;
+		PROC_LOCK(p);
+		if (newmin >= lim_cur(p, RLIMIT_NOFILE) ||
+		    newmin >= maxfilesperproc) {
+			PROC_UNLOCK(p);
+			error = EINVAL;
+			break;
+		}
+		PROC_UNLOCK(p);
+		error = do_dup(td, DUP_FIXED, fd, newmin, td->td_retval);
+		break;
+
 	case F_GETFD:
 		/* mtx_assert(&Giant, MA_NOTOWNED); */
 		td->td_retval[0] = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0;


>Release-Note:
>Audit-Trail:

From: Robert Watson <rwatson@FreeBSD.org>
To: Jukka Ukkonen <jau@iki.fi>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: kern/120233: FreeBSD is missing fcntl() operation F_DUP2FD
Date: Sun, 3 Feb 2008 19:17:25 +0000 (GMT)

 On Sun, 3 Feb 2008, Jukka Ukkonen wrote:
 
 > I have had this modification in my own environments for some 4 years 
 > starting from FreeBSD-4.x with no ill effects. In fact in my own C library I 
 > have both dup() and dup2() only as wrappers for fcntl() and everything works 
 > just fine.
 
 No opinion on the remainder of the patch, but just wanted to chime in on this 
 one point: once a system call is in the ABI, we generally won't ever remove 
 it.  The reason is that this would break backward compatibility for older 
 binaries and libraries that encode the old system call.  There may be an 
 argument for adding the new fcntl() interface, but there isn't really an 
 argument to remove the old system calls that overrides the need for backward 
 compatibility.  I will generally comment that it's unfortunate that we end up 
 with many APIs for the same operation, though, but that's generally a concern 
 overriden by the need for portability.
 
 Robert N M Watson
 Computer Laboratory
 University of Cambridge
Responsible-Changed-From-To: freebsd-bugs->antoine 
Responsible-Changed-By: antoine 
Responsible-Changed-When: Sat Feb 23 10:05:42 UTC 2008 
Responsible-Changed-Why:  
Take this. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/120233: commit references a PR
Date: Sat,  8 Mar 2008 22:02:28 +0000 (UTC)

 antoine     2008-03-08 22:02:21 UTC
 
   FreeBSD src repository
 
   Modified files:
     lib/libc/sys         fcntl.2 
     sys/kern             kern_descrip.c 
     sys/sys              fcntl.h 
     tools/regression/file/dup dup.c 
   Log:
   Introduce a new F_DUP2FD command to fcntl(2), for compatibility with
   Solaris and AIX.
   fcntl(fd, F_DUP2FD, arg) and dup2(fd, arg) are functionnaly equivalent.
   Document it.
   Add some regression tests (identical to the dup2(2) regression tests).
   
   PR:             120233
   Submitted by:   Jukka Ukkonen
   Approved by:    rwaston (mentor)
   MFC after:      1 month
   
   Revision  Changes    Path
   1.46      +37 -1     src/lib/libc/sys/fcntl.2
   1.325     +6 -1      src/sys/kern/kern_descrip.c
   1.18      +1 -0      src/sys/sys/fcntl.h
   1.3       +71 -2     src/tools/regression/file/dup/dup.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: antoine 
State-Changed-When: Sat Mar 8 22:13:35 UTC 2008 
State-Changed-Why:  
patched in HEAD. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/120233: commit references a PR
Date: Sun, 20 Apr 2008 19:32:51 +0000 (UTC)

 antoine     2008-04-20 19:32:46 UTC
 
   FreeBSD src repository
 
   Modified files:        (Branch: RELENG_7)
     lib/libc/sys         fcntl.2 
     sys/kern             kern_descrip.c 
     sys/sys              fcntl.h param.h 
     tools/regression/file/dup dup.c 
   Log:
   MFC to RELENG_7:
     Introduce a new F_DUP2FD command to fcntl(2), for compatibility with
     Solaris and AIX.
     fcntl(fd, F_DUP2FD, arg) and dup2(fd, arg) are functionnaly equivalent.
     Document it.
     Add some regression tests (identical to the dup2(2) regression tests).
   
     PR:             120233
     Submitted by:   Jukka Ukkonen
     Approved by:    rwaston (mentor)
     MFC after:      1 month
   
   Revision    Changes    Path
   1.45.2.2    +37 -1     src/lib/libc/sys/fcntl.2
   1.313.2.5   +6 -1      src/sys/kern/kern_descrip.c
   1.16.18.2   +1 -1      src/sys/sys/fcntl.h
   1.308.2.11  +1 -1      src/sys/sys/param.h
   1.2.2.1     +71 -2     src/tools/regression/file/dup/dup.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: antoine 
State-Changed-When: Sun Apr 20 20:05:07 UTC 2008 
State-Changed-Why:  
Close: committed in HEAD and RELENG_7. 
Thanks! 

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