* 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:
Ingo Weinhold 2009-11-10 10:55:43 +00:00
parent c3dbe62619
commit 9e81ddee87
5 changed files with 64 additions and 6 deletions

View File

@ -0,0 +1,21 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* 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

View File

@ -11,6 +11,7 @@
#include <fcntl.h>
#include <stdlib.h>
#include <dirent_private.h>
#include <syscalls.h>
#include <syscall_utils.h>
@ -31,7 +32,7 @@ open_attr_dir(int file, const char *path)
}
// allocate the DIR structure
if ((dir = fdopendir(fd)) == NULL) {
if ((dir = __create_dir_struct(fd)) == NULL) {
_kern_close(fd);
return NULL;
}

View File

@ -11,6 +11,7 @@
#include <fcntl.h>
#include <stdlib.h>
#include <dirent_private.h>
#include <syscalls.h>
#include <syscall_utils.h>
@ -64,7 +65,7 @@ fs_open_index_dir(dev_t device)
}
// allocate the DIR structure
if ((dir = fdopendir(fd)) == NULL) {
if ((dir = __create_dir_struct(fd)) == NULL) {
_kern_close(fd);
return NULL;
}

View File

@ -12,6 +12,7 @@
#include <stdlib.h>
#include <string.h>
#include <dirent_private.h>
#include <syscalls.h>
#include <syscall_utils.h>
@ -33,7 +34,7 @@ open_query_etc(dev_t device, const char *query,
}
// allocate the DIR structure
DIR *dir = fdopendir(fd);
DIR *dir = __create_dir_struct(fd);
if (dir == NULL) {
_kern_close(fd);
return NULL;

View File

@ -6,6 +6,7 @@
#include <dirent.h>
#include <dirent_private.h>
#include <errno.h>
#include <limits.h>
@ -93,11 +94,11 @@ do_seek_dir(DIR* dir)
}
// #pragma mark -
// #pragma mark - private API
DIR*
fdopendir(int fd)
__create_dir_struct(int fd)
{
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*
opendir(const char* path)
{
@ -128,7 +162,7 @@ opendir(const char* path)
}
// allocate the DIR structure
if ((dir = fdopendir(fd)) == NULL) {
if ((dir = __create_dir_struct(fd)) == NULL) {
_kern_close(fd);
return NULL;
}