1use core::str;
2
3use strat9_syscall::data::{
4 IPC_FILE_FLAG_CHUNK_READ, IPC_FILE_FLAG_CHUNK_WRITE, IPC_FILE_FLAG_PIPE,
5};
6use strate_net::IpcMessage;
7
8pub(crate) const HANDLE_FLAG_INFO: u32 = IPC_FILE_FLAG_CHUNK_READ;
9pub(crate) const HANDLE_FLAG_CONTROL: u32 = 0;
10pub(crate) const HANDLE_FLAG_STREAM: u32 =
11 IPC_FILE_FLAG_PIPE | IPC_FILE_FLAG_CHUNK_READ | IPC_FILE_FLAG_CHUNK_WRITE;
12pub(crate) const HANDLE_FLAG_DATAGRAM: u32 = IPC_FILE_FLAG_CHUNK_READ;
13
14pub(crate) fn reply_open(sender: u64, file_id: u64, size: u64, flags: u32) -> IpcMessage {
15 let mut msg = IpcMessage::new(0x80);
16 msg.sender = sender;
17 msg.payload[0..4].copy_from_slice(&0u32.to_le_bytes());
18 msg.payload[4..12].copy_from_slice(&file_id.to_le_bytes());
19 msg.payload[12..20].copy_from_slice(&size.to_le_bytes());
20 msg.payload[20..24].copy_from_slice(&flags.to_le_bytes());
21 msg
22}
23
24pub(crate) fn reply_read(sender: u64, data: &[u8]) -> IpcMessage {
25 let mut msg = IpcMessage::new(0x80);
26 msg.sender = sender;
27 msg.payload[0..4].copy_from_slice(&0u32.to_le_bytes());
28 let n = data.len().min(IpcMessage::READ_INLINE_CAPACITY);
29 msg.payload[4..8].copy_from_slice(&(n as u32).to_le_bytes());
30 msg.payload[8..8 + n].copy_from_slice(&data[..n]);
31 msg
32}
33
34pub(crate) fn reply_write(sender: u64, n: usize) -> IpcMessage {
35 let mut msg = IpcMessage::new(0x80);
36 msg.sender = sender;
37 msg.payload[0..4].copy_from_slice(&0u32.to_le_bytes());
38 msg.payload[4..8].copy_from_slice(&(n as u32).to_le_bytes());
39 msg
40}
41
42pub(crate) fn reply_write_data_len(sender: u64, msg: &IpcMessage) -> IpcMessage {
43 let data_len = u16::from_le_bytes([msg.payload[16], msg.payload[17]]) as usize;
44 reply_write(sender, data_len)
45}
46
47pub(crate) fn reply_ok(sender: u64) -> IpcMessage {
48 let mut msg = IpcMessage::new(0x80);
49 msg.sender = sender;
50 msg.payload[0..4].copy_from_slice(&0u32.to_le_bytes());
51 msg
52}
53
54pub(crate) fn open_path(msg: &IpcMessage) -> Result<&str, i32> {
55 let path_len = u16::from_le_bytes([msg.payload[4], msg.payload[5]]) as usize;
56 if path_len > IpcMessage::OPEN_INLINE_CAPACITY {
57 return Err(-22);
58 }
59 let path_bytes = &msg.payload[6..6 + path_len];
60 let path = str::from_utf8(path_bytes).map_err(|_| -22)?;
61 Ok(path.trim_start_matches('/'))
62}
63
64pub(crate) fn message_file_id(msg: &IpcMessage) -> u64 {
65 u64::from_le_bytes(msg.payload[0..8].try_into().unwrap_or([0u8; 8]))
66}
67
68pub(crate) fn read_request(msg: &IpcMessage) -> (u64, u64, usize) {
69 let file_id = message_file_id(msg);
70 let offset = u64::from_le_bytes(msg.payload[8..16].try_into().unwrap_or([0u8; 8]));
71 let requested = u32::from_le_bytes(msg.payload[16..20].try_into().unwrap_or([0u8; 4]));
72 (file_id, offset, requested as usize)
73}
74
75pub(crate) fn write_data_len(msg: &IpcMessage) -> usize {
76 let data_len = u16::from_le_bytes([msg.payload[16], msg.payload[17]]) as usize;
77 core::cmp::min(data_len, msg.payload.len().saturating_sub(18))
78}
79
80pub(crate) fn write_data(msg: &IpcMessage) -> &[u8] {
81 let data_len = write_data_len(msg);
82 &msg.payload[18..18 + data_len]
83}