From adbf8b25f8b29263fcb344ac86beceb9e83ce594 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 29 Aug 2009 20:25:24 +0000 Subject: [PATCH] * Added fdopendir() (POSIX). * Got rid of -- the __DIR structure is private to dirent.c, now. The attribute directory, index directory, and query functions use the the public POSIX API, so does the kernel module code. Those components were not initializing the structure correctly anymore since the introduction of telldir()/seekdir(). +alphabranch git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32819 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/posix/dirent.h | 20 +++--- headers/private/libroot/dirent_private.h | 24 ------- src/system/kernel/module.cpp | 16 ++--- src/system/libroot/os/Jamfile | 2 +- src/system/libroot/os/fs_attr.cpp | 32 +++------ src/system/libroot/os/fs_index.c | 31 ++------- src/system/libroot/os/fs_query.cpp | 26 +++----- src/system/libroot/posix/dirent.c | 82 +++++++++++++++++------- 8 files changed, 98 insertions(+), 135 deletions(-) delete mode 100644 headers/private/libroot/dirent_private.h diff --git a/headers/posix/dirent.h b/headers/posix/dirent.h index 354aa1c334..25bc7b4352 100644 --- a/headers/posix/dirent.h +++ b/headers/posix/dirent.h @@ -32,16 +32,16 @@ typedef struct __DIR DIR; extern "C" { #endif -DIR *opendir(const char *dirname); -struct dirent *readdir(DIR *dir); -int readdir_r(DIR *dir, struct dirent *entry, struct dirent **_result); -int closedir(DIR *dir); -void rewinddir(DIR *dir); -void seekdir(DIR *dir, long int loc); -long int telldir(DIR *); - -/* Non-POSIX extension to get the FD out of the private DIR */ -int dirfd(const DIR *dir); +DIR* fdopendir(int fd); +DIR* opendir(const char* dirName); +struct dirent* readdir(DIR* dir); +int readdir_r(DIR* dir, struct dirent* entry, + struct dirent** _result); +int closedir(DIR* dir); +void rewinddir(DIR* dir); +void seekdir(DIR* dir, long int position); +long int telldir(DIR* dir); +int dirfd(const DIR* dir); #ifdef __cplusplus } diff --git a/headers/private/libroot/dirent_private.h b/headers/private/libroot/dirent_private.h deleted file mode 100644 index 23b51c68b9..0000000000 --- a/headers/private/libroot/dirent_private.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. - * Distributed under the terms of the MIT License. - */ -#ifndef DIRENT_PRIVATE_H -#define DIRENT_PRIVATE_H - - -#include - - -#define DIR_BUFFER_SIZE 4096 -#define DIRENT_BUFFER_SIZE (DIR_BUFFER_SIZE - offsetof(struct __DIR, first_entry)) - -struct __DIR { - int fd; - short next_entry; - unsigned short entries_left; - long seek_position; - long current_position; - struct dirent first_entry; -}; - -#endif /* DIRENT_PRIVATE_H */ diff --git a/src/system/kernel/module.cpp b/src/system/kernel/module.cpp index 8b321b7b6c..8449bd054e 100644 --- a/src/system/kernel/module.cpp +++ b/src/system/kernel/module.cpp @@ -11,6 +11,7 @@ #include +#include #include #include #include @@ -19,8 +20,6 @@ #include #include -#include - #include #include #include @@ -1529,32 +1528,29 @@ ModuleNotificationService::_ScanDirectory(Stack& stack, DIR* dir, } struct stat stat; - status_t status = vfs_read_stat(dir->fd, dirent->d_name, true, &stat, + status_t status = vfs_read_stat(dirfd(dir), dirent->d_name, true, &stat, true); if (status != B_OK) continue; if (S_ISDIR(stat.st_mode)) { - int fd = _kern_open_dir(dir->fd, dirent->d_name); + int fd = _kern_open_dir(dirfd(dir), dirent->d_name); if (fd < 0) continue; - DIR* subDir = (DIR*)malloc(DIR_BUFFER_SIZE); + DIR* subDir = fdopendir(fd); if (subDir == NULL) { close(fd); continue; } - subDir->fd = fd; - subDir->entries_left = 0; - stack.Push(subDir); if (_AddDirectoryNode(stat.st_dev, stat.st_ino) == B_OK && directMatch) directMatchAdded = true; } else if (S_ISREG(stat.st_mode)) { - if (_AddModuleNode(stat.st_dev, stat.st_ino, dir->fd, + if (_AddModuleNode(stat.st_dev, stat.st_ino, dirfd(dir), dirent->d_name) == B_OK && directMatch) directMatchAdded = true; } @@ -1564,7 +1560,7 @@ ModuleNotificationService::_ScanDirectory(Stack& stack, DIR* dir, // We need to monitor this directory to see if a matching file // is added. struct stat stat; - status_t status = vfs_read_stat(dir->fd, NULL, true, &stat, true); + status_t status = vfs_read_stat(dirfd(dir), NULL, true, &stat, true); if (status == B_OK) _AddDirectoryNode(stat.st_dev, stat.st_ino); } diff --git a/src/system/libroot/os/Jamfile b/src/system/libroot/os/Jamfile index 2ee67345c9..cc21069cc4 100644 --- a/src/system/libroot/os/Jamfile +++ b/src/system/libroot/os/Jamfile @@ -3,7 +3,7 @@ SubDir HAIKU_TOP src system libroot os ; UsePrivateSystemHeaders ; UsePrivateHeaders kernel ; # for util/KMessage.h -UsePrivateHeaders libroot runtime_loader ; +UsePrivateHeaders libroot runtime_loader shared ; MergeObject os_main.o : area.c diff --git a/src/system/libroot/os/fs_attr.cpp b/src/system/libroot/os/fs_attr.cpp index 65a071cb6b..22413ee389 100644 --- a/src/system/libroot/os/fs_attr.cpp +++ b/src/system/libroot/os/fs_attr.cpp @@ -6,26 +6,18 @@ #include -#include -#include +#include #include +#include +#include -#include "dirent_private.h" -#include "syscalls.h" +#include +#include // TODO: think about adding special syscalls for the read/write/stat functions // to speed them up -#define RETURN_AND_SET_ERRNO(status) \ - { \ - if (status < 0) { \ - errno = status; \ - return -1; \ - } \ - return status; \ - } - static DIR * open_attr_dir(int file, const char *path) @@ -38,16 +30,12 @@ open_attr_dir(int file, const char *path) return NULL; } - /* allocate the memory for the DIR structure */ - if ((dir = (DIR *)malloc(DIR_BUFFER_SIZE)) == NULL) { - errno = B_NO_MEMORY; + // allocate the DIR structure + if ((dir = fdopendir(fd)) == NULL) { _kern_close(fd); return NULL; } - dir->fd = fd; - dir->entries_left = 0; - return dir; } @@ -151,11 +139,7 @@ fs_fopen_attr_dir(int fd) extern "C" int fs_close_attr_dir(DIR* dir) { - int status = _kern_close(dir->fd); - - free(dir); - - RETURN_AND_SET_ERRNO(status); + return closedir(dir); } diff --git a/src/system/libroot/os/fs_index.c b/src/system/libroot/os/fs_index.c index c352cd0c8a..872f8ac372 100644 --- a/src/system/libroot/os/fs_index.c +++ b/src/system/libroot/os/fs_index.c @@ -6,22 +6,13 @@ #include -#include -#include +#include #include +#include +#include -#include #include - - -#define RETURN_AND_SET_ERRNO(status) \ - { \ - if (status < 0) { \ - errno = status; \ - return -1; \ - } \ - return status; \ - } +#include int @@ -72,16 +63,12 @@ fs_open_index_dir(dev_t device) return NULL; } - /* allocate the memory for the DIR structure */ - if ((dir = (DIR *)malloc(DIR_BUFFER_SIZE)) == NULL) { - errno = B_NO_MEMORY; + // allocate the DIR structure + if ((dir = fdopendir(fd)) == NULL) { _kern_close(fd); return NULL; } - dir->fd = fd; - dir->entries_left = 0; - return dir; } @@ -89,11 +76,7 @@ fs_open_index_dir(dev_t device) int fs_close_index_dir(DIR *dir) { - int status = _kern_close(dir->fd); - - free(dir); - - RETURN_AND_SET_ERRNO(status); + return closedir(dir); } diff --git a/src/system/libroot/os/fs_query.cpp b/src/system/libroot/os/fs_query.cpp index b74f116a51..c9e5daa597 100644 --- a/src/system/libroot/os/fs_query.cpp +++ b/src/system/libroot/os/fs_query.cpp @@ -6,13 +6,14 @@ #include +#include +#include +#include #include #include -#include -#include -#include #include +#include static DIR * @@ -31,17 +32,13 @@ open_query_etc(dev_t device, const char *query, return NULL; } - // allocate a DIR - DIR *dir = (DIR *)malloc(DIR_BUFFER_SIZE); - if (!dir) { + // allocate the DIR structure + DIR *dir = fdopendir(fd); + if (dir == NULL) { _kern_close(fd); - errno = B_NO_MEMORY; return NULL; } - dir->fd = fd; - dir->entries_left = 0; - return dir; } @@ -70,14 +67,7 @@ fs_open_live_query(dev_t device, const char *query, int fs_close_query(DIR *dir) { - if (dir == NULL) { - errno = B_BAD_VALUE; - return -1; - } - - int fd = dir->fd; - free(dir); - return _kern_close(fd); + return closedir(dir); } diff --git a/src/system/libroot/posix/dirent.c b/src/system/libroot/posix/dirent.c index cee73ff75a..5db1f26275 100644 --- a/src/system/libroot/posix/dirent.c +++ b/src/system/libroot/posix/dirent.c @@ -6,15 +6,28 @@ #include + #include #include #include -#include #include #include +#define DIR_BUFFER_SIZE 4096 + + +struct __DIR { + int fd; + short next_entry; + unsigned short entries_left; + long seek_position; + long current_position; + struct dirent first_entry; +}; + + static int do_seek_dir(DIR* dir) { @@ -62,8 +75,8 @@ do_seek_dir(DIR* dir) dir->current_position += dir->entries_left; dir->entries_left = 0; - count = _kern_read_dir(dir->fd, &dir->first_entry, DIRENT_BUFFER_SIZE, - USHRT_MAX); + count = _kern_read_dir(dir->fd, &dir->first_entry, + (char*)dir + DIR_BUFFER_SIZE - (char*)&dir->first_entry, USHRT_MAX); if (count <= 0) { if (count < 0) errno = count; @@ -83,21 +96,14 @@ do_seek_dir(DIR* dir) // #pragma mark - -DIR * -opendir(const char *path) +DIR* +fdopendir(int fd) { - DIR *dir; - - int fd = _kern_open_dir(-1, path); - if (fd < 0) { - errno = fd; - return NULL; - } + DIR* dir; /* allocate the memory for the DIR structure */ - if ((dir = (DIR *)malloc(DIR_BUFFER_SIZE)) == NULL) { + if ((dir = (DIR*)malloc(DIR_BUFFER_SIZE)) == NULL) { errno = B_NO_MEMORY; - _kern_close(fd); return NULL; } @@ -110,10 +116,38 @@ opendir(const char *path) } -int -closedir(DIR *dir) +DIR* +opendir(const char* path) { - int status = _kern_close(dir->fd); + DIR* dir; + + int fd = _kern_open_dir(-1, path); + if (fd < 0) { + errno = fd; + return NULL; + } + + // allocate the DIR structure + if ((dir = fdopendir(fd)) == NULL) { + _kern_close(fd); + return NULL; + } + + return dir; +} + + +int +closedir(DIR* dir) +{ + int status; + + if (dir == NULL) { + errno = B_BAD_VALUE; + return -1; + } + + status = _kern_close(dir->fd); free(dir); @@ -121,8 +155,8 @@ closedir(DIR *dir) } -struct dirent * -readdir(DIR *dir) +struct dirent* +readdir(DIR* dir) { ssize_t count; @@ -145,8 +179,8 @@ readdir(DIR *dir) // we need to retrieve new entries - count = _kern_read_dir(dir->fd, &dir->first_entry, DIRENT_BUFFER_SIZE, - USHRT_MAX); + count = _kern_read_dir(dir->fd, &dir->first_entry, + (char*)dir + DIR_BUFFER_SIZE - (char*)&dir->first_entry, USHRT_MAX); if (count <= 0) { if (count < 0) errno = count; @@ -165,7 +199,7 @@ readdir(DIR *dir) int -readdir_r(DIR *dir, struct dirent *entry, struct dirent **_result) +readdir_r(DIR* dir, struct dirent* entry, struct dirent** _result) { ssize_t count = _kern_read_dir(dir->fd, entry, sizeof(struct dirent) + B_FILE_NAME_LENGTH, 1); @@ -183,7 +217,7 @@ readdir_r(DIR *dir, struct dirent *entry, struct dirent **_result) void -rewinddir(DIR *dir) +rewinddir(DIR* dir) { dir->seek_position = 0; } @@ -204,7 +238,7 @@ telldir(DIR* dir) int -dirfd(const DIR *dir) +dirfd(const DIR* dir) { return dir->fd; }