1use crate::{
7 arch::Trapframe,
8 ipc::event::{
9 Event, EventContent, EventManager, EventPayload, EventPriority, ProcessControlType,
10 },
11 ipc::pipe::UnidirectionalPipe,
12 ipc::shared_memory::SharedMemory,
13 library::std::string::parse_c_string_from_userspace,
14 object::KernelObject,
15 object::capability::EventSubscriber,
16 task::mytask,
17};
18use alloc::{string::ToString, sync::Arc};
19
20pub fn sys_pipe(trapframe: &mut Trapframe) -> usize {
33 let task = match mytask() {
34 Some(task) => task,
35 None => return usize::MAX,
36 };
37
38 let pipefd_ptr = trapframe.get_arg(0);
39
40 trapframe.increment_pc_next(task);
42
43 let pipefd_vaddr = match task.vm_manager.translate_vaddr(pipefd_ptr) {
45 Some(addr) => addr as *mut u32,
46 None => return usize::MAX, };
48
49 const DEFAULT_PIPE_BUFFER_SIZE: usize = 4096;
51 let (read_obj, write_obj) = UnidirectionalPipe::create_pair(DEFAULT_PIPE_BUFFER_SIZE);
52
53 use crate::object::handle::{AccessMode, HandleMetadata, HandleType};
55
56 let read_metadata = HandleMetadata {
57 handle_type: HandleType::IpcChannel,
58 access_mode: AccessMode::ReadOnly,
59 special_semantics: None,
60 };
61
62 let write_metadata = HandleMetadata {
63 handle_type: HandleType::IpcChannel,
64 access_mode: AccessMode::WriteOnly,
65 special_semantics: None,
66 };
67
68 let read_handle = match task
69 .handle_table
70 .insert_with_metadata(read_obj, read_metadata)
71 {
72 Ok(handle) => handle,
73 Err(_) => return usize::MAX, };
75
76 let write_handle = match task
77 .handle_table
78 .insert_with_metadata(write_obj, write_metadata)
79 {
80 Ok(handle) => handle,
81 Err(_) => {
82 let _ = task.handle_table.remove(read_handle);
84 return usize::MAX;
85 }
86 };
87
88 unsafe {
90 *pipefd_vaddr = read_handle;
91 *pipefd_vaddr.add(1) = write_handle;
92 }
93
94 0 }
96
97pub fn sys_pipe2(trapframe: &mut Trapframe) -> usize {
102 let _pipefd_ptr = trapframe.get_arg(0);
103 let _flags = trapframe.get_arg(1);
104
105 sys_pipe(trapframe)
108}
109
110pub fn sys_event_channel_create(trapframe: &mut Trapframe) -> usize {
119 let task = match mytask() {
120 Some(task) => task,
121 None => return usize::MAX,
122 };
123
124 let name_ptr = trapframe.get_arg(0);
125 trapframe.increment_pc_next(task);
126
127 let name = match parse_c_string_from_userspace(task, name_ptr, 256) {
128 Ok(s) => s,
129 Err(_) => return usize::MAX,
130 };
131
132 let mgr = EventManager::get_manager();
133 let ko = mgr.create_channel(name);
134 match task.handle_table.insert(ko) {
135 Ok(h) => h as usize,
136 Err(_) => usize::MAX,
137 }
138}
139
140pub fn sys_event_subscribe(trapframe: &mut Trapframe) -> usize {
147 let task = match mytask() {
148 Some(task) => task,
149 None => return usize::MAX,
150 };
151
152 let name_ptr = trapframe.get_arg(0);
153 trapframe.increment_pc_next(task);
154
155 let name = match parse_c_string_from_userspace(task, name_ptr, 256) {
156 Ok(s) => s,
157 Err(_) => return usize::MAX,
158 };
159
160 let mgr = EventManager::get_manager();
161 let ko = match mgr.create_subscription(name, task.get_id() as u32) {
162 Ok(ko) => ko,
163 Err(_) => return usize::MAX,
164 };
165 match task.handle_table.insert(ko) {
166 Ok(h) => h as usize,
167 Err(_) => usize::MAX,
168 }
169}
170
171pub fn sys_event_unsubscribe(trapframe: &mut Trapframe) -> usize {
178 let task = match mytask() {
179 Some(task) => task,
180 None => return usize::MAX,
181 };
182
183 let handle = trapframe.get_arg(0) as u32;
184 trapframe.increment_pc_next(task);
185
186 let (channel_name, subscription_id) = match task.handle_table.get(handle) {
188 Some(KernelObject::EventSubscription(sub)) => (
189 sub.channel_name().to_string(),
190 sub.subscription_id().to_string(),
191 ),
192 _ => return usize::MAX,
193 };
194
195 let mgr = EventManager::get_manager();
197 let _ = mgr.remove_subscription_from_channel(&channel_name, &subscription_id);
198
199 match task.handle_table.remove(handle) {
201 Some(_) => 0,
202 None => usize::MAX,
203 }
204}
205
206pub fn sys_event_publish(trapframe: &mut Trapframe) -> usize {
215 let task = match mytask() {
216 Some(task) => task,
217 None => return usize::MAX,
218 };
219
220 let channel_handle = trapframe.get_arg(0) as u32;
221 let event_id = trapframe.get_arg(1) as u32;
222 let payload_val = trapframe.get_arg(2) as isize as i64;
223 trapframe.increment_pc_next(task);
224
225 let ko = match task.handle_table.get(channel_handle) {
226 Some(obj) => obj,
227 None => return usize::MAX,
228 };
229
230 let channel = match ko.as_event_channel() {
231 Some(ch) => ch,
232 None => return usize::MAX,
233 };
234
235 let ev = Event::channel(
236 channel.name().to_string(),
237 EventContent::Custom {
238 namespace: "user".into(),
239 event_id,
240 },
241 false,
242 EventPriority::Normal,
243 EventPayload::Integer(payload_val),
244 );
245
246 match channel.broadcast_to_subscribers(ev) {
247 Ok(()) => 0,
248 Err(_) => usize::MAX,
249 }
250}
251
252pub fn sys_event_handler_register(trapframe: &mut Trapframe) -> usize {
264 let task = match mytask() {
265 Some(task) => task,
266 None => return usize::MAX,
267 };
268
269 let sub_handle = trapframe.get_arg(0) as u32;
270 let handler_id = trapframe.get_arg(1);
271 let filter_kind = trapframe.get_arg(2) as u32;
272 let param0 = trapframe.get_arg(3) as u32;
273 trapframe.increment_pc_next(task);
274
275 let ko = match task.handle_table.get(sub_handle) {
276 Some(obj) => obj,
277 None => return usize::MAX,
278 };
279 let sub = match ko.as_event_subscription() {
280 Some(s) => s,
281 None => return usize::MAX,
282 };
283
284 use crate::ipc::event::{EventFilter, EventTypeFilter};
285 let filter = match filter_kind {
286 0 => EventFilter::All,
287 1 => EventFilter::Sender(param0),
288 2 => EventFilter::EventId(param0),
289 3 => EventFilter::EventType(EventTypeFilter::Direct(param0)),
290 _ => EventFilter::All,
291 };
292
293 match sub.register_filter(filter, handler_id) {
294 Ok(()) => 0,
295 Err(_) => usize::MAX,
296 }
297}
298
299pub fn sys_event_send_direct(trapframe: &mut Trapframe) -> usize {
307 let task = match mytask() {
308 Some(task) => task,
309 None => return usize::MAX,
310 };
311 let target = trapframe.get_arg(0) as u32;
312 let kind = trapframe.get_arg(1) as u32;
313 let reliable = trapframe.get_arg(2) as u32 != 0;
314 let prio_raw = trapframe.get_arg(3) as u32;
315 trapframe.increment_pc_next(task);
316
317 let priority = match prio_raw {
318 1 => EventPriority::Low,
319 3 => EventPriority::High,
320 4 => EventPriority::Critical,
321 _ => EventPriority::Normal,
322 };
323
324 let event = if kind >= 1000 {
325 Event::direct_custom(
326 target,
327 "user".into(),
328 kind - 1000,
329 priority,
330 reliable,
331 EventPayload::Empty,
332 )
333 } else {
334 let ptype = match kind {
335 0 => ProcessControlType::Terminate,
336 1 => ProcessControlType::Kill,
337 2 => ProcessControlType::Stop,
338 3 => ProcessControlType::Continue,
339 4 => ProcessControlType::Interrupt,
340 5 => ProcessControlType::Quit,
341 6 => ProcessControlType::Hangup,
342 7 => ProcessControlType::ChildExit,
343 8 => ProcessControlType::PipeBroken,
344 9 => ProcessControlType::Alarm,
345 10 => ProcessControlType::IoReady,
346 _ => ProcessControlType::Terminate,
347 };
348 Event::direct_process_control(target, ptype, priority, reliable)
349 };
350
351 let mgr = EventManager::get_manager();
352 match mgr.send_event(event) {
353 Ok(()) => 0,
354 Err(_) => usize::MAX,
355 }
356}
357
358pub fn sys_shared_memory_create(trapframe: &mut Trapframe) -> usize {
373 let task = match mytask() {
374 Some(task) => task,
375 None => return usize::MAX,
376 };
377
378 let size = trapframe.get_arg(0);
379 let permissions = trapframe.get_arg(1);
380
381 trapframe.increment_pc_next(task);
383
384 if size == 0 || size > 1024 * 1024 * 1024 {
386 return usize::MAX;
388 }
389
390 let shmem = match SharedMemory::new(size, permissions) {
392 Ok(shmem) => shmem,
393 Err(_) => return usize::MAX,
394 };
395
396 let kernel_obj = KernelObject::from_shared_memory_object(Arc::new(shmem));
398
399 use crate::object::handle::{AccessMode, HandleMetadata, HandleType};
401
402 let metadata = HandleMetadata {
403 handle_type: HandleType::IpcChannel,
404 access_mode: if permissions & 0x3 == 0x3 {
405 AccessMode::ReadWrite
406 } else if permissions & 0x2 != 0 {
407 AccessMode::WriteOnly
408 } else {
409 AccessMode::ReadOnly
410 },
411 special_semantics: None,
412 };
413
414 let handle = match task.handle_table.insert_with_metadata(kernel_obj, metadata) {
415 Ok(handle) => handle,
416 Err(_) => return usize::MAX, };
418
419 handle as usize
420}
421
422pub fn sys_shared_memory_resize(trapframe: &mut Trapframe) -> usize {
432 let task = match mytask() {
433 Some(task) => task,
434 None => return usize::MAX,
435 };
436
437 let handle = trapframe.get_arg(0) as u32;
438 let size = trapframe.get_arg(1);
439
440 crate::println!("[sys_shared_memory_resize] handle={} size={}", handle, size);
441
442 trapframe.increment_pc_next(task);
443
444 let kernel_obj = match task.handle_table.get(handle) {
445 Some(obj) => obj,
446 None => {
447 crate::println!("[sys_shared_memory_resize] handle not found");
448 return usize::MAX;
449 }
450 };
451
452 let shared_memory = match kernel_obj.as_shared_memory() {
453 Some(obj) => obj,
454 None => {
455 crate::println!("[sys_shared_memory_resize] not a shared memory object");
456 return usize::MAX;
457 }
458 };
459
460 if let Err(e) = shared_memory.resize(size) {
461 crate::println!("[sys_shared_memory_resize] resize failed: {}", e);
462 return usize::MAX;
463 }
464
465 crate::println!(
466 "[sys_shared_memory_resize] SUCCESS new_size={}",
467 shared_memory.size()
468 );
469 0
470}
471
472pub fn sys_socket_send_handle(trapframe: &mut Trapframe) -> usize {
487 let task = match mytask() {
488 Some(task) => task,
489 None => return usize::MAX,
490 };
491
492 let socket_handle = trapframe.get_arg(0) as u32;
493 let object_handle = trapframe.get_arg(1) as u32;
494
495 trapframe.increment_pc_next(task);
497
498 let socket_obj = match task.handle_table.get(socket_handle) {
500 Some(KernelObject::Socket(socket)) => socket.clone(),
501 _ => return usize::MAX, };
503
504 use crate::network::local::LocalSocket;
505 let local_socket = match LocalSocket::from_socket_object(&socket_obj) {
506 Some(s) => s,
507 None => return usize::MAX, };
509
510 let object = match task.handle_table.clone_for_dup(object_handle) {
513 Some(obj) => obj,
514 None => return usize::MAX, };
516
517 match local_socket.send_handle(object) {
519 Ok(()) => 0,
520 Err(_) => usize::MAX,
521 }
522}
523
524pub fn sys_socket_recv_handle(trapframe: &mut Trapframe) -> usize {
536 let task = match mytask() {
537 Some(task) => task,
538 None => return usize::MAX,
539 };
540
541 let socket_handle = trapframe.get_arg(0) as u32;
542
543 trapframe.increment_pc_next(task);
545
546 let socket_obj = match task.handle_table.get(socket_handle) {
548 Some(KernelObject::Socket(socket)) => socket.clone(),
549 _ => return usize::MAX, };
551
552 use crate::network::local::LocalSocket;
555 let local_socket = match LocalSocket::from_socket_object(&socket_obj) {
556 Some(s) => s,
557 None => return usize::MAX, };
559
560 let object = match local_socket.recv_handle_blocking(task.get_id(), trapframe) {
561 Ok(obj) => obj,
562 Err(_) => return usize::MAX,
563 };
564
565 match task.handle_table.insert(object) {
567 Ok(handle) => handle as usize,
568 Err(_) => usize::MAX, }
570}
571
572pub fn sys_socket_send_handle_and_data(trapframe: &mut Trapframe) -> usize {
588 let task = match mytask() {
589 Some(task) => task,
590 None => return usize::MAX,
591 };
592
593 let socket_handle = trapframe.get_arg(0) as u32;
594 let object_handle = trapframe.get_arg(1) as u32;
595 let data_ptr = trapframe.get_arg(2);
596 let data_len = trapframe.get_arg(3);
597
598 trapframe.increment_pc_next(task);
600
601 let socket_obj = match task.handle_table.get(socket_handle) {
603 Some(KernelObject::Socket(socket)) => socket.clone(),
604 _ => return usize::MAX, };
606
607 use crate::network::local::LocalSocket;
608 let local_socket = match LocalSocket::from_socket_object(&socket_obj) {
609 Some(s) => s,
610 None => return usize::MAX, };
612
613 let object = match task.handle_table.clone_for_dup(object_handle) {
615 Some(obj) => obj,
616 None => return usize::MAX, };
618
619 if data_len == 0 {
621 match local_socket.send_handle(object) {
623 Ok(()) => return 0,
624 Err(_) => return usize::MAX,
625 }
626 }
627
628 let data_addr = match task.vm_manager.translate_vaddr(data_ptr) {
629 Some(addr) => addr,
630 None => return usize::MAX, };
632
633 const MAX_SEND_SIZE: usize = 65536; let data_len = data_len.min(MAX_SEND_SIZE);
636
637 let data = unsafe { core::slice::from_raw_parts(data_addr as *const u8, data_len) };
639
640 match local_socket.send_handle_and_data(object, data) {
642 Ok(()) => 0,
643 Err(_) => usize::MAX,
644 }
645}
646
647pub fn sys_socket_recv_handle_and_data(trapframe: &mut Trapframe) -> usize {
662 let task = match mytask() {
663 Some(task) => task,
664 None => return usize::MAX,
665 };
666
667 let socket_handle = trapframe.get_arg(0) as u32;
668 let handle_ptr = trapframe.get_arg(1);
669 let data_ptr = trapframe.get_arg(2);
670 let max_data_len = trapframe.get_arg(3);
671
672 trapframe.increment_pc_next(task);
674
675 let socket_obj = match task.handle_table.get(socket_handle) {
677 Some(KernelObject::Socket(socket)) => socket.clone(),
678 _ => return usize::MAX, };
680
681 use crate::network::local::LocalSocket;
682 let local_socket = match LocalSocket::from_socket_object(&socket_obj) {
683 Some(s) => s,
684 None => return usize::MAX, };
686
687 const MAX_RECV_SIZE: usize = 65536; let max_data_len = max_data_len.min(MAX_RECV_SIZE);
690
691 let (object, data) = match local_socket.recv_handle_and_data(max_data_len) {
693 Ok((h, d)) => (h, d),
694 Err(_) => return usize::MAX,
695 };
696
697 let new_handle = match task.handle_table.insert(object) {
699 Ok(h) => h,
700 Err(_) => return usize::MAX, };
702
703 if handle_ptr != 0 {
705 let handle_addr = match task.vm_manager.translate_vaddr(handle_ptr) {
706 Some(addr) => addr as *mut u32,
707 None => return usize::MAX,
708 };
709 unsafe {
710 *handle_addr = new_handle;
711 }
712 }
713
714 if !data.is_empty() && data_ptr != 0 {
716 let data_addr = match task.vm_manager.translate_vaddr(data_ptr) {
717 Some(addr) => addr as *mut u8,
718 None => return usize::MAX,
719 };
720 unsafe {
721 core::ptr::copy_nonoverlapping(data.as_ptr(), data_addr, data.len());
722 }
723 }
724
725 data.len()
726}