kernel/object/capability/stream/
syscall.rs

1//! System calls for StreamOps capability
2//!
3//! This module implements system calls that operate on KernelObjects
4//! with StreamOps capability (read/write operations).
5
6use crate::arch::Trapframe;
7use crate::task::mytask;
8
9/// System call for reading from a KernelObject with StreamOps capability
10///
11/// # Arguments
12/// - handle: Handle to the KernelObject
13/// - buffer_ptr: Pointer to the buffer to read into
14/// - count: Number of bytes to read
15///
16/// # Returns
17/// - On success: number of bytes read
18/// - On error: usize::MAX
19pub fn sys_stream_read(trapframe: &mut Trapframe) -> usize {
20    let task = match mytask() {
21        Some(task) => task,
22        None => return usize::MAX,
23    };
24
25    let handle = trapframe.get_arg(0) as u32;
26    let buf_ptr = match task.vm_manager.translate_vaddr(trapframe.get_arg(1)) {
27        Some(ptr) => ptr as *mut u8,
28        None => return usize::MAX, // Invalid buffer pointer
29    };
30    let count = trapframe.get_arg(2) as usize;
31
32    // Increment PC to avoid infinite loop if read fails
33    trapframe.increment_pc_next(task);
34
35    // Get KernelObject from handle table
36    let kernel_obj = match task.handle_table.get(handle) {
37        Some(obj) => obj,
38        None => return usize::MAX,
39    };
40
41    // Check if object supports StreamOps
42    let stream = match kernel_obj.as_stream() {
43        Some(stream) => stream,
44        None => return usize::MAX, // Object doesn't support stream operations
45    };
46
47    // Perform read operation (may block)
48    let buffer = unsafe { core::slice::from_raw_parts_mut(buf_ptr, count) };
49    match stream.read(buffer) {
50        Ok(n) => n,
51        Err(super::StreamError::WouldBlock) => {
52            // Return EAGAIN error code (negative value indicates error)
53            (-(11i32)) as usize
54        }
55        Err(_) => usize::MAX,
56    }
57}
58
59/// System call for writing to a KernelObject with StreamOps capability
60///
61/// # Arguments
62/// - handle: Handle to the KernelObject
63/// - buffer_ptr: Pointer to the buffer to write from
64/// - count: Number of bytes to write
65///
66/// # Returns
67/// - On success: number of bytes written
68/// - On error: usize::MAX
69pub fn sys_stream_write(trapframe: &mut Trapframe) -> usize {
70    let task = match mytask() {
71        Some(task) => task,
72        None => return usize::MAX,
73    };
74
75    let handle = trapframe.get_arg(0) as u32;
76    let buf_ptr = match task.vm_manager.translate_vaddr(trapframe.get_arg(1)) {
77        Some(ptr) => ptr as *const u8,
78        None => return usize::MAX, // Invalid buffer pointer
79    };
80    let count = trapframe.get_arg(2) as usize;
81
82    // Increment PC to avoid infinite loop if write fails
83    trapframe.increment_pc_next(task);
84
85    // Get KernelObject from handle table
86    let kernel_obj = match task.handle_table.get(handle) {
87        Some(obj) => obj,
88        None => return usize::MAX, // Invalid handle
89    };
90
91    // Check if object supports StreamOps
92    let stream = match kernel_obj.as_stream() {
93        Some(stream) => stream,
94        None => return usize::MAX, // Object doesn't support stream operations
95    };
96
97    // Perform write operation
98    let buffer = unsafe { core::slice::from_raw_parts(buf_ptr, count) };
99    match stream.write(buffer) {
100        Ok(bytes_written) => bytes_written,
101        Err(_) => usize::MAX, // Write error
102    }
103}