Compare commits

...

13 Commits

27 changed files with 523 additions and 78 deletions

View File

@@ -3,9 +3,11 @@ interface fs 6400;
func open[0](path: string, flags: int) -> (err: int);
func close[1]() -> (err: int);
func read[2](count: size) -> (err: int, nr_read: size, data: buffer);
func read[2](count: size) -> (err: int, data: buffer);
func write[3](data: buffer) -> (err: int, nr_written: size);
func seek[4](offset: offset, origin: int) -> (err: int, new_pos: offset);
func map[5](prot: int, flags: int) -> (err: int, vmo: handle);
func getdents[6]() -> (err: int, dents: buffer);

2
kernel

Submodule kernel updated: 110f625f04...a0a6a061a4

View File

@@ -1,12 +1,10 @@
#include <errno.h>
#include <mango/log.h>
#include <mango/status.h>
static int __errno = 32;
int __attribute__((weak)) * __errno_location(void)
{
kern_log("using builtin errno");
return &__errno;
}

13
lib/libc/include/dirent.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef DIRENT_H_
#define DIRENT_H_
#define DT_UNKNOWN 0
#define DT_BLK 1
#define DT_CHR 2
#define DT_DIR 3
#define DT_FIFO 4
#define DT_LNK 5
#define DT_REG 6
#define DT_SOCK 7
#endif

View File

@@ -7,4 +7,11 @@
#define SEEK_CUR 1
#define SEEK_END 2
struct dentry {
unsigned long d_ino;
unsigned short d_reclen;
char d_type;
char d_name[];
};
#endif

View File

@@ -12,4 +12,6 @@ extern int write(int fd, const void *buf, size_t count);
extern off_t lseek(int fd, off_t offset, int whence);
extern long getdents(int fd, struct dentry *dirp, unsigned int count);
#endif

View File

@@ -0,0 +1,22 @@
#include <errno.h>
#include <mango/handle.h>
#include <mango/msg.h>
#include <rosetta/fs.h>
#include <sys/remote.h>
#include <sys/types.h>
int getdents(int fd, struct dentry *dirp, unsigned int count)
{
int err;
size_t nr_read = 0;
kern_status_t status = fs_getdents(fd, &err, dirp, count, &nr_read);
if (status != KERN_OK) {
return __set_errno(__errno_from_kern_status(status));
}
if (err != SUCCESS) {
return __set_errno(err);
}
return nr_read;
}

View File

