kernel/object/handle/
syscall.rs1use crate::{
6 arch::Trapframe,
7 object::{
8 handle::HandleMetadata, handle::HandleType, handle::StandardInputOutput,
9 introspection::KernelObjectInfo,
10 },
11 task::mytask,
12};
13
14pub fn sys_handle_query(trapframe: &mut Trapframe) -> usize {
27 let task = match mytask() {
28 Some(task) => task,
29 None => return usize::MAX,
30 };
31
32 let handle = trapframe.get_arg(0) as u32;
33 let info_ptr = trapframe.get_arg(1);
34
35 trapframe.increment_pc_next(task);
37
38 let info_vaddr = match task.vm_manager.translate_vaddr(info_ptr) {
40 Some(addr) => addr as *mut KernelObjectInfo,
41 None => return usize::MAX, };
43
44 match task.handle_table.get_object_info(handle) {
46 Some(info) => {
47 unsafe {
49 *info_vaddr = info;
50 }
51 0 }
53 None => usize::MAX, }
55}
56
57pub fn sys_handle_set_role(trapframe: &mut Trapframe) -> usize {
68 let task = match mytask() {
69 Some(task) => task,
70 None => return usize::MAX,
71 };
72
73 let handle = trapframe.get_arg(0) as u32;
74 let new_role_raw = trapframe.get_arg(1);
75 let _flags = trapframe.get_arg(2);
76
77 trapframe.increment_pc_next(task);
78
79 let new_role = match decode_handle_type(new_role_raw) {
81 Some(role) => role,
82 None => return usize::MAX, };
84
85 let current_metadata = match task.handle_table.get_metadata(handle) {
87 Some(meta) => meta.clone(),
88 None => return usize::MAX, };
90
91 let new_metadata = HandleMetadata {
93 handle_type: new_role,
94 access_mode: current_metadata.access_mode,
95 special_semantics: current_metadata.special_semantics,
96 };
97
98 if let Err(_) = task.handle_table.update_metadata(handle, new_metadata) {
100 return usize::MAX; }
102
103 0 }
105
106pub fn sys_handle_close(trapframe: &mut Trapframe) -> usize {
117 let task = match mytask() {
118 Some(task) => task,
119 None => return usize::MAX,
120 };
121
122 let handle = trapframe.get_arg(0) as u32;
123 trapframe.increment_pc_next(task);
124
125 if task.handle_table.remove(handle).is_some() {
126 0 } else {
128 usize::MAX }
130}
131
132pub fn sys_handle_duplicate(trapframe: &mut Trapframe) -> usize {
144 let task = match mytask() {
145 Some(task) => task,
146 None => return usize::MAX,
147 };
148
149 let handle = trapframe.get_arg(0) as u32;
150 trapframe.increment_pc_next(task);
151
152 if let Some(kernel_obj) = task.handle_table.get(handle) {
154 match task.handle_table.insert(kernel_obj.clone()) {
156 Ok(new_handle) => new_handle as usize,
157 Err(_) => usize::MAX, }
159 } else {
160 usize::MAX }
162}
163
164fn decode_handle_type(raw: usize) -> Option<HandleType> {
166 match raw {
167 0 => Some(HandleType::Regular),
168 1 => Some(HandleType::IpcChannel),
169 2 => Some(HandleType::StandardInputOutput(StandardInputOutput::Stdin)),
170 3 => Some(HandleType::StandardInputOutput(StandardInputOutput::Stdout)),
171 4 => Some(HandleType::StandardInputOutput(StandardInputOutput::Stderr)),
172 5 => Some(HandleType::EventChannel),
173 6 => Some(HandleType::EventSubscription),
174 _ => None,
175 }
176}
177
178pub fn encode_handle_type(handle_type: &HandleType) -> usize {
180 match handle_type {
181 HandleType::Regular => 0,
182 HandleType::IpcChannel => 1,
183 HandleType::StandardInputOutput(StandardInputOutput::Stdin) => 2,
184 HandleType::StandardInputOutput(StandardInputOutput::Stdout) => 3,
185 HandleType::StandardInputOutput(StandardInputOutput::Stderr) => 4,
186 HandleType::EventChannel => 5,
187 HandleType::EventSubscription => 6,
188 }
189}
190
191pub fn sys_handle_control(trapframe: &mut Trapframe) -> usize {
205 let task = match mytask() {
206 Some(task) => task,
207 None => return usize::MAX,
208 };
209
210 let handle = trapframe.get_arg(0) as u32;
211 let command = trapframe.get_arg(1) as u32;
212 let arg = trapframe.get_arg(2);
213
214 trapframe.increment_pc_next(task);
216
217 let kernel_object = match task.handle_table.get(handle) {
219 Some(obj) => obj,
220 None => return usize::MAX,
221 };
222
223 let result = match kernel_object.as_control() {
225 Some(control_ops) => control_ops.control(command, arg),
226 None => Err("Control operations not supported on this object"),
227 };
228
229 match result {
231 Ok(value) => value as usize,
232 Err(_) => usize::MAX,
233 }
234}