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
This commit is contained in:
parent
f90febf947
commit
50f29d6e48
@ -66,7 +66,17 @@ opendir(const char *name)
|
|||||||
DIR *
|
DIR *
|
||||||
fdopendir(int fd)
|
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));
|
return (__opendir_common(fd, NULL, DTF_HIDEW|DTF_NODUP));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,21 +84,11 @@ DIR *
|
|||||||
__opendir2(const char *name, int flags)
|
__opendir2(const char *name, int flags)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct stat statb;
|
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
|
|
||||||
/*
|
if ((fd = _open(name,
|
||||||
* stat() before _open() because opening of special files may be
|
O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC)) == -1)
|
||||||
* 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)
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
dir = __opendir_common(fd, name, flags);
|
dir = __opendir_common(fd, name, flags);
|
||||||
@ -119,19 +119,9 @@ __opendir_common(int fd, const char *name, int flags)
|
|||||||
int saved_errno;
|
int saved_errno;
|
||||||
int unionstack;
|
int unionstack;
|
||||||
int fd2;
|
int fd2;
|
||||||
struct stat statb;
|
|
||||||
|
|
||||||
dirp = NULL;
|
if ((dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL)
|
||||||
/* _fstat() the open handler because the file may have changed. */
|
return (NULL);
|
||||||
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;
|
|
||||||
|
|
||||||
dirp->dd_td = (struct _telldir *)((char *)dirp + sizeof(DIR));
|
dirp->dd_td = (struct _telldir *)((char *)dirp + sizeof(DIR));
|
||||||
LIST_INIT(&dirp->dd_td->td_locq);
|
LIST_INIT(&dirp->dd_td->td_locq);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user