@@ -8,7 +8,7 @@ int read(int fd, void *buf, size_t count)
{
int err;
size_t nr_read;
kern_status_t status = fs_read(fd, count, &err, &nr_read, buf, count);
kern_status_t status = fs_read(fd, count, &err, buf, count, &nr_read);
if (status != KERN_OK) {
return __set_errno(__errno_from_kern_status(status));
}

View File

@@ -1,12 +1,9 @@
#include "pthread.h"
#include <mango/log.h>
#include <pthread.h>
#include <stdio.h>
int *__errno_location(void)
{
struct __pthread *self = pthread_self();
kern_logf("using pthread errno %p", &self->thr_errno);
return &self->thr_errno;
}

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.seek = fs_msg_seek;
ctx->ctx_vtable.map = fs_msg_map;
ctx->ctx_vtable.getdents = fs_msg_getdents;
return ctx;
}
@@ -140,6 +141,28 @@ kern_handle_t fs_context_get_vm_controller(const struct fs_context *ctx)
return ctx->ctx_vm_controller;
}
static enum fs_status handle_event(struct fs_context *ctx, xpc_msg_t *msg)
{
switch (msg->msg_event) {
case KERN_MSG_EVENT_CONNECTION:
kern_logf("received connection");
break;
case KERN_MSG_EVENT_DISCONNECTION: {
struct fs_file *f
= fs_context_get_file(ctx, msg->msg_sender.e_port);
if (f) {
fs_context_close_file(ctx, f);
}
break;
}
default:
kern_logf("received unknown event");
break;
}
return FS_SUCCESS;
}
static enum fs_status handle_msg(struct fs_context *ctx)
{
xpc_msg_t msg;
@@ -153,6 +176,10 @@ static enum fs_status handle_msg(struct fs_context *ctx)
return FS_ERR_INTERNAL_FAILURE;
}
if (msg.msg_type != KERN_MSG_TYPE_DATA) {
return handle_event(ctx, &msg);
}
switch (msg.msg_header.hdr_interface) {
case INTERFACE_FS:
status = fs_context_dispatch_msg(ctx, &msg);
@@ -168,18 +195,43 @@ static enum fs_status handle_msg(struct fs_context *ctx)
return FS_SUCCESS;
}
static enum fs_status handle_page_request(struct fs_context *ctx)
static enum fs_status handle_page_request_detach(
struct fs_context *ctx,
equeue_packet_page_request_t *packet,
struct file_mapping *mapping)
{
equeue_packet_page_request_t packet;
vm_controller_recv(ctx->ctx_vm_controller, &packet);
struct file_mapping *mapping = (struct file_mapping *)packet.req_vmo;
kern_tracef(
"received page request [%zx-%zx] for file %s",
packet.req_offset,
packet.req_offset + packet.req_length,
kern_logf(
"received page request (detach) for file %s",
mapping->m_file->f_dent->d_name);
size_t length = packet.req_length;
struct fs_file *f = mapping->m_file;
switch (mapping->m_type) {
case FILE_MAPPING_PRIVATE:
queue_delete(&f->f_mappings, &mapping->m_entry);
break;
default:
break;
}
kern_handle_close(mapping->m_vmo);
fs_context_free(ctx, mapping);
fs_context_close_file(ctx, f);
return FS_SUCCESS;
}
static enum fs_status handle_page_request_read(
struct fs_context *ctx,
equeue_packet_page_request_t *packet,
struct file_mapping *mapping)
{
kern_tracef(
"received page request (read) [%zx-%zx] for file %s",
packet->req_offset,
packet->req_offset + packet->req_length,
mapping->m_file->f_dent->d_name);
size_t length = packet->req_length;
if (length > TEMP_OBJECT_SIZE) {
length = TEMP_OBJECT_SIZE;
}
@@ -189,7 +241,7 @@ static enum fs_status handle_page_request(struct fs_context *ctx)
enum fs_status status = fs_file_read_at(
mapping->m_file,
&buf,
packet.req_offset,
packet->req_offset,
length);
if (status != FS_SUCCESS) {
kern_tracef("map-read failed with code %d", status);
@@ -199,10 +251,34 @@ static enum fs_status handle_page_request(struct fs_context *ctx)
vm_controller_supply_pages(
ctx->ctx_vm_controller,
mapping->m_vmo,
packet.req_offset,
packet->req_offset,
ctx->ctx_temp_object,
0,
packet.req_length);
packet->req_length);
return FS_SUCCESS;
}
static enum fs_status handle_page_request(struct fs_context *ctx)
{
equeue_packet_page_request_t packet;
kern_status_t status
= vm_controller_recv(ctx->ctx_vm_controller, &packet);
if (status != KERN_OK) {
return KERN_BAD_STATE;
}
struct file_mapping *mapping = (struct file_mapping *)packet.req_vmo;
switch (packet.req_type) {
case PAGE_REQUEST_READ:
return handle_page_request_read(ctx, &packet, mapping);
case PAGE_REQUEST_DETACH:
return handle_page_request_detach(ctx, &packet, mapping);
default:
kern_logf("unknown page request type %zx", packet.req_type);
break;
}
return FS_SUCCESS;
}
@@ -261,6 +337,16 @@ struct fs_file *fs_context_get_file(struct fs_context *ctx, unsigned long id)
void fs_context_close_file(struct fs_context *ctx, struct fs_file *f)
{
if (f->f_ref > 1) {
kern_logf(
"reference to file '%s' has been closed",
f->f_dent->d_name);
f->f_ref--;
return;
}
kern_logf("file '%s' has been closed", f->f_dent->d_name);
btree_delete(&ctx->ctx_filelist, &f->f_node);
}
static size_t get_first_path_component(const char *in, char *out, size_t max)

View File

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

View File

@@ -9,6 +9,9 @@
#include <fs/inode.h>
struct fs_file {
/* reference count includes the file descriptor, and any vm-objects
* attached to the file */
unsigned int f_ref;
/* id of the open file, equal to the koid of the port being used to
* access the file */
unsigned long f_id;

View File

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

View File

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

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

@@ -105,6 +105,7 @@ extern kern_status_t fs_msg_map(
kern_handle_t vmo;
kern_handle_duplicate(mapping->m_vmo, &vmo);
f->f_ref++;
*out_err = SUCCESS;
*out_vmo = vmo;

View File

@@ -45,6 +45,7 @@ extern kern_status_t fs_msg_open(
return KERN_OK;
}
f->f_ref = 1;
f->f_seek = 0;
f->f_dent = dent;
f->f_inode = dent->d_inode;

View File

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

View File

@@ -5,6 +5,7 @@
kern_status_t xpc_buffer_read(
const xpc_buffer_t *buf,
size_t offset,
void *out,
size_t max,
size_t *nr_read)
@@ -14,25 +15,35 @@ kern_status_t xpc_buffer_read(
return KERN_BAD_STATE;
}
size_t to_read = max;
if (to_read > buf->buf_len) {
to_read = buf->buf_len;
if (offset >= buf->buf_len) {
if (nr_read) {
*nr_read = 0;
}
return KERN_OK;
}
kern_status_t status
= xpc_msg_read(buf->buf_origin, buf->buf_offset, out, to_read);
size_t to_read = max;
if (offset + to_read > buf->buf_len) {
to_read = buf->buf_len - offset;
}
kern_status_t status = xpc_msg_read(
buf->buf_origin,
buf->buf_offset + offset,
out,
to_read,
nr_read);
if (status != KERN_OK) {
return status;
}
/* TODO */
*nr_read = to_read;
return KERN_OK;
}
kern_status_t xpc_buffer_write(
xpc_buffer_t *buf,
size_t offset,
const void *in,
size_t len,
size_t *nr_written)
@@ -41,9 +52,17 @@ kern_status_t xpc_buffer_write(
return KERN_BAD_STATE;
}
if (offset >= buf->buf_max) {
if (nr_written) {
*nr_written = 0;
}
return KERN_OK;
}
size_t to_write = len;
if (to_write > buf->buf_max) {
to_write = buf->buf_max;
if (offset + to_write > buf->buf_max) {
to_write = buf->buf_max - offset;
}
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
@@ -54,8 +73,70 @@ kern_status_t xpc_buffer_write(
return xpc_msg_write(
buf->buf_origin,
buf->buf_offset,
buf->buf_offset + offset,
in,
to_write,
nr_written);
}
xpc_status_t xpc_buffer_readv(
const xpc_buffer_t *buf,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read)
{
if (!(buf->buf_flags & XPC_BUFFER_F_IN)) {
return KERN_BAD_STATE;
}
/* TODO limit to buffer bounds */
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
/* TODO */
return KERN_UNIMPLEMENTED;
}
return xpc_msg_readv(
buf->buf_origin,
buf->buf_offset + offset,
iov,
nr_iov,
nr_read);
}
xpc_status_t xpc_buffer_writev(
xpc_buffer_t *buf,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written)
{
if (!(buf->buf_flags & XPC_BUFFER_F_OUT)) {
return KERN_BAD_STATE;
}
/* TODO limit to buffer bounds */
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
/* TODO */
return KERN_UNIMPLEMENTED;
}
return xpc_msg_writev(
buf->buf_origin,
buf->buf_offset + offset,
iov,
nr_iov,
nr_written);
}
xpc_status_t xpc_buffer_length(const xpc_buffer_t *s)
{
return s->buf_len;
}
xpc_status_t xpc_buffer_capacity(const xpc_buffer_t *s)
{
return s->buf_max;
}

View File

@@ -1,6 +1,7 @@
#ifndef XPC_BUFFER_H_
#define XPC_BUFFER_H_
#include <mango/types.h>
#include <stddef.h>
#include <xpc/status.h>
@@ -71,13 +72,31 @@ typedef struct xpc_buffer {
extern xpc_status_t xpc_buffer_read(
const xpc_buffer_t *s,
size_t offset,
void *out,
size_t max,
size_t *nr_read);
extern xpc_status_t xpc_buffer_write(
xpc_buffer_t *s,
size_t offset,
const void *in,
size_t len,
size_t *nr_written);
extern xpc_status_t xpc_buffer_readv(
const xpc_buffer_t *s,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read);
extern xpc_status_t xpc_buffer_writev(
xpc_buffer_t *s,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written);
extern xpc_status_t xpc_buffer_length(const xpc_buffer_t *s);
extern xpc_status_t xpc_buffer_capacity(const xpc_buffer_t *s);
#endif

View File

@@ -17,10 +17,21 @@ typedef struct xpc_msg_header {
typedef struct xpc_msg {
xpc_endpoint_t msg_sender;
xpc_msg_header_t msg_header;
size_t msg_handles_count;
kern_msg_type_t msg_type;
kern_msg_handle_t msg_handles[KERN_MSG_MAX_HANDLES];
union {
/* msg_type = KERN_MSG_TYPE_DATA */
struct {
xpc_msg_header_t msg_header;
size_t msg_handles_count;
kern_msg_handle_t msg_handles[KERN_MSG_MAX_HANDLES];
};
/* msg_type = KERN_MSG_TYPE_EVENT */
struct {
kern_msg_event_type_t msg_event;
};
};
} xpc_msg_t;
extern void xpc_msg_header_init(
@@ -34,7 +45,8 @@ extern kern_status_t xpc_msg_read(
const xpc_msg_t *msg,
size_t offset,
void *p,
size_t count);
size_t count,
size_t *nr_read);
extern kern_status_t xpc_msg_write(
const xpc_msg_t *msg,
size_t offset,
@@ -42,6 +54,19 @@ extern kern_status_t xpc_msg_write(
size_t count,
size_t *nr_written);
extern kern_status_t xpc_msg_readv(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read);
extern kern_status_t xpc_msg_writev(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written);
extern kern_status_t xpc_msg_reply(
const xpc_msg_t *msg,
kern_iovec_t *iov,

View File

@@ -54,14 +54,24 @@ static kern_status_t __msg_recv(
return status;
}
if (!xpc_msg_header_validate(&out->msg_header)) {
return KERN_INVALID_ARGUMENT;
switch (msg.msg_type) {
case KERN_MSG_TYPE_DATA:
if (!xpc_msg_header_validate(&out->msg_header)) {
return KERN_INVALID_ARGUMENT;
}
break;
case KERN_MSG_TYPE_EVENT:
out->msg_event = msg.msg_event;
break;
default:
break;
}
out->msg_sender.e_channel = channel;
out->msg_sender.e_task = msg.msg_sender;
out->msg_sender.e_port = msg.msg_endpoint;
out->msg_sender.e_msg = msg.msg_id;
out->msg_type = msg.msg_type;
return KERN_OK;
}
@@ -89,17 +99,17 @@ kern_status_t xpc_msg_read(
const xpc_msg_t *msg,
size_t offset,
void *p,
size_t count)
size_t count,
size_t *nr_read)
{
kern_iovec_t iov = IOVEC(p, count);
size_t r = 0;
return msg_read(
msg->msg_sender.e_channel,
msg->msg_sender.e_msg,
offset,
&iov,
1,
&r);
nr_read);
}
kern_status_t xpc_msg_write(
@@ -119,6 +129,38 @@ kern_status_t xpc_msg_write(
nr_written);
}
kern_status_t xpc_msg_readv(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read)
{
return msg_read(
msg->msg_sender.e_channel,
msg->msg_sender.e_msg,
offset,
iov,
nr_iov,
nr_read);
}
kern_status_t xpc_msg_writev(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written)
{
return msg_write(
msg->msg_sender.e_channel,
msg->msg_sender.e_msg,
offset,
iov,
nr_iov,
nr_written);
}
kern_status_t xpc_msg_reply(
const xpc_msg_t *msg,
kern_iovec_t *iov,

View File

@@ -19,14 +19,12 @@ xpc_status_t xpc_string_read(
}
kern_status_t status
= xpc_msg_read(s->s_origin, s->s_offset, out, to_read);
= xpc_msg_read(s->s_origin, s->s_offset, out, to_read, nr_read);
if (status != KERN_OK) {
return status;
}
out[to_read] = '\0';
/* TODO */
*nr_read = to_read;
return KERN_OK;
}

View File

@@ -3,6 +3,9 @@
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/remote.h>
#include <sys/types.h>
#include <unistd.h>
static void *thread_func(void *arg)
{
@@ -13,6 +16,8 @@ static void *thread_func(void *arg)
int main(int argc, const char *argv[], const char *envp[])
{
sys_remote_set(SYS_REMOTE_NSD, 0, 0);
kern_logf("herdd");
kern_logf("args:");
@@ -29,6 +34,28 @@ int main(int argc, const char *argv[], const char *envp[])
kern_logf("self = %p", pthread_self());
errno = 200;
#if 1
int dir = open("/", 0);
if (dir >= 0) {
kern_logf("opened '/'");
char buf[4096] = {0};
struct dentry *dent = (struct dentry *)buf;
long len = getdents(dir, dent, sizeof buf);
if (len < 0) {
kern_logf("getdents failed (%s)", strerror(errno));
} else {
for (long i = 0; i < len;) {
dent = (struct dentry *)(buf + i);
kern_logf(" - %s", dent->d_name);
i += dent->d_reclen;
}
}
close(dir);
} else {
kern_logf("open() failed: %s", strerror(errno));
}
#endif
pthread_t thread;
pthread_create(&thread, NULL, thread_func, (void *)0xdeafcafe);
kern_logf("started thread %p", thread);
@@ -36,8 +63,5 @@ int main(int argc, const char *argv[], const char *envp[])
pthread_join(thread, &ret);
kern_logf("thread returned %p", ret);
kern_logf("errno...");
kern_logf("%u", errno);
kern_logf("...errno");
return 0;
}

View File

@@ -203,31 +203,6 @@ int main(
while (1) {
fs_context_handle_request(fs);
#if 0
xpc_msg_t msg;
kern_status_t status = xpc_msg_recv(channel, &msg);
if (status != KERN_OK) {
kern_logf("message recv error %d", status);
continue;
}
switch (msg.msg_header.hdr_interface) {
case INTERFACE_FS:
status = fs_context_dispatch_msg(fs, &msg);
break;
default:
kern_logf(
"unknown message protocol %u",
msg.msg_header.hdr_interface);
xpc_msg_reply_error(&msg, KERN_UNSUPPORTED);
break;
}
if (status != KERN_OK) {
kern_logf("message reply error %d", status);
continue;
}
#endif
}
return 0;

View File

@@ -11,6 +11,7 @@
#include <mango/vm.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <xpc/buffer.h>
struct tar_superblock {
@@ -148,6 +149,24 @@ static struct tar_entry *entry_get_child(
return NULL;
}
static struct tar_entry *entry_get_child_at(struct tar_entry *entry, size_t at)
{
struct queue_entry *cur = queue_first(&entry->e_children);
while (cur) {
struct tar_entry *child
= QUEUE_CONTAINER(struct tar_entry, e_entry, cur);
if (at == 0) {
return child;
}
at--;
cur = queue_next(cur);
}
return NULL;
}
static const struct fs_dentry_ops dentry_ops = {};
static enum fs_status dir_lookup(
@@ -189,7 +208,7 @@ static enum fs_status file_read(
char *src = (char *)entry->e_data + offset;
size_t w;
xpc_buffer_write(buf, src, count, &w);
xpc_buffer_write(buf, 0, src, count, &w);
offset += w;
*seek = offset;
@@ -197,10 +216,66 @@ static enum fs_status file_read(
return FS_SUCCESS;
}
static enum fs_status dir_readdir(
struct fs_file *f,
xpc_buffer_t *out,
off_t *seek)
{
off_t offset = *seek;
struct tar_entry *entry = entry_from_inode(fs_file_get_inode(f));
if (!entry) {
return FS_ERR_BAD_STATE;
}
size_t bytes_written = 0;
size_t available = xpc_buffer_capacity(out);
while (1) {
struct tar_entry *child = entry_get_child_at(entry, offset);
if (!child) {
break;
}
struct dentry dent = {0};
size_t name_len = strlen(child->e_dentry.d_name);
size_t to_write
= offsetof(struct dentry, d_name) + name_len + 1;
if (to_write > available) {
break;
}
dent.d_reclen = to_write;
kern_iovec_t iov[] = {
IOVEC(&dent, offsetof(struct dentry, d_name)),
IOVEC(child->e_dentry.d_name, name_len + 1),
};
size_t tmp = 0;
kern_status_t status
= xpc_buffer_writev(out, bytes_written, iov, 2, &tmp);
if (status != KERN_OK) {
break;
}
bytes_written += tmp;
available -= tmp;
offset++;
}
*seek = offset;
out->buf_len = bytes_written;
return FS_SUCCESS;
}
static const struct fs_file_ops file_ops = {
.f_read = file_read,
};
static const struct fs_file_ops dir_ops = {
.f_readdir = dir_readdir,
};
static const struct fs_inode_ops file_inode_ops = {
.i_lookup = NULL,
};
@@ -224,6 +299,7 @@ static struct tar_entry *create_dir_entry(
entry->e_inode.i_sb = &sb->sb_base;
entry->e_inode.i_mode = FS_INODE_DIR;
entry->e_inode.i_ops = &dir_inode_ops;
entry->e_inode.i_fops = &dir_ops;
entry->e_dentry.d_sb = &sb->sb_base;
entry->e_dentry.d_ops = &dentry_ops;

View File

@@ -542,6 +542,11 @@ static int emit_interface_msg_function_send_impl(
emit(ctx, ": KERN_HANDLE_INVALID;\n");
break;
case TYPE_BUFFER:
emit(ctx,
"*out_%s_len = msg_data.msg_response.%s_len;\n",
param->p_name,
param->p_name);
break;
case TYPE_STRING:
break;
default:
@@ -627,13 +632,17 @@ static int emit_interface_msg_function_send(
break;
case TYPE_STRING:
emit(ctx,
"char *out_%s,\nsize_t out_%s_max",
"char *out_%s,\nsize_t out_%s_max,\nsize_t "
"*out_%s_len",
param->p_name,
param->p_name,
param->p_name);
break;
case TYPE_BUFFER:
emit(ctx,
"void *out_%s,\nsize_t out_%s_max",
"void *out_%s,\nsize_t out_%s_max,\nsize_t "
"*out_%s_len",
param->p_name,
param->p_name,
param->p_name);
break;
@@ -679,7 +688,7 @@ static int emit_interface_dispatcher_impl_msg(
msg->msg_name);
emit(ctx,
"status = xpc_msg_read(msg, 0, &" MSG_STRUCT_NAME
", sizeof " MSG_STRUCT_NAME ");\n");
", sizeof " MSG_STRUCT_NAME ", NULL);\n");
fx_queue_entry *entry = fx_queue_first(&msg->msg_params);
while (entry) {
@@ -836,6 +845,13 @@ static int emit_interface_dispatcher_impl_msg(
handle_index);
handle_index++;
break;
case TYPE_BUFFER:
emit(ctx,
MSG_STRUCT_NAME
".msg_response.%s_len = xpc_buffer_length(&%s);\n",
param->p_name,
param->p_name);
break;
default:
break;
}