diff --git a/lib/libmsg-fs/CMakeLists.txt b/lib/libmsg-fs/CMakeLists.txt index abcbea3..90c2127 100644 --- a/lib/libmsg-fs/CMakeLists.txt +++ b/lib/libmsg-fs/CMakeLists.txt @@ -18,4 +18,4 @@ sysroot_add_library( HEADER_DIR /usr/include LIB_DIR /usr/lib) -target_link_libraries(libmsg-fs libmsg libmango) +target_link_libraries(libmsg-fs libmsg libmango ulibc) diff --git a/lib/libmsg-fs/fs.c b/lib/libmsg-fs/fs.c index e4a0c44..33cf939 100644 --- a/lib/libmsg-fs/fs.c +++ b/lib/libmsg-fs/fs.c @@ -1,3 +1,111 @@ -void msg_fs_tmp(void) +#include +#include + +kern_status_t rosetta_msg_fs_open_send( + kern_handle_t port, + const char *path, + int flags, + int *out_err) { + size_t path_len = strlen(path); + + struct rosetta_msg_fs_open msg = {0}; + rosetta_msg_init(&msg.msg_base, ROSETTA_MSG_FS, ROSETTA_MSG_FS_OPEN); + uint16_t offset = sizeof msg; + msg.msg_request.o_path = offset; + msg.msg_request.o_path_len = path_len; + msg.msg_request.o_flags = flags; + + struct iovec send_vec[] = { + IOVEC(&msg, sizeof msg), + IOVEC(path, path_len), + }; + + struct iovec reply_vec[] = { + IOVEC(&msg, sizeof msg), + }; + + struct msg req = { + .msg_data = send_vec, + .msg_data_count = sizeof send_vec / sizeof send_vec[0], + }; + + struct msg resp = { + .msg_data = reply_vec, + .msg_data_count = sizeof reply_vec / sizeof reply_vec[0], + }; + + kern_status_t status = msg_send(port, 0, &req, &resp); + if (status != KERN_OK) { + return status; + } + + *out_err = msg.msg_response.o_err; + + return KERN_OK; +} + +kern_status_t rosetta_msg_fs_open_recv( + kern_handle_t channel, + msgid_t id, + struct rosetta_msg_string *out_path, + int *out_flags) +{ + struct rosetta_msg_fs_open msg; + struct iovec vec = IOVEC(&msg, sizeof msg); + size_t r = 0; + + kern_status_t status = msg_read(channel, id, 0, &vec, 1, &r); + if (status != KERN_OK) { + return status; + } + + if (r != sizeof msg) { + /* TODO better error code for malformed messages */ + return KERN_INVALID_ARGUMENT; + } + + out_path->s_len = msg.msg_request.o_path_len; + if (out_path->s_max > 0) { + vec.io_base = (virt_addr_t)out_path->s_buf; + vec.io_len = out_path->s_max - 1; + + if (vec.io_len > out_path->s_len) { + vec.io_len = out_path->s_len; + } + + status = msg_read( + channel, + id, + msg.msg_request.o_path, + &vec, + 1, + &r); + if (status != KERN_OK) { + return status; + } + + if (r != out_path->s_len) { + return KERN_INVALID_ARGUMENT; + } + + out_path->s_buf[out_path->s_len] = 0; + } + + *out_flags = msg.msg_request.o_flags; + + return KERN_OK; +} + +kern_status_t rosetta_msg_fs_open_reply( + kern_handle_t channel, + msgid_t id, + int err) +{ + struct rosetta_msg_fs_open msg = {0}; + msg.msg_response.o_err = err; + struct iovec vec = IOVEC(&msg, sizeof msg); + + struct msg kmsg = {.msg_data = &vec, .msg_data_count = 1}; + return msg_reply(channel, 0, id, &kmsg); } diff --git a/lib/libmsg-fs/include/rosetta/msg/fs.h b/lib/libmsg-fs/include/rosetta/msg/fs.h index b258673..8c6c1b7 100644 --- a/lib/libmsg-fs/include/rosetta/msg/fs.h +++ b/lib/libmsg-fs/include/rosetta/msg/fs.h @@ -7,21 +7,36 @@ #define ROSETTA_MSG_FS 0x01409DD2U /* rosetta.msg.fs.open message ID */ -#define ROSETTA_MSG_FS_OPEN 0x7D837778U +#define ROSETTA_MSG_FS_OPEN 0x7778U struct rosetta_msg_fs_open { struct rosetta_msg msg_base; union { struct { uint16_t o_path; + uint16_t o_path_len; uint16_t o_flags; } msg_request; struct { int o_err; - uint16_t o_fd_index; } msg_response; }; }; +extern kern_status_t rosetta_msg_fs_open_send( + kern_handle_t port, + const char *path, + int flags, + int *out_err); +extern kern_status_t rosetta_msg_fs_open_recv( + kern_handle_t channel, + msgid_t id, + struct rosetta_msg_string *out_path, + int *out_flags); +extern kern_status_t rosetta_msg_fs_open_reply( + kern_handle_t channel, + msgid_t id, + int err); + #endif