1 use system_error::SystemError; 2 3 use crate::{ 4 process::{fork::CloneFlags, ProcessManager}, 5 syscall::Syscall, 6 }; 7 8 use super::namespace::{ 9 check_unshare_flags, commit_nsset, prepare_nsset, unshare_nsproxy_namespaces, 10 }; 11 12 impl Syscall { 13 pub fn sys_unshare(mut unshare_flags: u64) -> Result<usize, SystemError> { 14 if unshare_flags & CloneFlags::CLONE_NEWUSER.bits() != 0 { 15 unshare_flags |= CloneFlags::CLONE_THREAD.bits() | CloneFlags::CLONE_FS.bits(); 16 } 17 18 if unshare_flags & CloneFlags::CLONE_VM.bits() != 0 { 19 unshare_flags |= CloneFlags::CLONE_SIGHAND.bits(); 20 } 21 22 if unshare_flags & CloneFlags::CLONE_SIGHAND.bits() != 0 { 23 unshare_flags |= CloneFlags::CLONE_THREAD.bits(); 24 } 25 26 if unshare_flags & CloneFlags::CLONE_NEWNS.bits() != 0 { 27 unshare_flags |= CloneFlags::CLONE_FS.bits(); 28 } 29 30 let check = check_unshare_flags(unshare_flags)?; 31 32 let current = ProcessManager::current_pcb(); 33 if let Some(nsproxy) = unshare_nsproxy_namespaces(unshare_flags)? { 34 *current.get_nsproxy().write() = nsproxy; 35 } 36 37 Ok(check) 38 } 39 40 pub fn sys_setns(_fd: i32, flags: u64) -> Result<usize, SystemError> { 41 let check = check_unshare_flags(flags)?; 42 43 let nsset = prepare_nsset(flags)?; 44 45 if check == 0 { 46 commit_nsset(nsset) 47 }; 48 Ok(0) 49 } 50 } 51