1use strat9_abi::ipc_payload::{
8 OpenReply, OpenRequest, ReadReply, ReadRequest, WriteReply, WriteRequest,
9};
10use strat9_syscall::data::{
11 IpcMessage, IPC_FILE_FLAG_CHUNK_READ, IPC_FILE_FLAG_CHUNK_WRITE, IPC_FILE_FLAG_PIPE,
12};
13
14pub(crate) const HANDLE_FLAG_INFO: u32 = IPC_FILE_FLAG_CHUNK_READ;
15pub(crate) const HANDLE_FLAG_CONTROL: u32 = 0;
16pub(crate) const HANDLE_FLAG_STREAM: u32 =
17 IPC_FILE_FLAG_PIPE | IPC_FILE_FLAG_CHUNK_READ | IPC_FILE_FLAG_CHUNK_WRITE;
18pub(crate) const HANDLE_FLAG_DATAGRAM: u32 = IPC_FILE_FLAG_CHUNK_READ;
19
20const EINVAL: i32 = -22;
22
23pub(crate) fn reply_open(sender: u64, file_id: u64, size: u64, flags: u32) -> IpcMessage {
24 let mut msg = IpcMessage::new(IpcMessage::REPLY_MSG_TYPE);
25 msg.sender = sender;
26 OpenReply {
27 status: 0,
28 file_id,
29 size,
30 file_flags: flags,
31 }
32 .encode_into(&mut msg.payload);
33 msg
34}
35
36pub(crate) fn reply_read(sender: u64, data: &[u8]) -> IpcMessage {
37 let (msg, _n) = ReadReply::encode_ok(sender, data);
38 msg
39}
40
41pub(crate) fn reply_write(sender: u64, n: usize) -> IpcMessage {
42 WriteReply::encode_ok(sender, n)
43}
44
45pub(crate) fn reply_write_data_len(sender: u64, msg: &IpcMessage) -> IpcMessage {
46 match WriteRequest::parse_prefix(&msg.payload) {
47 Some(req) => reply_write(sender, req.data_len as usize),
48 None => reply_write(sender, 0),
49 }
50}
51
52pub(crate) fn reply_ok(sender: u64) -> IpcMessage {
53 IpcMessage::status_reply(sender, 0)
54}
55
56pub(crate) fn open_path(msg: &IpcMessage) -> Result<&str, i32> {
58 let (_flags, path) = OpenRequest::parse(&msg.payload).ok_or(EINVAL)?;
59 if path.len() > IpcMessage::OPEN_INLINE_CAPACITY {
60 return Err(EINVAL);
61 }
62 Ok(path.trim_start_matches('/'))
63}
64
65pub(crate) fn message_file_id(msg: &IpcMessage) -> u64 {
66 u64::from_le_bytes(msg.payload[0..8].try_into().unwrap_or([0u8; 8]))
68}
69
70pub(crate) fn read_request(msg: &IpcMessage) -> (u64, u64, usize) {
72 match ReadRequest::parse(&msg.payload) {
73 Some(req) => (req.ino, req.offset, req.count_usize()),
74 None => (0, 0, 0),
75 }
76}
77
78pub(crate) fn write_data(msg: &IpcMessage) -> &[u8] {
79 WriteRequest::parse_prefix(&msg.payload)
80 .and_then(|req| req.data(&msg.payload))
81 .unwrap_or(&[])
82}