* Fixed fdopendir(): We have to explicitly (re-)open the directory, because FDs
returned by open() aren't suitable for directory iteration and because checks have to be performed (like whether this is a directory at all and whether the user has read permission). * Added __create_dir_struct() for the attribute, index, and query open functions to use instead. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33974 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _LIBROOT_DIRENT_PRIVATE_H
|
||||||
|
#define _LIBROOT_DIRENT_PRIVATE_H
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
DIR* __create_dir_struct(int fd);
|
||||||
|
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _LIBROOT_DIRENT_PRIVATE_H
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <dirent_private.h>
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
#include <syscall_utils.h>
|
#include <syscall_utils.h>
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ open_attr_dir(int file, const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocate the DIR structure
|
// allocate the DIR structure
|
||||||
if ((dir = fdopendir(fd)) == NULL) {
|
if ((dir = __create_dir_struct(fd)) == NULL) {
|
||||||
_kern_close(fd);
|
_kern_close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <dirent_private.h>
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
#include <syscall_utils.h>
|
#include <syscall_utils.h>
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ fs_open_index_dir(dev_t device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocate the DIR structure
|
// allocate the DIR structure
|
||||||
if ((dir = fdopendir(fd)) == NULL) {
|
if ((dir = __create_dir_struct(fd)) == NULL) {
|
||||||
_kern_close(fd);
|
_kern_close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <dirent_private.h>
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
#include <syscall_utils.h>
|
#include <syscall_utils.h>
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ open_query_etc(dev_t device, const char *query,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocate the DIR structure
|
// allocate the DIR structure
|
||||||
DIR *dir = fdopendir(fd);
|
DIR *dir = __create_dir_struct(fd);
|
||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
_kern_close(fd);
|
_kern_close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <dirent_private.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@@ -93,11 +94,11 @@ do_seek_dir(DIR* dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark - private API
|
||||||
|
|
||||||
|
|
||||||
DIR*
|
DIR*
|
||||||
fdopendir(int fd)
|
__create_dir_struct(int fd)
|
||||||
{
|
{
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
|
|
||||||
@@ -116,6 +117,39 @@ fdopendir(int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - public API
|
||||||
|
|
||||||
|
|
||||||
|
DIR*
|
||||||
|
fdopendir(int fd)
|
||||||
|
{
|
||||||
|
DIR* dir;
|
||||||
|
|
||||||
|
// Since our standard file descriptors can't be used as directory file
|
||||||
|
// descriptors, we have to open a fresh one explicitly.
|
||||||
|
int dirFD = _kern_open_dir(fd, NULL);
|
||||||
|
if (dirFD < 0) {
|
||||||
|
errno = dirFD;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dir = __create_dir_struct(dirFD);
|
||||||
|
if (dir == NULL) {
|
||||||
|
close(dirFD);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// According to the spec, "the file descriptor is under the control of the
|
||||||
|
// system" now. It's not quite clear whether we're allowed to close it now,
|
||||||
|
// though. We could dup2() the new FD over the old one and close the new
|
||||||
|
// one, if it turns out to be a problem.
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DIR*
|
DIR*
|
||||||
opendir(const char* path)
|
opendir(const char* path)
|
||||||
{
|
{
|
||||||
@@ -128,7 +162,7 @@ opendir(const char* path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocate the DIR structure
|
// allocate the DIR structure
|
||||||
if ((dir = fdopendir(fd)) == NULL) {
|
if ((dir = __create_dir_struct(fd)) == NULL) {
|
||||||
_kern_close(fd);
|
_kern_close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user