lib: fs: implement fs.seek()
This commit is contained in:
@@ -90,6 +90,7 @@ struct fs_context *fs_context_create(struct fs_allocator *alloc)
|
|||||||
ctx->ctx_vtable.close = fs_msg_close;
|
ctx->ctx_vtable.close = fs_msg_close;
|
||||||
ctx->ctx_vtable.read = fs_msg_read;
|
ctx->ctx_vtable.read = fs_msg_read;
|
||||||
ctx->ctx_vtable.write = fs_msg_write;
|
ctx->ctx_vtable.write = fs_msg_write;
|
||||||
|
ctx->ctx_vtable.seek = fs_msg_seek;
|
||||||
ctx->ctx_vtable.map = fs_msg_map;
|
ctx->ctx_vtable.map = fs_msg_map;
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ extern kern_status_t fs_msg_write(
|
|||||||
size_t *out_nr_written,
|
size_t *out_nr_written,
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
|
extern kern_status_t fs_msg_seek(
|
||||||
|
xpc_context_t *ctx,
|
||||||
|
const xpc_endpoint_t *sender,
|
||||||
|
off_t offset,
|
||||||
|
int origin,
|
||||||
|
int *out_err,
|
||||||
|
off_t *out_new_pos,
|
||||||
|
void *arg);
|
||||||
extern kern_status_t fs_msg_map(
|
extern kern_status_t fs_msg_map(
|
||||||
xpc_context_t *ctx,
|
xpc_context_t *ctx,
|
||||||
const xpc_endpoint_t *sender,
|
const xpc_endpoint_t *sender,
|
||||||
|
|||||||
52
lib/libfs/interface/seek.c
Normal file
52
lib/libfs/interface/seek.c
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include "../file.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fs/context.h>
|
||||||
|
#include <fs/file.h>
|
||||||
|
#include <fs/status.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
extern kern_status_t fs_msg_seek(
|
||||||
|
xpc_context_t *xpc,
|
||||||
|
const xpc_endpoint_t *sender,
|
||||||
|
off_t rel_offset,
|
||||||
|
int origin,
|
||||||
|
int *out_err,
|
||||||
|
off_t *out_new_pos,
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t new_offset = 0;
|
||||||
|
|
||||||
|
switch (origin) {
|
||||||
|
case SEEK_SET:
|
||||||
|
new_offset = rel_offset;
|
||||||
|
break;
|
||||||
|
case SEEK_CUR:
|
||||||
|
new_offset = f->f_seek + rel_offset;
|
||||||
|
break;
|
||||||
|
case SEEK_END:
|
||||||
|
new_offset = f->f_inode->i_size + rel_offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*out_err = EINVAL;
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_offset > f->f_inode->i_size) {
|
||||||
|
*out_err = EINVAL;
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->f_seek = new_offset;
|
||||||
|
*out_err = SUCCESS;
|
||||||
|
*out_new_pos = new_offset;
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user