*_read_dir() now also returns "." and ".." Entries.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8920 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2004-09-12 00:00:29 +00:00
parent c654468395
commit 119e5eeef8
2 changed files with 89 additions and 10 deletions
+44 -5
View File
@@ -97,6 +97,7 @@ struct devfs_cookie {
struct devfs_cookie *next;
struct devfs_cookie *prev;
struct devfs_vnode *ptr;
int state; // iteration state
} dir;
struct cookie_dev {
void *dcookie;
@@ -104,6 +105,14 @@ struct devfs_cookie {
} u;
};
// directory iteration states
enum {
ITERATION_STATE_DOT = 0,
ITERATION_STATE_DOT_DOT = 1,
ITERATION_STATE_OTHERS = 2,
ITERATION_STATE_BEGIN = ITERATION_STATE_DOT,
};
/* the one and only allowed devfs instance */
static struct devfs *sDeviceFileSystem = NULL;
@@ -961,6 +970,7 @@ devfs_open_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie *_cookie)
mutex_lock(&fs->lock);
cookie->u.dir.ptr = vnode->stream.u.dir.dir_head;
cookie->u.dir.state = ITERATION_STATE_BEGIN;
*_cookie = cookie;
mutex_unlock(&fs->lock);
@@ -975,6 +985,10 @@ devfs_read_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, struct dirent
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
struct devfs *fs = (struct devfs *)_fs;
status_t status = B_OK;
struct devfs_vnode *childNode = NULL;
const char *name = NULL;
struct devfs_vnode *nextChildNode = NULL;
int nextState = cookie->u.dir.state;
TRACE(("devfs_read_dir: vnode %p, cookie %p, buffer %p, size %ld\n", _vnode, cookie, dirent, bufferSize));
@@ -983,25 +997,49 @@ devfs_read_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, struct dirent
mutex_lock(&fs->lock);
if (cookie->u.dir.ptr == NULL) {
switch (cookie->u.dir.state) {
case ITERATION_STATE_DOT:
childNode = vnode;
name = ".";
nextChildNode = vnode->stream.u.dir.dir_head;
nextState = cookie->u.dir.state + 1;
break;
case ITERATION_STATE_DOT_DOT:
childNode = vnode->parent;
name = "..";
nextChildNode = vnode->stream.u.dir.dir_head;
nextState = cookie->u.dir.state + 1;
break;
default:
childNode = cookie->u.dir.ptr;
if (childNode) {
name = childNode->name;
nextChildNode = childNode->dir_next;
}
break;
}
if (!childNode) {
*_num = 0;
goto err;
}
dirent->d_dev = fs->id;
dirent->d_ino = cookie->u.dir.ptr->id;
dirent->d_reclen = strlen(cookie->u.dir.ptr->name) + sizeof(struct dirent);
dirent->d_ino = childNode->id;
dirent->d_reclen = strlen(name) + sizeof(struct dirent);
if (dirent->d_reclen > bufferSize) {
status = ENOBUFS;
goto err;
}
status = user_strlcpy(dirent->d_name, cookie->u.dir.ptr->name, bufferSize - sizeof(struct dirent));
status = user_strlcpy(dirent->d_name, name,
bufferSize - sizeof(struct dirent));
if (status < B_OK)
goto err;
cookie->u.dir.ptr = cookie->u.dir.ptr->dir_next;
cookie->u.dir.ptr = nextChildNode;
cookie->u.dir.state = nextState;
status = B_OK;
err:
@@ -1026,6 +1064,7 @@ devfs_rewind_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
mutex_lock(&fs->lock);
cookie->u.dir.ptr = vnode->stream.u.dir.dir_head;
cookie->u.dir.state = ITERATION_STATE_BEGIN;
mutex_unlock(&fs->lock);
return B_OK;
+45 -5
View File
@@ -68,6 +68,15 @@ struct rootfs_cookie {
struct rootfs_cookie *prev;
struct rootfs_vnode *ptr;
int oflags;
int state; // iteration state
};
// directory iteration states
enum {
ITERATION_STATE_DOT = 0,
ITERATION_STATE_DOT_DOT = 1,
ITERATION_STATE_OTHERS = 2,
ITERATION_STATE_BEGIN = ITERATION_STATE_DOT,
};
#define ROOTFS_HASH_SIZE 16
@@ -623,6 +632,7 @@ rootfs_open_dir(fs_volume _fs, fs_vnode _v, fs_cookie *_cookie)
cookie->ptr = vnode->stream.dir.dir_head;
//cookie->oflags = oflags;
cookie->state = ITERATION_STATE_BEGIN;
insert_cookie_in_jar(vnode, cookie);
*_cookie = cookie;
@@ -636,34 +646,63 @@ rootfs_open_dir(fs_volume _fs, fs_vnode _v, fs_cookie *_cookie)
static status_t
rootfs_read_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, struct dirent *dirent, size_t bufferSize, uint32 *_num)
{
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode;
struct rootfs_cookie *cookie = _cookie;
struct rootfs *fs = _fs;
status_t status = B_OK;
struct rootfs_vnode *childNode = NULL;
const char *name = NULL;
struct rootfs_vnode *nextChildNode = NULL;
int nextState = cookie->state;
TRACE(("rootfs_read_dir: vnode %p, cookie %p, buffer = %p, bufferSize = %ld, num = %p\n", _vnode, cookie, dirent, bufferSize,_num));
mutex_lock(&fs->lock);
if (cookie->ptr == NULL) {
switch (cookie->state) {
case ITERATION_STATE_DOT:
childNode = vnode;
name = ".";
nextChildNode = vnode->stream.dir.dir_head;
nextState = cookie->state + 1;
break;
case ITERATION_STATE_DOT_DOT:
childNode = vnode->parent;
name = "..";
nextChildNode = vnode->stream.dir.dir_head;
nextState = cookie->state + 1;
break;
default:
childNode = cookie->ptr;
if (childNode) {
name = childNode->name;
nextChildNode = childNode->dir_next;
}
break;
}
if (!childNode) {
// we're at the end of the directory
*_num = 0;
goto err;
}
dirent->d_dev = fs->id;
dirent->d_ino = cookie->ptr->id;
dirent->d_reclen = strlen(cookie->ptr->name) + sizeof(struct dirent);
dirent->d_ino = childNode->id;
dirent->d_reclen = strlen(name) + sizeof(struct dirent);
if (dirent->d_reclen > bufferSize) {
status = ENOBUFS;
goto err;
}
status = user_strlcpy(dirent->d_name, cookie->ptr->name, bufferSize - sizeof(struct dirent));
status = user_strlcpy(dirent->d_name, name,
bufferSize - sizeof(struct dirent));
if (status < B_OK)
goto err;
cookie->ptr = cookie->ptr->dir_next;
cookie->ptr = nextChildNode;
cookie->state = nextState;
status = B_OK;
err:
@@ -683,6 +722,7 @@ rootfs_rewind_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
mutex_lock(&fs->lock);
cookie->ptr = vnode->stream.dir.dir_head;
cookie->state = ITERATION_STATE_BEGIN;
mutex_unlock(&fs->lock);
return B_OK;