diff --git a/scheme/debug.rs b/scheme/debug.rs index 27ab62614ccfa9a76397c89d28554ba6e9a03d88..8a8f556a8e47c15de9b74eee2c89ae792c21b14c 100644 --- a/scheme/debug.rs +++ b/scheme/debug.rs @@ -33,7 +33,7 @@ impl Scheme for DebugScheme { Ok(0) } - fn dup(&self, _file: usize) -> Result<usize> { + fn dup(&self, _file: usize, _buf: &[u8]) -> Result<usize> { Ok(0) } diff --git a/scheme/env.rs b/scheme/env.rs index 4a51485001fa96755ed3b68459e8342b71c0146d..3c88b1e19ea5eddaefe18470ec9b0e3d8720e937 100644 --- a/scheme/env.rs +++ b/scheme/env.rs @@ -88,7 +88,7 @@ impl Scheme for EnvScheme { } } - fn dup(&self, id: usize) -> Result<usize> { + fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> { let new_handle = { let handles = self.handles.read(); let handle = handles.get(&id).ok_or(Error::new(EBADF))?; diff --git a/scheme/event.rs b/scheme/event.rs index cca7420c404aa661f6ec0aaa28452ac89e6c3886..2266141eba0cab79d33d452f22f3b172e7830e9d 100644 --- a/scheme/event.rs +++ b/scheme/event.rs @@ -39,7 +39,7 @@ impl Scheme for EventScheme { Ok(id) } - fn dup(&self, id: usize) -> Result<usize> { + fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> { let handle = { let handles = self.handles.read(); let handle_weak = handles.get(&id).ok_or(Error::new(EBADF))?; diff --git a/scheme/initfs.rs b/scheme/initfs.rs index 18696ed0f8fee306fc6d867e8ecaa0f214d95f40..99f1f7d277009317b3d4f8033d5c4ccace40ff70 100644 --- a/scheme/initfs.rs +++ b/scheme/initfs.rs @@ -57,7 +57,7 @@ impl Scheme for InitFsScheme { Err(Error::new(ENOENT)) } - fn dup(&self, id: usize) -> Result<usize> { + fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> { let (path, data, mode, seek) = { let handles = self.handles.read(); let handle = handles.get(&id).ok_or(Error::new(EBADF))?; diff --git a/scheme/irq.rs b/scheme/irq.rs index f91118e870e079a5b7cc55fc7d2198ac2a8eb340..a20aca71c39efa570a3744a348659e8b4c6c9f93 100644 --- a/scheme/irq.rs +++ b/scheme/irq.rs @@ -40,7 +40,7 @@ impl Scheme for IrqScheme { } } - fn dup(&self, file: usize) -> Result<usize> { + fn dup(&self, file: usize, _buf: &[u8]) -> Result<usize> { Ok(file) } diff --git a/scheme/pipe.rs b/scheme/pipe.rs index 35dfd004f756ee727ed765f908b764b9eb929c78..49d48956f34e2eb59403122c00414ad133dab2aa 100644 --- a/scheme/pipe.rs +++ b/scheme/pipe.rs @@ -42,7 +42,7 @@ pub fn pipe(flags: usize) -> (usize, usize) { pub struct PipeScheme; impl Scheme for PipeScheme { - fn dup(&self, id: usize) -> Result<usize> { + fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> { let mut pipes = pipes_mut(); let read_option = pipes.0.get(&id).map(|pipe| pipe.clone()); diff --git a/scheme/root.rs b/scheme/root.rs index a2531328c0eb6480165fdfad33e08f7c7b79c21e..737e74b665f8e9fca93bfea4b69f794b139efe78 100644 --- a/scheme/root.rs +++ b/scheme/root.rs @@ -56,7 +56,7 @@ impl Scheme for RootScheme { } } - fn dup(&self, file: usize) -> Result<usize> { + fn dup(&self, file: usize, _buf: &[u8]) -> Result<usize> { let mut handles = self.handles.write(); let inner = { let inner = handles.get(&file).ok_or(Error::new(EBADF))?; @@ -89,12 +89,24 @@ impl Scheme for RootScheme { inner.write(buf) } - fn fevent(&self, file: usize, _flags: usize) -> Result<usize> { - Ok(file) + fn fevent(&self, file: usize, flags: usize) -> Result<usize> { + let inner = { + let handles = self.handles.read(); + let inner = handles.get(&file).ok_or(Error::new(EBADF))?; + inner.clone() + }; + + inner.fevent(flags) } - fn fsync(&self, _file: usize) -> Result<usize> { - Ok(0) + fn fsync(&self, file: usize) -> Result<usize> { + let inner = { + let handles = self.handles.read(); + let inner = handles.get(&file).ok_or(Error::new(EBADF))?; + inner.clone() + }; + + inner.fsync() } fn close(&self, file: usize) -> Result<usize> { diff --git a/scheme/sys/mod.rs b/scheme/sys/mod.rs index 917b9071edb67386c316d2090a9cd2535fab04ce..7d560d37001fba627df760793c3ea0308749b328 100644 --- a/scheme/sys/mod.rs +++ b/scheme/sys/mod.rs @@ -92,7 +92,7 @@ impl Scheme for SysScheme { Err(Error::new(ENOENT)) } - fn dup(&self, id: usize) -> Result<usize> { + fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> { let (path, data, mode, seek) = { let handles = self.handles.read(); let handle = handles.get(&id).ok_or(Error::new(EBADF))?; diff --git a/scheme/user.rs b/scheme/user.rs index 8f1c95a7d47880f81797a5ceecc5f911e207b471..28548217750a7885e98a5efa0646b5a8b0568b95 100644 --- a/scheme/user.rs +++ b/scheme/user.rs @@ -61,10 +61,7 @@ impl UserInner { }; let len = self.todo.send(packet); - //TODO: Use O_NONBLOCK and send one notification - for _i in 0 .. len { - context::event::trigger(ROOT_SCHEME_ID.load(Ordering::SeqCst), self.handle_id, EVENT_READ, mem::size_of::<Packet>()); - } + context::event::trigger(ROOT_SCHEME_ID.load(Ordering::SeqCst), self.handle_id, EVENT_READ, mem::size_of::<Packet>() * len); Error::demux(self.done.receive(&id)) } @@ -182,6 +179,14 @@ impl UserInner { Ok(i * packet_size) } + + pub fn fevent(&self, _flags: usize) -> Result<usize> { + Ok(self.handle_id) + } + + pub fn fsync(&self) -> Result<usize> { + Ok(0) + } } /// UserInner has to be wrapped @@ -230,9 +235,12 @@ impl Scheme for UserScheme { result } - fn dup(&self, file: usize) -> Result<usize> { + fn dup(&self, file: usize, buf: &[u8]) -> Result<usize> { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; - inner.call(SYS_DUP, file, 0, 0) + let address = inner.capture(buf)?; + let result = inner.call(SYS_DUP, file, address, buf.len()); + let _ = inner.release(address); + result } fn read(&self, file: usize, buf: &mut [u8]) -> Result<usize> { diff --git a/syscall/fs.rs b/syscall/fs.rs index 6c953e468f2caf6a272a4409c03a0122f9aaea87..ff4a51d8eaf5b9a8779316f2f9c5c886240bb978 100644 --- a/syscall/fs.rs +++ b/syscall/fs.rs @@ -83,10 +83,10 @@ pub fn open(path: &[u8], flags: usize) -> Result<usize> { let reference_opt = parts.next(); let (scheme_id, file_id) = { - let namespace = namespace_opt.ok_or(Error::new(ENOENT))?; + let namespace = namespace_opt.ok_or(Error::new(ENODEV))?; let (scheme_id, scheme) = { let schemes = scheme::schemes(); - let (scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?; + let (scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENODEV))?; (scheme_id, scheme.clone()) }; let file_id = scheme.open(reference_opt.unwrap_or(b""), flags, uid, gid)?; @@ -146,10 +146,10 @@ pub fn mkdir(path: &[u8], mode: u16) -> Result<usize> { let namespace_opt = parts.next(); let reference_opt = parts.next(); - let namespace = namespace_opt.ok_or(Error::new(ENOENT))?; + let namespace = namespace_opt.ok_or(Error::new(ENODEV))?; let scheme = { let schemes = scheme::schemes(); - let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?; + let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENODEV))?; scheme.clone() }; scheme.mkdir(reference_opt.unwrap_or(b""), mode, uid, gid) @@ -168,10 +168,10 @@ pub fn rmdir(path: &[u8]) -> Result<usize> { let namespace_opt = parts.next(); let reference_opt = parts.next(); - let namespace = namespace_opt.ok_or(Error::new(ENOENT))?; + let namespace = namespace_opt.ok_or(Error::new(ENODEV))?; let scheme = { let schemes = scheme::schemes(); - let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?; + let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENODEV))?; scheme.clone() }; scheme.rmdir(reference_opt.unwrap_or(b""), uid, gid) @@ -190,10 +190,10 @@ pub fn unlink(path: &[u8]) -> Result<usize> { let namespace_opt = parts.next(); let reference_opt = parts.next(); - let namespace = namespace_opt.ok_or(Error::new(ENOENT))?; + let namespace = namespace_opt.ok_or(Error::new(ENODEV))?; let scheme = { let schemes = scheme::schemes(); - let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?; + let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENODEV))?; scheme.clone() }; scheme.unlink(reference_opt.unwrap_or(b""), uid, gid) @@ -222,7 +222,7 @@ pub fn close(fd: usize) -> Result<usize> { } /// Duplicate file descriptor -pub fn dup(fd: usize) -> Result<usize> { +pub fn dup(fd: usize, buf: &[u8]) -> Result<usize> { let file = { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; @@ -237,7 +237,7 @@ pub fn dup(fd: usize) -> Result<usize> { let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; scheme.clone() }; - scheme.dup(file.number)? + scheme.dup(file.number, buf)? }; let contexts = context::contexts(); diff --git a/syscall/mod.rs b/syscall/mod.rs index 8e1c190ebd49b75b882cf50bd2d51eac7948e9c3..2598cfa5a754d23d624b39adcf4831605e584bb1 100644 --- a/syscall/mod.rs +++ b/syscall/mod.rs @@ -39,7 +39,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize SYS_ARG_MSLICE => file_op_mut_slice(a, b, validate_slice_mut(c as *mut u8, d)?), _ => match a { SYS_CLOSE => close(b), - SYS_DUP => dup(b), + SYS_DUP => dup(b, validate_slice(c as *const u8, d)?), SYS_FEVENT => fevent(b, c), _ => file_op(a, b, c, d) } diff --git a/syscall/process.rs b/syscall/process.rs index 39dd822c78bc88b1e3380bb865c31224a74801cb..e3cd886cffd01b783622fe7d3993051723fc4480 100644 --- a/syscall/process.rs +++ b/syscall/process.rs @@ -227,7 +227,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; scheme.clone() }; - let result = scheme.dup(file.number); + let result = scheme.dup(file.number, &[]); result }; match result {