112 lines
2.2 KiB
C
112 lines
2.2 KiB
C
#include <rosetta/msg/fs.h>
|
|
#include <string.h>
|
|
|
|
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);
|
|
}
|