* 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:
Ingo Weinhold 2009-08-29 20:25:24 +00:00
parent 781aa0f579
commit adbf8b25f8
8 changed files with 98 additions and 135 deletions

View File

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

View File

@ -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 <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 */

View File

@ -11,6 +11,7 @@
#include <kmodule.h>
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@ -19,8 +20,6 @@
#include <FindDirectory.h>
#include <NodeMonitor.h>
#include <dirent_private.h>
#include <boot_device.h>
#include <boot/elf.h>
#include <elf.h>
@ -1529,32 +1528,29 @@ ModuleNotificationService::_ScanDirectory(Stack<DIR*>& 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<DIR*>& 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);
}

View File

@ -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

View File

@ -6,26 +6,18 @@
#include <fs_attr.h>
#include <stdlib.h>
#include <fcntl.h>
#include <syscall_utils.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
// 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);
}

View File

@ -6,22 +6,13 @@
#include <fs_index.h>
#include <stdlib.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <dirent_private.h>
#include <syscalls.h>
#define RETURN_AND_SET_ERRNO(status) \
{ \
if (status < 0) { \
errno = status; \
return -1; \
} \
return status; \
}
#include <syscall_utils.h>
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);
}

View File

@ -6,13 +6,14 @@
#include <fs_query.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent_private.h>
#include <syscalls.h>
#include <syscall_utils.h>
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);
}

View File

@ -6,15 +6,28 @@
#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <dirent_private.h>
#include <syscalls.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
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;
}