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.
This commit is contained in:
parent
f6386c2536
commit
6fda52ba75
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=178256
@ -100,6 +100,7 @@ int getdents(int, char *, int);
|
|||||||
int getdirentries(int, char *, int, long *);
|
int getdirentries(int, char *, int, long *);
|
||||||
#endif
|
#endif
|
||||||
DIR *opendir(const char *);
|
DIR *opendir(const char *);
|
||||||
|
DIR *fdopendir(int);
|
||||||
struct dirent *
|
struct dirent *
|
||||||
readdir(DIR *);
|
readdir(DIR *);
|
||||||
#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 500
|
#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 500
|
||||||
|
@ -72,6 +72,7 @@ MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3
|
|||||||
MLINKS+=ctermid.3 ctermid_r.3
|
MLINKS+=ctermid.3 ctermid_r.3
|
||||||
MLINKS+=devname.3 devname_r.3
|
MLINKS+=devname.3 devname_r.3
|
||||||
MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.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 readdir.3 directory.3 readdir_r.3 directory.3 rewinddir.3 \
|
||||||
directory.3 seekdir.3 directory.3 telldir.3
|
directory.3 seekdir.3 directory.3 telldir.3
|
||||||
MLINKS+=dlopen.3 dlclose.3 dlopen.3 dlerror.3 dlopen.3 dlfunc.3 \
|
MLINKS+=dlopen.3 dlclose.3 dlopen.3 dlerror.3 dlopen.3 dlfunc.3 \
|
||||||
|
@ -329,6 +329,7 @@ FBSD_1.0 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
FBSD_1.1 {
|
FBSD_1.1 {
|
||||||
|
fdopendir;
|
||||||
fts_open;
|
fts_open;
|
||||||
fts_close;
|
fts_close;
|
||||||
fts_read;
|
fts_read;
|
||||||
|
@ -28,11 +28,12 @@
|
|||||||
.\" @(#)directory.3 8.1 (Berkeley) 6/4/93
|
.\" @(#)directory.3 8.1 (Berkeley) 6/4/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 4, 1993
|
.Dd April 16, 2008
|
||||||
.Dt DIRECTORY 3
|
.Dt DIRECTORY 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm opendir ,
|
.Nm opendir ,
|
||||||
|
.Nm fdopendir ,
|
||||||
.Nm readdir ,
|
.Nm readdir ,
|
||||||
.Nm readdir_r ,
|
.Nm readdir_r ,
|
||||||
.Nm telldir ,
|
.Nm telldir ,
|
||||||
@ -48,6 +49,8 @@
|
|||||||
.In dirent.h
|
.In dirent.h
|
||||||
.Ft DIR *
|
.Ft DIR *
|
||||||
.Fn opendir "const char *filename"
|
.Fn opendir "const char *filename"
|
||||||
|
.Ft DIR *
|
||||||
|
.Fn fdopendir "int fd"
|
||||||
.Ft struct dirent *
|
.Ft struct dirent *
|
||||||
.Fn readdir "DIR *dirp"
|
.Fn readdir "DIR *dirp"
|
||||||
.Ft int
|
.Ft int
|
||||||
@ -84,6 +87,36 @@ cannot be accessed, or if it cannot
|
|||||||
enough memory to hold the whole thing.
|
enough memory to hold the whole thing.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
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
|
.Fn readdir
|
||||||
function
|
function
|
||||||
returns a pointer to the next directory entry.
|
returns a pointer to the next directory entry.
|
||||||
@ -202,3 +235,7 @@ and
|
|||||||
.Fn dirfd
|
.Fn dirfd
|
||||||
functions appeared in
|
functions appeared in
|
||||||
.Bx 4.2 .
|
.Bx 4.2 .
|
||||||
|
The
|
||||||
|
.Fn fdopendir
|
||||||
|
function appeared in
|
||||||
|
.Fx 8.0 .
|
||||||
|
@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "un-namespace.h"
|
#include "un-namespace.h"
|
||||||
|
|
||||||
#include "telldir.h"
|
#include "telldir.h"
|
||||||
|
|
||||||
|
static DIR * __opendir_common(int, const char *, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open a directory.
|
* Open a directory.
|
||||||
*/
|
*/
|
||||||
@ -57,19 +60,25 @@ opendir(const char *name)
|
|||||||
return (__opendir2(name, DTF_HIDEW|DTF_NODUP));
|
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 *
|
DIR *
|
||||||
__opendir2(const char *name, int flags)
|
__opendir2(const char *name, int flags)
|
||||||
{
|
{
|
||||||
DIR *dirp;
|
|
||||||
int fd;
|
int fd;
|
||||||
int incr;
|
|
||||||
int saved_errno;
|
|
||||||
int unionstack;
|
|
||||||
struct stat statb;
|
struct stat statb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* stat() before _open() because opening of special files may be
|
* 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)
|
if (stat(name, &statb) != 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -79,7 +88,24 @@ __opendir2(const char *name, int flags)
|
|||||||
}
|
}
|
||||||
if ((fd = _open(name, O_RDONLY | O_NONBLOCK)) == -1)
|
if ((fd = _open(name, O_RDONLY | O_NONBLOCK)) == -1)
|
||||||
return (NULL);
|
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;
|
dirp = NULL;
|
||||||
|
/* _fstat() the open handler because the file may have changed. */
|
||||||
if (_fstat(fd, &statb) != 0)
|
if (_fstat(fd, &statb) != 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (!S_ISDIR(statb.st_mode)) {
|
if (!S_ISDIR(statb.st_mode)) {
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
* is created, otherwise 1.
|
* is created, otherwise 1.
|
||||||
*/
|
*/
|
||||||
#undef __FreeBSD_version
|
#undef __FreeBSD_version
|
||||||
#define __FreeBSD_version 800034 /* Master, propagated to newvers */
|
#define __FreeBSD_version 800035 /* Master, propagated to newvers */
|
||||||
|
|
||||||
#ifndef LOCORE
|
#ifndef LOCORE
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user