* Added fdopendir() (POSIX).
* Got rid of <dirent_private.h> -- 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
This commit is contained in:
+10
-10
@@ -32,16 +32,16 @@ typedef struct __DIR DIR;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DIR *opendir(const char *dirname);
|
DIR* fdopendir(int fd);
|
||||||
struct dirent *readdir(DIR *dir);
|
DIR* opendir(const char* dirName);
|
||||||
int readdir_r(DIR *dir, struct dirent *entry, struct dirent **_result);
|
struct dirent* readdir(DIR* dir);
|
||||||
int closedir(DIR *dir);
|
int readdir_r(DIR* dir, struct dirent* entry,
|
||||||
void rewinddir(DIR *dir);
|
struct dirent** _result);
|
||||||
void seekdir(DIR *dir, long int loc);
|
int closedir(DIR* dir);
|
||||||
long int telldir(DIR *);
|
void rewinddir(DIR* dir);
|
||||||
|
void seekdir(DIR* dir, long int position);
|
||||||
/* Non-POSIX extension to get the FD out of the private DIR */
|
long int telldir(DIR* dir);
|
||||||
int dirfd(const DIR *dir);
|
int dirfd(const DIR* dir);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2008, Axel Dörfler, [email protected].
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef DIRENT_PRIVATE_H
|
|
||||||
#define DIRENT_PRIVATE_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
|
|
||||||
#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 */
|
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <kmodule.h>
|
#include <kmodule.h>
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -19,8 +20,6 @@
|
|||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
#include <NodeMonitor.h>
|
#include <NodeMonitor.h>
|
||||||
|
|
||||||
#include <dirent_private.h>
|
|
||||||
|
|
||||||
#include <boot_device.h>
|
#include <boot_device.h>
|
||||||
#include <boot/elf.h>
|
#include <boot/elf.h>
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
@@ -1529,32 +1528,29 @@ ModuleNotificationService::_ScanDirectory(Stack<DIR*>& stack, DIR* dir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct stat stat;
|
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);
|
true);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (S_ISDIR(stat.st_mode)) {
|
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)
|
if (fd < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DIR* subDir = (DIR*)malloc(DIR_BUFFER_SIZE);
|
DIR* subDir = fdopendir(fd);
|
||||||
if (subDir == NULL) {
|
if (subDir == NULL) {
|
||||||
close(fd);
|
close(fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
subDir->fd = fd;
|
|
||||||
subDir->entries_left = 0;
|
|
||||||
|
|
||||||
stack.Push(subDir);
|
stack.Push(subDir);
|
||||||
|
|
||||||
if (_AddDirectoryNode(stat.st_dev, stat.st_ino) == B_OK
|
if (_AddDirectoryNode(stat.st_dev, stat.st_ino) == B_OK
|
||||||
&& directMatch)
|
&& directMatch)
|
||||||
directMatchAdded = true;
|
directMatchAdded = true;
|
||||||
} else if (S_ISREG(stat.st_mode)) {
|
} 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)
|
dirent->d_name) == B_OK && directMatch)
|
||||||
directMatchAdded = true;
|
directMatchAdded = true;
|
||||||
}
|
}
|
||||||
@@ -1564,7 +1560,7 @@ ModuleNotificationService::_ScanDirectory(Stack<DIR*>& stack, DIR* dir,
|
|||||||
// We need to monitor this directory to see if a matching file
|
// We need to monitor this directory to see if a matching file
|
||||||
// is added.
|
// is added.
|
||||||
struct stat stat;
|
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)
|
if (status == B_OK)
|
||||||
_AddDirectoryNode(stat.st_dev, stat.st_ino);
|
_AddDirectoryNode(stat.st_dev, stat.st_ino);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ SubDir HAIKU_TOP src system libroot os ;
|
|||||||
UsePrivateSystemHeaders ;
|
UsePrivateSystemHeaders ;
|
||||||
UsePrivateHeaders kernel ;
|
UsePrivateHeaders kernel ;
|
||||||
# for util/KMessage.h
|
# for util/KMessage.h
|
||||||
UsePrivateHeaders libroot runtime_loader ;
|
UsePrivateHeaders libroot runtime_loader shared ;
|
||||||
|
|
||||||
MergeObject os_main.o :
|
MergeObject os_main.o :
|
||||||
area.c
|
area.c
|
||||||
|
|||||||
@@ -6,26 +6,18 @@
|
|||||||
|
|
||||||
#include <fs_attr.h>
|
#include <fs_attr.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <syscall_utils.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "dirent_private.h"
|
#include <syscalls.h>
|
||||||
#include "syscalls.h"
|
#include <syscall_utils.h>
|
||||||
|
|
||||||
|
|
||||||
// TODO: think about adding special syscalls for the read/write/stat functions
|
// TODO: think about adding special syscalls for the read/write/stat functions
|
||||||
// to speed them up
|
// to speed them up
|
||||||
|
|
||||||
#define RETURN_AND_SET_ERRNO(status) \
|
|
||||||
{ \
|
|
||||||
if (status < 0) { \
|
|
||||||
errno = status; \
|
|
||||||
return -1; \
|
|
||||||
} \
|
|
||||||
return status; \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static DIR *
|
static DIR *
|
||||||
open_attr_dir(int file, const char *path)
|
open_attr_dir(int file, const char *path)
|
||||||
@@ -38,16 +30,12 @@ open_attr_dir(int file, const char *path)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate the memory for the DIR structure */
|
// allocate the DIR structure
|
||||||
if ((dir = (DIR *)malloc(DIR_BUFFER_SIZE)) == NULL) {
|
if ((dir = fdopendir(fd)) == NULL) {
|
||||||
errno = B_NO_MEMORY;
|
|
||||||
_kern_close(fd);
|
_kern_close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir->fd = fd;
|
|
||||||
dir->entries_left = 0;
|
|
||||||
|
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,11 +139,7 @@ fs_fopen_attr_dir(int fd)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
fs_close_attr_dir(DIR* dir)
|
fs_close_attr_dir(DIR* dir)
|
||||||
{
|
{
|
||||||
int status = _kern_close(dir->fd);
|
return closedir(dir);
|
||||||
|
|
||||||
free(dir);
|
|
||||||
|
|
||||||
RETURN_AND_SET_ERRNO(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,22 +6,13 @@
|
|||||||
|
|
||||||
#include <fs_index.h>
|
#include <fs_index.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <dirent_private.h>
|
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
|
#include <syscall_utils.h>
|
||||||
|
|
||||||
#define RETURN_AND_SET_ERRNO(status) \
|
|
||||||
{ \
|
|
||||||
if (status < 0) { \
|
|
||||||
errno = status; \
|
|
||||||
return -1; \
|
|
||||||
} \
|
|
||||||
return status; \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -72,16 +63,12 @@ fs_open_index_dir(dev_t device)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate the memory for the DIR structure */
|
// allocate the DIR structure
|
||||||
if ((dir = (DIR *)malloc(DIR_BUFFER_SIZE)) == NULL) {
|
if ((dir = fdopendir(fd)) == NULL) {
|
||||||
errno = B_NO_MEMORY;
|
|
||||||
_kern_close(fd);
|
_kern_close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir->fd = fd;
|
|
||||||
dir->entries_left = 0;
|
|
||||||
|
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,11 +76,7 @@ fs_open_index_dir(dev_t device)
|
|||||||
int
|
int
|
||||||
fs_close_index_dir(DIR *dir)
|
fs_close_index_dir(DIR *dir)
|
||||||
{
|
{
|
||||||
int status = _kern_close(dir->fd);
|
return closedir(dir);
|
||||||
|
|
||||||
free(dir);
|
|
||||||
|
|
||||||
RETURN_AND_SET_ERRNO(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
|
|
||||||
#include <fs_query.h>
|
#include <fs_query.h>
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <dirent_private.h>
|
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
|
#include <syscall_utils.h>
|
||||||
|
|
||||||
|
|
||||||
static DIR *
|
static DIR *
|
||||||
@@ -31,17 +32,13 @@ open_query_etc(dev_t device, const char *query,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate a DIR
|
// allocate the DIR structure
|
||||||
DIR *dir = (DIR *)malloc(DIR_BUFFER_SIZE);
|
DIR *dir = fdopendir(fd);
|
||||||
if (!dir) {
|
if (dir == NULL) {
|
||||||
_kern_close(fd);
|
_kern_close(fd);
|
||||||
errno = B_NO_MEMORY;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir->fd = fd;
|
|
||||||
dir->entries_left = 0;
|
|
||||||
|
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,14 +67,7 @@ fs_open_live_query(dev_t device, const char *query,
|
|||||||
int
|
int
|
||||||
fs_close_query(DIR *dir)
|
fs_close_query(DIR *dir)
|
||||||
{
|
{
|
||||||
if (dir == NULL) {
|
return closedir(dir);
|
||||||
errno = B_BAD_VALUE;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd = dir->fd;
|
|
||||||
free(dir);
|
|
||||||
return _kern_close(fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,28 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.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>
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
static int
|
||||||
do_seek_dir(DIR* dir)
|
do_seek_dir(DIR* dir)
|
||||||
{
|
{
|
||||||
@@ -62,8 +75,8 @@ do_seek_dir(DIR* dir)
|
|||||||
dir->current_position += dir->entries_left;
|
dir->current_position += dir->entries_left;
|
||||||
dir->entries_left = 0;
|
dir->entries_left = 0;
|
||||||
|
|
||||||
count = _kern_read_dir(dir->fd, &dir->first_entry, DIRENT_BUFFER_SIZE,
|
count = _kern_read_dir(dir->fd, &dir->first_entry,
|
||||||
USHRT_MAX);
|
(char*)dir + DIR_BUFFER_SIZE - (char*)&dir->first_entry, USHRT_MAX);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
errno = count;
|
errno = count;
|
||||||
@@ -83,21 +96,14 @@ do_seek_dir(DIR* dir)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
DIR *
|
DIR*
|
||||||
opendir(const char *path)
|
fdopendir(int fd)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR* dir;
|
||||||
|
|
||||||
int fd = _kern_open_dir(-1, path);
|
|
||||||
if (fd < 0) {
|
|
||||||
errno = fd;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate the memory for the DIR structure */
|
/* 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;
|
errno = B_NO_MEMORY;
|
||||||
_kern_close(fd);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,10 +116,38 @@ opendir(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
DIR*
|
||||||
closedir(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);
|
free(dir);
|
||||||
|
|
||||||
@@ -121,8 +155,8 @@ closedir(DIR *dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dirent *
|
struct dirent*
|
||||||
readdir(DIR *dir)
|
readdir(DIR* dir)
|
||||||
{
|
{
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
|
|
||||||
@@ -145,8 +179,8 @@ readdir(DIR *dir)
|
|||||||
|
|
||||||
// we need to retrieve new entries
|
// we need to retrieve new entries
|
||||||
|
|
||||||
count = _kern_read_dir(dir->fd, &dir->first_entry, DIRENT_BUFFER_SIZE,
|
count = _kern_read_dir(dir->fd, &dir->first_entry,
|
||||||
USHRT_MAX);
|
(char*)dir + DIR_BUFFER_SIZE - (char*)&dir->first_entry, USHRT_MAX);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
errno = count;
|
errno = count;
|
||||||
@@ -165,7 +199,7 @@ readdir(DIR *dir)
|
|||||||
|
|
||||||
|
|
||||||
int
|
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)
|
ssize_t count = _kern_read_dir(dir->fd, entry, sizeof(struct dirent)
|
||||||
+ B_FILE_NAME_LENGTH, 1);
|
+ B_FILE_NAME_LENGTH, 1);
|
||||||
@@ -183,7 +217,7 @@ readdir_r(DIR *dir, struct dirent *entry, struct dirent **_result)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
rewinddir(DIR *dir)
|
rewinddir(DIR* dir)
|
||||||
{
|
{
|
||||||
dir->seek_position = 0;
|
dir->seek_position = 0;
|
||||||
}
|
}
|
||||||
@@ -204,7 +238,7 @@ telldir(DIR* dir)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
dirfd(const DIR *dir)
|
dirfd(const DIR* dir)
|
||||||
{
|
{
|
||||||
return dir->fd;
|
return dir->fd;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user