From 8a22d9666927cd2d7040711b7db4eb4dcf73fc48 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 15 Nov 2016 16:11:43 -0700 Subject: [PATCH] Minimal O_CLOEXEC implementation --- scheme/resource.rs | 40 ++++++++++++++++++++++++++++++---------- scheme/scheme.rs | 13 +++++++++++-- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/scheme/resource.rs b/scheme/resource.rs index ab756e578f..ea044d278d 100644 --- a/scheme/resource.rs +++ b/scheme/resource.rs @@ -3,14 +3,15 @@ use redoxfs::FileSystem; use std::cmp::{min, max}; use syscall::error::{Error, Result, EBADF, EINVAL}; -use syscall::flag::{O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR}; +use syscall::flag::{O_ACCMODE, O_CLOEXEC, O_RDONLY, O_WRONLY, O_RDWR, F_GETFL, F_SETFL}; use syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END}; pub trait Resource { - fn dup(&self) -> Result>; + fn dup(&self, buf: &[u8]) -> Result>; fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem) -> Result; fn write(&mut self, buf: &[u8], fs: &mut FileSystem) -> Result; fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem) -> Result; + fn fcntl(&mut self, cmd: usize, arg: usize) -> Result; fn path(&self, buf: &mut [u8]) -> Result; fn stat(&self, _stat: &mut Stat, fs: &mut FileSystem) -> Result; fn sync(&mut self) -> Result; @@ -36,7 +37,7 @@ impl DirResource { } impl Resource for DirResource { - fn dup(&self) -> Result> { + fn dup(&self, _buf: &[u8]) -> Result> { Ok(Box::new(DirResource { path: self.path.clone(), block: self.block, @@ -70,6 +71,10 @@ impl Resource for DirResource { Ok(self.seek) } + fn fcntl(&mut self, _cmd: usize, _arg: usize) -> Result { + Err(Error::new(EBADF)) + } + fn path(&self, buf: &mut [u8]) -> Result { let path = self.path.as_bytes(); @@ -121,13 +126,17 @@ impl FileResource { } impl Resource for FileResource { - fn dup(&self) -> Result> { - Ok(Box::new(FileResource { - path: self.path.clone(), - block: self.block, - flags: self.flags, - seek: self.seek, - })) + fn dup(&self, buf: &[u8]) -> Result> { + if buf == b"exec" && self.flags & O_CLOEXEC == O_CLOEXEC { + Err(Error::new(EBADF)) + } else { + Ok(Box::new(FileResource { + path: self.path.clone(), + block: self.block, + flags: self.flags, + seek: self.seek, + })) + } } fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem) -> Result { @@ -163,6 +172,17 @@ impl Resource for FileResource { Ok(self.seek as usize) } + fn fcntl(&mut self, cmd: usize, arg: usize) -> Result { + match cmd { + F_GETFL => Ok(self.flags), + F_SETFL => { + self.flags = arg & ! O_ACCMODE; + Ok(0) + } + _ => Err(Error::new(EINVAL)) + } + } + fn path(&self, buf: &mut [u8]) -> Result { let path = self.path.as_bytes(); diff --git a/scheme/scheme.rs b/scheme/scheme.rs index 3270bdbd23..a87c2b7944 100644 --- a/scheme/scheme.rs +++ b/scheme/scheme.rs @@ -286,12 +286,12 @@ impl Scheme for FileScheme { /* Resource operations */ #[allow(unused_variables)] - fn dup(&self, old_id: usize, _buf: &[u8]) -> Result { + fn dup(&self, old_id: usize, buf: &[u8]) -> Result { // println!("Dup {}", old_id); let mut files = self.files.lock(); let resource = if let Some(old_resource) = files.get(&old_id) { - try!(old_resource.dup()) + old_resource.dup(buf)? } else { return Err(Error::new(EBADF)); }; @@ -333,6 +333,15 @@ impl Scheme for FileScheme { } } + fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result { + let mut files = self.files.lock(); + if let Some(mut file) = files.get_mut(&id) { + file.fcntl(cmd, arg) + } else { + Err(Error::new(EBADF)) + } + } + fn fpath(&self, id: usize, buf: &mut [u8]) -> Result { // println!("Fpath {}, {:X} {}", id, buf.as_ptr() as usize, buf.len()); let files = self.files.lock();