diff options
author | ru <ru@FreeBSD.org> | 2012-03-02 10:03:38 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2012-03-02 10:03:38 +0000 |
commit | 50f29d6e48bfdf86bb45e982b75cf4bce1c9681c (patch) | |
tree | 784bc7582b6729e0faebeb3b191a7f68ef819b0a /lib/libc/gen | |
parent | f90febf94750a1e4d57d01ee20c7d2fc12725531 (diff) | |
download | FreeBSD-src-50f29d6e48bfdf86bb45e982b75cf4bce1c9681c.zip FreeBSD-src-50f29d6e48bfdf86bb45e982b75cf4bce1c9681c.tar.gz |
Finally removed the stat() and fstat() calls from the opendir() code.
They were made excessive in r205424 by opening with O_DIRECTORY.
Also eliminated the fcntl() call used to set FD_CLOEXEC by opening
with O_CLOEXEC.
(fdopendir() still checks that the passed descriptor is a directory,
and sets FD_CLOEXEC on it.)
Reviewed by: ed
Diffstat (limited to 'lib/libc/gen')
-rw-r--r-- | lib/libc/gen/opendir.c | 38 |
1 files changed, 14 insertions, 24 deletions
diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c index 407c047..3beead7 100644 --- a/lib/libc/gen/opendir.c +++ b/lib/libc/gen/opendir.c @@ -66,7 +66,17 @@ opendir(const char *name) DIR * fdopendir(int fd) { + struct stat statb; + /* Check that fd is associated with a directory. */ + if (_fstat(fd, &statb) != 0) + return (NULL); + if (!S_ISDIR(statb.st_mode)) { + errno = ENOTDIR; + return (NULL); + } + if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + return (NULL); return (__opendir_common(fd, NULL, DTF_HIDEW|DTF_NODUP)); } @@ -74,21 +84,11 @@ DIR * __opendir2(const char *name, int flags) { int fd; - struct stat statb; DIR *dir; int saved_errno; - /* - * stat() before _open() because opening of special files may be - * harmful. - */ - if (stat(name, &statb) != 0) - return (NULL); - if (!S_ISDIR(statb.st_mode)) { - errno = ENOTDIR; - return (NULL); - } - if ((fd = _open(name, O_RDONLY | O_NONBLOCK | O_DIRECTORY)) == -1) + if ((fd = _open(name, + O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC)) == -1) return (NULL); dir = __opendir_common(fd, name, flags); @@ -119,19 +119,9 @@ __opendir_common(int fd, const char *name, int flags) int saved_errno; int unionstack; int fd2; - 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)) { - errno = ENOTDIR; - goto fail; - } - if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 || - (dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL) - goto fail; + if ((dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL) + return (NULL); dirp->dd_td = (struct _telldir *)((char *)dirp + sizeof(DIR)); LIST_INIT(&dirp->dd_td->td_locq); |