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; }