lib: xpc: implement support for iterating through directories
This commit is contained in:
@@ -92,6 +92,7 @@ struct fs_context *fs_context_create(struct fs_allocator *alloc)
|
||||
ctx->ctx_vtable.write = fs_msg_write;
|
||||
ctx->ctx_vtable.seek = fs_msg_seek;
|
||||
ctx->ctx_vtable.map = fs_msg_map;
|
||||
ctx->ctx_vtable.getdents = fs_msg_getdents;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -52,3 +52,15 @@ enum fs_status fs_file_write(
|
||||
f->f_seek = seek;
|
||||
return status;
|
||||
}
|
||||
|
||||
enum fs_status fs_file_readdir(struct fs_file *f, struct xpc_buffer *buf)
|
||||
{
|
||||
if (!f->f_ops || !f->f_ops->f_readdir) {
|
||||
return FS_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
off_t seek = f->f_seek;
|
||||
enum fs_status status = f->f_ops->f_readdir(f, buf, &seek);
|
||||
f->f_seek = seek;
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ struct fs_file_ops {
|
||||
size_t,
|
||||
off_t *);
|
||||
enum fs_status (*f_seek)(struct fs_file *, off_t, int);
|
||||
enum fs_status (
|
||||
*f_readdir)(struct fs_file *, struct xpc_buffer *, off_t *);
|
||||
};
|
||||
|
||||
extern struct fs_inode *fs_file_get_inode(const struct fs_file *f);
|
||||
@@ -37,4 +39,8 @@ extern enum fs_status fs_file_write(
|
||||
const struct xpc_buffer *buf,
|
||||
size_t count);
|
||||
|
||||
extern enum fs_status fs_file_readdir(
|
||||
struct fs_file *f,
|
||||
struct xpc_buffer *buf);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,6 @@ extern kern_status_t fs_msg_read(
|
||||
const xpc_endpoint_t *sender,
|
||||
size_t count,
|
||||
int *out_err,
|
||||
size_t *out_nr_read,
|
||||
xpc_buffer_t *out_data,
|
||||
void *arg);
|
||||
extern kern_status_t fs_msg_write(
|
||||
@@ -55,4 +54,11 @@ extern kern_status_t fs_msg_map(
|
||||
kern_handle_t *out_vmo,
|
||||
void *arg);
|
||||
|
||||
extern kern_status_t fs_msg_getdents(
|
||||
xpc_context_t *ctx,
|
||||
const xpc_endpoint_t *sender,
|
||||
int *out_err,
|
||||
xpc_buffer_t *out_dents,
|
||||
void *arg);
|
||||
|
||||
#endif
|
||||
|
||||
34
lib/libfs/interface/getdents.c
Normal file
34
lib/libfs/interface/getdents.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "../file.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fs/context.h>
|
||||
#include <fs/file.h>
|
||||
#include <fs/status.h>
|
||||
|
||||
kern_status_t fs_msg_getdents(
|
||||
xpc_context_t *xpc,
|
||||
const xpc_endpoint_t *sender,
|
||||
int *out_err,
|
||||
xpc_buffer_t *out_dents,
|
||||
void *arg)
|
||||
{
|
||||
struct fs_context *ctx = arg;
|
||||
struct fs_file *f = fs_context_get_file(ctx, sender->e_port);
|
||||
if (!f) {
|
||||
*out_err = EBADF;
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
if (!(f->f_inode->i_mode & FS_INODE_DIR)) {
|
||||
*out_err = ENOTDIR;
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
size_t start = fs_file_get_cursor(f);
|
||||
enum fs_status status = fs_file_readdir(f, out_dents);
|
||||
size_t end = fs_file_get_cursor(f);
|
||||
|
||||
*out_err = fs_status_to_errno(status);
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
@@ -8,7 +8,6 @@ extern kern_status_t fs_msg_read(
|
||||
xpc_endpoint_t *sender,
|
||||
size_t count,
|
||||
int *out_err,
|
||||
size_t *out_nr_read,
|
||||
xpc_buffer_t *out_data,
|
||||
void *arg)
|
||||
{
|
||||
@@ -24,7 +23,7 @@ extern kern_status_t fs_msg_read(
|
||||
size_t end = fs_file_get_cursor(f);
|
||||
|
||||
*out_err = fs_status_to_errno(status);
|
||||
*out_nr_read = end - start;
|
||||
out_data->buf_len = end - start;
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user