diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 76fcfd6f9c09dde85de91a51205ec60ead9ddcff..1de6cedca86cc1ced89451db9534bafe865b18f1 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -240,8 +240,7 @@ pub fn close(fd: FileHandle) -> Result<usize> { file.close(fd) } -/// Duplicate file descriptor -pub fn dup(fd: FileHandle, buf: &[u8]) -> Result<FileHandle> { +fn duplicate_file(fd: FileHandle, buf: &[u8]) -> Result<FileDescriptor> { let file = { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; @@ -251,15 +250,11 @@ pub fn dup(fd: FileHandle, buf: &[u8]) -> Result<FileHandle> { }; if buf.is_empty() { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - - context.add_file(FileDescriptor { + Ok(FileDescriptor { description: Arc::clone(&file.description), event: None, cloexec: false, - }).ok_or(Error::new(EMFILE)) + }) } else { let description = file.description.read(); @@ -273,11 +268,7 @@ pub fn dup(fd: FileHandle, buf: &[u8]) -> Result<FileHandle> { scheme.dup(description.number, buf)? }; - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - - context.add_file(FileDescriptor { + Ok(FileDescriptor { description: Arc::new(RwLock::new(FileDescription { scheme: description.scheme, number: new_id, @@ -285,61 +276,34 @@ pub fn dup(fd: FileHandle, buf: &[u8]) -> Result<FileHandle> { })), event: None, cloexec: false, - }).ok_or(Error::new(EMFILE)) + }) } } +/// Duplicate file descriptor +pub fn dup(fd: FileHandle, buf: &[u8]) -> Result<FileHandle> { + let new_file = duplicate_file(fd, buf)?; + + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + + context.add_file(new_file).ok_or(Error::new(EMFILE)) +} + /// Duplicate file descriptor, replacing another pub fn dup2(fd: FileHandle, new_fd: FileHandle, buf: &[u8]) -> Result<FileHandle> { if fd == new_fd { Ok(new_fd) } else { let _ = close(new_fd); + let new_file = duplicate_file(fd, buf)?; - let file = { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - context.get_file(fd).ok_or(Error::new(EBADF))? - }; - - if buf.is_empty() { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - - context.insert_file(new_fd, FileDescriptor { - description: Arc::clone(&file.description), - event: None, - cloexec: false, - }).ok_or(Error::new(EBADF)) - } else { - let description = file.description.read(); - - let new_id = { - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(description.scheme).ok_or(Error::new(EBADF))?; - - scheme.clone() - }; - scheme.dup(description.number, buf)? - }; + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - - context.insert_file(new_fd, FileDescriptor { - description: Arc::new(RwLock::new(FileDescription { - scheme: description.scheme, - number: new_id, - flags: description.flags, - })), - event: None, - cloexec: false, - }).ok_or(Error::new(EMFILE)) - } + context.insert_file(new_fd, new_file).ok_or(Error::new(EMFILE)) } }