kernel/abi/xv6/riscv64/
pipe.rs1use crate::{arch::Trapframe, ipc::UnidirectionalPipe, task::mytask};
2
3pub fn sys_pipe(
4 abi: &mut crate::abi::xv6::riscv64::Xv6Riscv64Abi,
5 trapframe: &mut Trapframe,
6) -> usize {
7 let task = mytask().unwrap();
8 trapframe.increment_pc_next(task);
9
10 let pipefd_ptr = task
11 .vm_manager
12 .translate_vaddr(trapframe.get_arg(0))
13 .expect("Invalid pipefd pointer");
14 let pipefd = unsafe { &mut *(pipefd_ptr as *mut [u32; 2]) };
15
16 let (read_end, write_end) = UnidirectionalPipe::create_pair(4096);
17
18 let read_handle = task
19 .handle_table
20 .insert(read_end)
21 .expect("Failed to insert read end");
22 let write_handle = task
23 .handle_table
24 .insert(write_end)
25 .expect("Failed to insert write end");
26
27 let read_fd = match abi.allocate_fd(read_handle as u32) {
29 Ok(fd) => fd,
30 Err(_) => return usize::MAX, };
32 let write_fd = match abi.allocate_fd(write_handle as u32) {
33 Ok(fd) => fd,
34 Err(_) => {
35 abi.remove_fd(read_fd);
37 task.handle_table.remove(read_handle);
38 return usize::MAX; }
40 };
41
42 pipefd[0] = read_fd as u32;
43 pipefd[1] = write_fd as u32;
44
45 0
46}