(
uctx: &UserContext,
flags: u32,
stack: usize,
parent_tid: usize,
#[cfg(any(target_arch = "x86_64", target_arch = "loongarch64"))] child_tid: usize,
tls: usize,
#[cfg(not(
| 86 | } |
| 87 | |
| 88 | pub fn sys_clone( |
| 89 | uctx: &UserContext, |
| 90 | flags: u32, |
| 91 | stack: usize, |
| 92 | parent_tid: usize, |
| 93 | #[cfg(any(target_arch = "x86_64", target_arch = "loongarch64"))] child_tid: usize, |
| 94 | tls: usize, |
| 95 | #[cfg(not(any(target_arch = "x86_64", target_arch = "loongarch64")))] child_tid: usize, |
| 96 | ) -> AxResult<isize> { |
| 97 | const FLAG_MASK: u32 = 0xff; |
| 98 | let exit_signal = flags & FLAG_MASK; |
| 99 | let mut flags = CloneFlags::from_bits_truncate(flags & !FLAG_MASK); |
| 100 | if flags.contains(CloneFlags::VFORK) { |
| 101 | debug!("sys_clone: CLONE_VFORK slow path"); |
| 102 | flags.remove(CloneFlags::VM); |
| 103 | } |
| 104 | |
| 105 | debug!( |
| 106 | "sys_clone <= flags: {flags:?}, exit_signal: {exit_signal}, stack: {stack:#x}, ptid: \ |
| 107 | {parent_tid:#x}, ctid: {child_tid:#x}, tls: {tls:#x}" |
| 108 | ); |
| 109 | |
| 110 | if exit_signal != 0 && flags.contains(CloneFlags::THREAD | CloneFlags::PARENT) { |
| 111 | return Err(AxError::InvalidInput); |
| 112 | } |
| 113 | if flags.contains(CloneFlags::THREAD) && !flags.contains(CloneFlags::VM | CloneFlags::SIGHAND) { |
| 114 | return Err(AxError::InvalidInput); |
| 115 | } |
| 116 | if flags.contains(CloneFlags::PIDFD | CloneFlags::PARENT_SETTID) { |
| 117 | return Err(AxError::InvalidInput); |
| 118 | } |
| 119 | let exit_signal = Signo::from_repr(exit_signal as u8); |
| 120 | |
| 121 | let mut new_uctx = *uctx; |
| 122 | if stack != 0 { |
| 123 | new_uctx.set_sp(stack); |
| 124 | } |
| 125 | if flags.contains(CloneFlags::SETTLS) { |
| 126 | new_uctx.set_tls(tls); |
| 127 | } |
| 128 | new_uctx.set_retval(0); |
| 129 | |
| 130 | let set_child_tid = if flags.contains(CloneFlags::CHILD_SETTID) { |
| 131 | child_tid |
| 132 | } else { |
| 133 | 0 |
| 134 | }; |
| 135 | |
| 136 | let curr = current(); |
| 137 | let old_proc_data = &curr.as_thread().proc_data; |
| 138 | |
| 139 | let mut new_task = new_user_task(&curr.name(), new_uctx, set_child_tid); |
| 140 | |
| 141 | let tid = new_task.id().as_u64() as Pid; |
| 142 | if flags.contains(CloneFlags::PARENT_SETTID) { |
| 143 | (parent_tid as *mut Pid).vm_write(tid).ok(); |
| 144 | } |
| 145 |
no test coverage detected