lib: xpc: implement support for iterating through directories

This commit is contained in:
2026-03-24 12:41:12 +00:00
parent 1eb6853cb0
commit 30614e679b
6 changed files with 61 additions and 3 deletions

View File

@@ -92,6 +92,7 @@ struct fs_context *fs_context_create(struct fs_allocator *alloc)
ctx->ctx_vtable.write = fs_msg_write; ctx->ctx_vtable.write = fs_msg_write;
ctx->ctx_vtable.seek = fs_msg_seek; ctx->ctx_vtable.seek = fs_msg_seek;
ctx->ctx_vtable.map = fs_msg_map; ctx->ctx_vtable.map = fs_msg_map;
ctx->ctx_vtable.getdents = fs_msg_getdents;
return ctx; return ctx;
} }

View File

@@ -52,3 +52,15 @@ enum fs_status fs_file_write(
f->f_seek = seek; f->f_seek = seek;
return status; 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;
}

View File

@@ -19,6 +19,8 @@ struct fs_file_ops {
size_t, size_t,
off_t *); off_t *);
enum fs_status (*f_seek)(struct fs_file *, off_t, int); 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); 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, const struct xpc_buffer *buf,
size_t count); size_t count);
extern enum fs_status fs_file_readdir(
struct fs_file *f,
struct xpc_buffer *buf);
#endif #endif

View File

@@ -27,7 +27,6 @@ extern kern_status_t fs_msg_read(
const xpc_endpoint_t *sender, const xpc_endpoint_t *sender,
size_t count, size_t count,
int *out_err, int *out_err,
size_t *out_nr_read,
xpc_buffer_t *out_data, xpc_buffer_t *out_data,
void *arg); void *arg);
extern kern_status_t fs_msg_write( extern kern_status_t fs_msg_write(
@@ -55,4 +54,11 @@ extern kern_status_t fs_msg_map(
kern_handle_t *out_vmo, kern_handle_t *out_vmo,
void *arg); 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 #endif

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

View File

@@ -8,7 +8,6 @@ extern kern_status_t fs_msg_read(
xpc_endpoint_t *sender, xpc_endpoint_t *sender,
size_t count, size_t count,
int *out_err, int *out_err,
size_t *out_nr_read,
xpc_buffer_t *out_data, xpc_buffer_t *out_data,
void *arg) void *arg)
{ {
@@ -24,7 +23,7 @@ extern kern_status_t fs_msg_read(
size_t end = fs_file_get_cursor(f); size_t end = fs_file_get_cursor(f);
*out_err = fs_status_to_errno(status); *out_err = fs_status_to_errno(status);
*out_nr_read = end - start; out_data->buf_len = end - start;
return KERN_OK; return KERN_OK;
} }