diff --git a/headers/private/libroot/dirent_private.h b/headers/private/libroot/dirent_private.h new file mode 100644 index 0000000000..b86d24034f --- /dev/null +++ b/headers/private/libroot/dirent_private.h @@ -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 + +#include + + +__BEGIN_DECLS + +DIR* __create_dir_struct(int fd); + + +__END_DECLS + + +#endif // _LIBROOT_DIRENT_PRIVATE_H diff --git a/src/system/libroot/os/fs_attr.cpp b/src/system/libroot/os/fs_attr.cpp index 22413ee389..93a360cabd 100644 --- a/src/system/libroot/os/fs_attr.cpp +++ b/src/system/libroot/os/fs_attr.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -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; } diff --git a/src/system/libroot/os/fs_index.c b/src/system/libroot/os/fs_index.c index 872f8ac372..2fe30cccc3 100644 --- a/src/system/libroot/os/fs_index.c +++ b/src/system/libroot/os/fs_index.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -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; } diff --git a/src/system/libroot/os/fs_query.cpp b/src/system/libroot/os/fs_query.cpp index c9e5daa597..781ae67e98 100644 --- a/src/system/libroot/os/fs_query.cpp +++ b/src/system/libroot/os/fs_query.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -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; diff --git a/src/system/libroot/posix/dirent.c b/src/system/libroot/posix/dirent.c index 5db1f26275..4e05af6768 100644 --- a/src/system/libroot/posix/dirent.c +++ b/src/system/libroot/posix/dirent.c @@ -6,6 +6,7 @@ #include +#include #include #include @@ -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; }