diff --git a/src/context/context.rs b/src/context/context.rs index 3a5acad..b6db7b5 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -109,6 +109,8 @@ pub struct Context { pub egid: u32, /// The effective namespace id pub ens: SchemeNamespace, + /// Process umask + pub umask: usize, /// Status of context pub status: Status, /// Context running or not @@ -169,6 +171,7 @@ impl Context { euid: 0, egid: 0, ens: SchemeNamespace::from(0), + umask: 0o022, status: Status::Blocked, running: false, cpu_id: None, diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 437c434..77a0cb9 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -85,13 +85,15 @@ pub fn getcwd(buf: &mut [u8]) -> Result { /// Open syscall pub fn open(path: &[u8], flags: usize) -> Result { - let (path_canon, uid, gid, scheme_ns) = { + let (path_canon, uid, gid, scheme_ns, umask) = { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - (context.canonicalize(path), context.euid, context.egid, context.ens) + (context.canonicalize(path), context.euid, context.egid, context.ens, context.umask) }; + let flags = (flags & (!0o777)) | (flags & 0o777) & (!(umask & 0o777)); + //println!("open {}", unsafe { ::core::str::from_utf8_unchecked(&path_canon) }); let mut parts = path_canon.splitn(2, |&b| b == b':'); diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index 37a1a10..cd2831f 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -131,6 +131,7 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u SYS_PHYSFREE => physfree(b, c), SYS_PHYSMAP => physmap(b, c, d), SYS_PHYSUNMAP => physunmap(b), + SYS_UMASK => umask(b), SYS_VIRTTOPHYS => virttophys(b), _ => Err(Error::new(ENOSYS)) } diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 110264b..895286c 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -73,6 +73,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result { let euid; let egid; let ens; + let umask; let mut cpu_id = None; let arch; let vfork; @@ -104,6 +105,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result { euid = context.euid; egid = context.egid; ens = context.ens; + umask = context.umask; if flags & CLONE_VM == CLONE_VM { cpu_id = context.cpu_id; @@ -323,6 +325,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result { context.euid = euid; context.egid = egid; context.ens = ens; + context.umask = umask; context.cpu_id = cpu_id; @@ -1187,6 +1190,19 @@ pub fn sigreturn() -> Result { unreachable!(); } +pub fn umask(mask: usize) -> Result { + let previous; + { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let mut context = context_lock.write(); + previous = context.umask; + context.umask = mask; + } + + Ok(previous) +} + fn reap(pid: ContextId) -> Result { // Spin until not running let mut running = true; diff --git a/syscall b/syscall index de0f062..cbb3916 160000 --- a/syscall +++ b/syscall @@ -1 +1 @@ -Subproject commit de0f06244695a5cbdd3a8157dc19823324af951e +Subproject commit cbb39163d4f08cec10adb9154ad53c8be323b7a6