From owner-freebsd-current@FreeBSD.ORG Sun Apr 13 21:47:14 2008 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 35708106567B for ; Sun, 13 Apr 2008 21:47:14 +0000 (UTC) (envelope-from delphij@delphij.net) Received: from tarsier.delphij.net (delphij-pt.tunnel.tserv2.fmt.ipv6.he.net [IPv6:2001:470:1f03:2c9::2]) by mx1.freebsd.org (Postfix) with ESMTP id 836AE8FC21 for ; Sun, 13 Apr 2008 21:47:13 +0000 (UTC) (envelope-from delphij@delphij.net) Received: from tarsier.geekcn.org (tarsier.geekcn.org [202.108.54.204]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by tarsier.delphij.net (Postfix) with ESMTPS id ABD6528448 for ; Mon, 14 Apr 2008 05:47:12 +0800 (CST) Received: from localhost (tarsier.geekcn.org [202.108.54.204]) by tarsier.geekcn.org (Postfix) with ESMTP id 76582EB1503; Mon, 14 Apr 2008 05:47:12 +0800 (CST) X-Virus-Scanned: amavisd-new at geekcn.org Received: from tarsier.geekcn.org ([202.108.54.204]) by localhost (mail.geekcn.org [202.108.54.204]) (amavisd-new, port 10024) with ESMTP id ijr0Tp3RbWOQ; Mon, 14 Apr 2008 05:47:06 +0800 (CST) Received: from charlie.delphij.net (c-69-181-135-56.hsd1.ca.comcast.net [69.181.135.56]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by tarsier.geekcn.org (Postfix) with ESMTPSA id 171B9EB1495; Mon, 14 Apr 2008 05:47:04 +0800 (CST) DomainKey-Signature: a=rsa-sha1; s=default; d=delphij.net; c=nofws; q=dns; h=message-id:date:from:reply-to:organization:user-agent: mime-version:to:subject:x-enigmail-version:openpgp:content-type; b=EbnuSduaW+85ZRqXGzvJzE2K3IeaozFIv3+D8Rgx5ZEhNE4YB+0iRSZsm8g7S2rzp yVcc649ywkLPAhNLHDeFQ== Message-ID: <48027F56.9010302@delphij.net> Date: Sun, 13 Apr 2008 14:47:02 -0700 From: Xin LI Organization: The FreeBSD Project User-Agent: Thunderbird 2.0.0.12 (X11/20080312) MIME-Version: 1.0 To: FreeBSD Current X-Enigmail-Version: 0.95.6 OpenPGP: id=18EDEBA0; url=http://www.delphij.net/delphij.asc Content-Type: multipart/mixed; boundary="------------020406040907070205010105" Subject: [PATCH] fdopendir(3) X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: d@delphij.net List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Apr 2008 21:47:14 -0000 This is a multi-part message in MIME format. --------------020406040907070205010105 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, Any objection for the attached patch which implements fdopendir(3) that is found in various other OSes? Basically it splits __opendir2 into two parts, and expose the second part which deals with fd to provide fdopendir(3) functionalities. Cheers, -- Xin LI http://www.delphij.net/ FreeBSD - The Power to Serve! --------------020406040907070205010105 Content-Type: text/plain; name="fdopendir.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="fdopendir.diff" Index: include/dirent.h =================================================================== RCS file: /home/ncvs/src/include/dirent.h,v retrieving revision 1.15 diff -u -p -r1.15 dirent.h --- include/dirent.h 20 Nov 2007 01:49:00 -0000 1.15 +++ include/dirent.h 13 Apr 2008 07:25:58 -0000 @@ -100,6 +100,7 @@ int getdents(int, char *, int); int getdirentries(int, char *, int, long *); #endif DIR *opendir(const char *); +DIR *fdopendir(int); struct dirent * readdir(DIR *); #if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 500 Index: lib/libc/gen/Makefile.inc =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/Makefile.inc,v retrieving revision 1.133 diff -u -p -r1.133 Makefile.inc --- lib/libc/gen/Makefile.inc 29 Mar 2008 16:19:35 -0000 1.133 +++ lib/libc/gen/Makefile.inc 13 Apr 2008 07:48:19 -0000 @@ -72,6 +72,7 @@ MLINKS+=arc4random.3 arc4random_addrando MLINKS+=ctermid.3 ctermid_r.3 MLINKS+=devname.3 devname_r.3 MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \ + directory.3 fdopendir.3 \ directory.3 readdir.3 directory.3 readdir_r.3 directory.3 rewinddir.3 \ directory.3 seekdir.3 directory.3 telldir.3 MLINKS+=dlopen.3 dlclose.3 dlopen.3 dlerror.3 dlopen.3 dlfunc.3 \ Index: lib/libc/gen/Symbol.map =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/Symbol.map,v retrieving revision 1.8 diff -u -p -r1.8 Symbol.map --- lib/libc/gen/Symbol.map 26 Jan 2008 17:09:40 -0000 1.8 +++ lib/libc/gen/Symbol.map 13 Apr 2008 07:45:37 -0000 @@ -451,3 +451,8 @@ FBSDprivate_1.0 { __waitpid; _waitpid; }; + + +FBSD_1.1 { + fdopendir; +}; Index: lib/libc/gen/directory.3 =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/directory.3,v retrieving revision 1.16 diff -u -p -r1.16 directory.3 --- lib/libc/gen/directory.3 9 Jan 2007 00:27:53 -0000 1.16 +++ lib/libc/gen/directory.3 13 Apr 2008 07:43:44 -0000 @@ -28,11 +28,12 @@ .\" @(#)directory.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD: src/lib/libc/gen/directory.3,v 1.16 2007/01/09 00:27:53 imp Exp $ .\" -.Dd June 4, 1993 +.Dd April 13, 2008 .Dt DIRECTORY 3 .Os .Sh NAME .Nm opendir , +.Nm fdopendir , .Nm readdir , .Nm readdir_r , .Nm telldir , @@ -48,6 +49,8 @@ .In dirent.h .Ft DIR * .Fn opendir "const char *filename" +.Ft DIR * +.Fn fdopendir "int filedes" .Ft struct dirent * .Fn readdir "DIR *dirp" .Ft int @@ -84,6 +87,15 @@ cannot be accessed, or if it cannot enough memory to hold the whole thing. .Pp The +.Fn fdopendir +function +associates a stream with the existing file descriptor, +.Fa fildes . +When the stream is closed via +.Xr closedir 3 , +fildes is closed also. +.Pp +The .Fn readdir function returns a pointer to the next directory entry. Index: lib/libc/gen/opendir.c =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/opendir.c,v retrieving revision 1.23 diff -u -p -r1.23 opendir.c --- lib/libc/gen/opendir.c 9 Jan 2007 00:27:54 -0000 1.23 +++ lib/libc/gen/opendir.c 13 Apr 2008 07:59:29 -0000 @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -47,32 +47,38 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/ope #include "un-namespace.h" #include "telldir.h" + +static inline DIR * __opendir_common(int, const char *, int); + /* * Open a directory. */ DIR * -opendir(name) - const char *name; +opendir(const char *name) { return (__opendir2(name, DTF_HIDEW|DTF_NODUP)); } +/* + * Open a directory with existing file descriptor. + */ DIR * -__opendir2(name, flags) - const char *name; - int flags; +fdopendir(int fd) +{ + + return (__opendir_common(fd, NULL, DTF_HIDEW|DTF_NODUP)); +} + +DIR * +__opendir2(const char *name, int flags) { - DIR *dirp; int fd; - int incr; - int saved_errno; - int unionstack; struct stat statb; /* * stat() before _open() because opening of special files may be - * harmful. _fstat() after open because the file may have changed. + * harmful. */ if (stat(name, &statb) != 0) return (NULL); @@ -82,7 +88,21 @@ __opendir2(name, flags) } if ((fd = _open(name, O_RDONLY | O_NONBLOCK)) == -1) return (NULL); + + return __opendir_common(fd, name, flags); +} + +static inline DIR * +__opendir_common(int fd, const char *name, int flags) +{ + DIR *dirp; + int incr; + int saved_errno; + int unionstack; + struct stat statb; + dirp = NULL; + /* _fstat() the open handler because the file may have changed. */ if (_fstat(fd, &statb) != 0) goto fail; if (!S_ISDIR(statb.st_mode)) { --------------020406040907070205010105--