aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2008-04-16 18:59:36 +0000
committerXin LI <delphij@FreeBSD.org>2008-04-16 18:59:36 +0000
commit6fda52ba75654d8a540536228390922bfae1db69 (patch)
tree8c9b74f319a953968d992cfa91a87e7fe29827a0
parentf6386c2536267cd1de56dc61657389e8648ade5e (diff)
downloadsrc-6fda52ba75654d8a540536228390922bfae1db69.tar.gz
src-6fda52ba75654d8a540536228390922bfae1db69.zip
Implement fdopendir(3) by splitting __opendir2() into two parts, the upper part
deals with the usual __opendir2() calls, and the rest part with an interface translator to expose fdopendir(3) functionality. Manual page was obtained from kib@'s work for *at(2) system calls.
Notes
Notes: svn path=/head/; revision=178256
-rw-r--r--include/dirent.h1
-rw-r--r--lib/libc/gen/Makefile.inc1
-rw-r--r--lib/libc/gen/Symbol.map1
-rw-r--r--lib/libc/gen/directory.339
-rw-r--r--lib/libc/gen/opendir.c36
-rw-r--r--sys/sys/param.h2
6 files changed, 73 insertions, 7 deletions
diff --git a/include/dirent.h b/include/dirent.h
index 3c2f0715f8cb..63626b59bc72 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -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
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index 6aa45a434162..c39fdb3c8679 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -72,6 +72,7 @@ MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3
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 \
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index 5ec8144842f6..22c43953db7f 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -329,6 +329,7 @@ FBSD_1.0 {
};
FBSD_1.1 {
+ fdopendir;
fts_open;
fts_close;
fts_read;
diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3
index 353def2651ed..3be3fa894fc3 100644
--- a/lib/libc/gen/directory.3
+++ b/lib/libc/gen/directory.3
@@ -28,11 +28,12 @@
.\" @(#)directory.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd June 4, 1993
+.Dd April 16, 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 fd"
.Ft struct dirent *
.Fn readdir "DIR *dirp"
.Ft int
@@ -84,6 +87,36 @@ cannot be accessed, or if it cannot
enough memory to hold the whole thing.
.Pp
The
+.Fn fdopendir
+function is equivalent to the
+.Fn opendir
+function except that the directory is specified by a file descriptor
+.Fa fd
+rather than by a name.
+The file offset associated with the file descriptor at the time of the call
+determines which entries are returned.
+.Pp
+Upon successful return from
+.Fn fdopendir ,
+the file descriptor is under the control of the system,
+and if any attempt is made to close the file descriptor,
+or to modify the state of the associated description other than by means
+of
+.Fn closedir ,
+.Fn readdir ,
+.Fn readdir_r ,
+or
+.Fn rewinddir ,
+the behavior is undefined.
+Upon calling
+.Fn closedir
+the file descriptor is closed.
+The
+.Dv FD_CLOEXEC
+flag is set on the file descriptor by a successful call to
+.Fn fdopendir .
+.Pp
+The
.Fn readdir
function
returns a pointer to the next directory entry.
@@ -202,3 +235,7 @@ and
.Fn dirfd
functions appeared in
.Bx 4.2 .
+The
+.Fn fdopendir
+function appeared in
+.Fx 8.0 .
diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c
index 5725ca3bc1a6..9625ec690941 100644
--- a/lib/libc/gen/opendir.c
+++ b/lib/libc/gen/opendir.c
@@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "telldir.h"
+
+static DIR * __opendir_common(int, const char *, int);
+
/*
* Open a directory.
*/
@@ -57,19 +60,25 @@ opendir(const char *name)
return (__opendir2(name, DTF_HIDEW|DTF_NODUP));
}
+/*
+ * Open a directory with existing file descriptor.
+ */
+DIR *
+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);
@@ -79,7 +88,24 @@ __opendir2(const char *name, int flags)
}
if ((fd = _open(name, O_RDONLY | O_NONBLOCK)) == -1)
return (NULL);
+
+ return __opendir_common(fd, name, flags);
+}
+
+/*
+ * Common routine for opendir(3), __opendir2(3) and fdopendir(3).
+ */
+static 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)) {
diff --git a/sys/sys/param.h b/sys/sys/param.h
index d9d51255cf66..ffeb7c7f0d30 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -57,7 +57,7 @@
* is created, otherwise 1.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 800034 /* Master, propagated to newvers */
+#define __FreeBSD_version 800035 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>