Skip to content
Snippets Groups Projects
Commit cf27b3a3 authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Fix close, add dup

parent 7a928a5f
No related branches found
No related tags found
No related merge requests found
...@@ -202,4 +202,23 @@ impl Context { ...@@ -202,4 +202,23 @@ impl Context {
None None
} }
} }
/// Get a file
pub fn get_file(&self, i: usize) -> Option<file::File> {
if i < self.files.len() {
self.files[i]
} else {
None
}
}
/// Remove a file
// TODO: adjust files vector to smaller size if possible
pub fn remove_file(&mut self, i: usize) -> Option<file::File> {
if i < self.files.len() {
self.files[i].take()
} else {
None
}
}
} }
...@@ -10,6 +10,10 @@ impl Scheme for DebugScheme { ...@@ -10,6 +10,10 @@ impl Scheme for DebugScheme {
Ok(0) Ok(0)
} }
fn dup(&mut self, _file: usize) -> Result<usize> {
Ok(0)
}
/// Read the file `number` into the `buffer` /// Read the file `number` into the `buffer`
/// ///
/// Returns the number of bytes read /// Returns the number of bytes read
......
...@@ -33,18 +33,33 @@ impl InitFsScheme { ...@@ -33,18 +33,33 @@ impl InitFsScheme {
impl Scheme for InitFsScheme { impl Scheme for InitFsScheme {
fn open(&mut self, path: &[u8], _flags: usize) -> Result<usize> { fn open(&mut self, path: &[u8], _flags: usize) -> Result<usize> {
let data = self.files.get(path).ok_or(Error::NoEntry)?; let data = self.files.get(path).ok_or(Error::NoEntry)?;
let id = self.next_id; let id = self.next_id;
self.next_id += 1; self.next_id += 1;
self.handles.insert(id, Handle { self.handles.insert(id, Handle {
data: data, data: data,
seek: 0 seek: 0
}); });
Ok(id)
}
fn dup(&mut self, file: usize) -> Result<usize> {
let (data, seek) = {
let handle = self.handles.get(&file).ok_or(Error::BadFile)?;
(handle.data, handle.seek)
};
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle {
data: data,
seek: seek
});
Ok(id) Ok(id)
} }
/// Read the file `number` into the `buffer`
///
/// Returns the number of bytes read
fn read(&mut self, file: usize, buffer: &mut [u8]) -> Result<usize> { fn read(&mut self, file: usize, buffer: &mut [u8]) -> Result<usize> {
let mut handle = self.handles.get_mut(&file).ok_or(Error::BadFile)?; let mut handle = self.handles.get_mut(&file).ok_or(Error::BadFile)?;
...@@ -58,14 +73,10 @@ impl Scheme for InitFsScheme { ...@@ -58,14 +73,10 @@ impl Scheme for InitFsScheme {
Ok(i) Ok(i)
} }
/// Write the `buffer` to the `file`
///
/// Returns the number of bytes written
fn write(&mut self, _file: usize, _buffer: &[u8]) -> Result<usize> { fn write(&mut self, _file: usize, _buffer: &[u8]) -> Result<usize> {
Err(Error::NotPermitted) Err(Error::NotPermitted)
} }
/// Close the file `number`
fn close(&mut self, file: usize) -> Result<()> { fn close(&mut self, file: usize) -> Result<()> {
self.handles.remove(&file).ok_or(Error::BadFile).and(Ok(())) self.handles.remove(&file).ok_or(Error::BadFile).and(Ok(()))
} }
......
...@@ -113,16 +113,21 @@ pub trait Scheme { ...@@ -113,16 +113,21 @@ pub trait Scheme {
/// Returns a file descriptor or an error /// Returns a file descriptor or an error
fn open(&mut self, path: &[u8], flags: usize) -> Result<usize>; fn open(&mut self, path: &[u8], flags: usize) -> Result<usize>;
/// Duplicate an open file descriptor
///
/// Returns a file descriptor or an error
fn dup(&mut self, file: usize) -> Result<usize>;
/// Read from some file descriptor into the `buffer` /// Read from some file descriptor into the `buffer`
/// ///
/// Returns the number of bytes read /// Returns the number of bytes read
fn read(&mut self, fd: usize, buffer: &mut [u8]) -> Result<usize>; fn read(&mut self, file: usize, buffer: &mut [u8]) -> Result<usize>;
/// Write the `buffer` to the file descriptor /// Write the `buffer` to the file descriptor
/// ///
/// Returns the number of bytes written /// Returns the number of bytes written
fn write(&mut self, fd: usize, buffer: &[u8]) -> Result<usize>; fn write(&mut self, file: usize, buffer: &[u8]) -> Result<usize>;
/// Close the file descriptor /// Close the file descriptor
fn close(&mut self, fd: usize) -> Result<()>; fn close(&mut self, file: usize) -> Result<()>;
} }
...@@ -11,7 +11,7 @@ pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> { ...@@ -11,7 +11,7 @@ pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> {
let contexts = context::contexts(); let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::NoProcess)?; let context_lock = contexts.current().ok_or(Error::NoProcess)?;
let context = context_lock.read(); let context = context_lock.read();
let file = context.files.get(fd).ok_or(Error::BadFile)?.ok_or(Error::BadFile)?; let file = context.get_file(fd).ok_or(Error::BadFile)?;
file file
}; };
...@@ -27,7 +27,7 @@ pub fn write(fd: usize, buf: &[u8]) -> Result<usize> { ...@@ -27,7 +27,7 @@ pub fn write(fd: usize, buf: &[u8]) -> Result<usize> {
let contexts = context::contexts(); let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::NoProcess)?; let context_lock = contexts.current().ok_or(Error::NoProcess)?;
let context = context_lock.read(); let context = context_lock.read();
let file = context.files.get(fd).ok_or(Error::BadFile)?.ok_or(Error::BadFile)?; let file = context.get_file(fd).ok_or(Error::BadFile)?;
file file
}; };
...@@ -65,8 +65,8 @@ pub fn close(fd: usize) -> Result<usize> { ...@@ -65,8 +65,8 @@ pub fn close(fd: usize) -> Result<usize> {
let file = { let file = {
let contexts = context::contexts(); let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::NoProcess)?; let context_lock = contexts.current().ok_or(Error::NoProcess)?;
let context = context_lock.read(); let mut context = context_lock.write();
let file = context.files.get(fd).ok_or(Error::BadFile)?.ok_or(Error::BadFile)?; let file = context.remove_file(fd).ok_or(Error::BadFile)?;
file file
}; };
...@@ -75,3 +75,19 @@ pub fn close(fd: usize) -> Result<usize> { ...@@ -75,3 +75,19 @@ pub fn close(fd: usize) -> Result<usize> {
let result = scheme_mutex.lock().close(file.number).and(Ok(0)); let result = scheme_mutex.lock().close(file.number).and(Ok(0));
result result
} }
/// Duplicate file descriptor
pub fn dup(fd: usize) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::NoProcess)?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::BadFile)?;
file
};
let schemes = scheme::schemes();
let scheme_mutex = schemes.get(file.scheme).ok_or(Error::BadFile)?;
let result = scheme_mutex.lock().dup(file.number);
result
}
...@@ -30,6 +30,8 @@ pub enum Call { ...@@ -30,6 +30,8 @@ pub enum Call {
Exec = 11, Exec = 11,
/// Get process ID /// Get process ID
GetPid = 20, GetPid = 20,
/// Duplicate file descriptor
Dup = 41,
/// Set process break /// Set process break
Brk = 45, Brk = 45,
/// Set process I/O privilege level /// Set process I/O privilege level
...@@ -52,6 +54,7 @@ impl Call { ...@@ -52,6 +54,7 @@ impl Call {
6 => Ok(Call::Close), 6 => Ok(Call::Close),
11 => Ok(Call::Exec), 11 => Ok(Call::Exec),
20 => Ok(Call::GetPid), 20 => Ok(Call::GetPid),
41 => Ok(Call::Dup),
45 => Ok(Call::Brk), 45 => Ok(Call::Brk),
110 => Ok(Call::Iopl), 110 => Ok(Call::Iopl),
120 => Ok(Call::Clone), 120 => Ok(Call::Clone),
...@@ -112,6 +115,7 @@ pub fn handle(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize) -> Re ...@@ -112,6 +115,7 @@ pub fn handle(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize) -> Re
Call::Close => close(b), Call::Close => close(b),
Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?), Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?),
Call::GetPid => getpid(), Call::GetPid => getpid(),
Call::Dup => dup(b),
Call::Brk => brk(b), Call::Brk => brk(b),
Call::Iopl => iopl(b), Call::Iopl => iopl(b),
Call::Clone => clone(b), Call::Clone => clone(b),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment