-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
598: add support of basic file descriptors r=mkroening a=stlankes To generalize the interface to the hardware, UNIX-like file descriptors is introduced. As long term solution, file descriptors are also used for sockets and other I/O interfaces. Co-authored-by: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
- Loading branch information
Showing
8 changed files
with
585 additions
and
335 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
use alloc::boxed::Box; | ||
use core::{isize, slice, str}; | ||
|
||
use crate::fd::{ | ||
uhyve_send, ObjectInterface, SysClose, SysLseek, SysRead, SysWrite, UHYVE_PORT_CLOSE, | ||
UHYVE_PORT_LSEEK, UHYVE_PORT_READ, UHYVE_PORT_WRITE, | ||
}; | ||
use crate::syscalls::fs::{self, PosixFile, SeekWhence}; | ||
|
||
const SEEK_SET: i32 = 0; | ||
const SEEK_CUR: i32 = 1; | ||
const SEEK_END: i32 = 2; | ||
|
||
impl TryFrom<i32> for SeekWhence { | ||
type Error = &'static str; | ||
|
||
fn try_from(value: i32) -> Result<Self, Self::Error> { | ||
match value { | ||
SEEK_CUR => Ok(SeekWhence::Cur), | ||
SEEK_SET => Ok(SeekWhence::Set), | ||
SEEK_END => Ok(SeekWhence::End), | ||
_ => Err("Got invalid seek whence parameter!"), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct UhyveFile(i32); | ||
|
||
impl UhyveFile { | ||
pub fn new(fd: i32) -> Self { | ||
Self(fd) | ||
} | ||
} | ||
|
||
impl ObjectInterface for UhyveFile { | ||
fn close(&self) -> i32 { | ||
let mut sysclose = SysClose::new(self.0); | ||
uhyve_send(UHYVE_PORT_CLOSE, &mut sysclose); | ||
|
||
sysclose.ret | ||
} | ||
|
||
fn write(&self, buf: *const u8, len: usize) -> isize { | ||
let mut syswrite = SysWrite::new(self.0, buf, len); | ||
uhyve_send(UHYVE_PORT_WRITE, &mut syswrite); | ||
|
||
syswrite.len as isize | ||
} | ||
|
||
fn read(&self, buf: *mut u8, len: usize) -> isize { | ||
let mut sysread = SysRead::new(self.0, buf, len); | ||
uhyve_send(UHYVE_PORT_READ, &mut sysread); | ||
|
||
sysread.ret | ||
} | ||
|
||
fn lseek(&self, offset: isize, whence: i32) -> isize { | ||
let mut syslseek = SysLseek::new(self.0, offset, whence); | ||
uhyve_send(UHYVE_PORT_LSEEK, &mut syslseek); | ||
|
||
syslseek.offset | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct GenericFile(u64); | ||
|
||
impl GenericFile { | ||
pub fn new(fd: u64) -> Self { | ||
Self(fd) | ||
} | ||
} | ||
|
||
impl ObjectInterface for GenericFile { | ||
fn close(&self) -> i32 { | ||
let mut fs = fs::FILESYSTEM.lock(); | ||
fs.close(self.0); | ||
0 | ||
} | ||
|
||
fn write(&self, buf: *const u8, len: usize) -> isize { | ||
assert!(len <= isize::MAX as usize); | ||
let buf = unsafe { slice::from_raw_parts(buf, len) }; | ||
|
||
// Normal file | ||
let mut written_bytes = 0; | ||
let mut fs = fs::FILESYSTEM.lock(); | ||
fs.fd_op(self.0, |file: &mut Box<dyn PosixFile + Send>| { | ||
written_bytes = file.write(buf).unwrap(); // TODO: might fail | ||
}); | ||
debug!("Write done! {}", written_bytes); | ||
written_bytes as isize | ||
} | ||
|
||
fn read(&self, buf: *mut u8, len: usize) -> isize { | ||
debug!("Read! {}, {}", self.0, len); | ||
|
||
let mut fs = fs::FILESYSTEM.lock(); | ||
let mut read_bytes = 0; | ||
fs.fd_op(self.0, |file: &mut Box<dyn PosixFile + Send>| { | ||
let dat = file.read(len as u32).unwrap(); // TODO: might fail | ||
|
||
read_bytes = dat.len(); | ||
unsafe { | ||
core::slice::from_raw_parts_mut(buf, read_bytes).copy_from_slice(&dat); | ||
} | ||
}); | ||
|
||
read_bytes as isize | ||
} | ||
|
||
fn lseek(&self, offset: isize, whence: i32) -> isize { | ||
debug!("lseek! {}, {}, {}", self.0, offset, whence); | ||
|
||
let mut fs = fs::FILESYSTEM.lock(); | ||
let mut ret = 0; | ||
fs.fd_op(self.0, |file: &mut Box<dyn PosixFile + Send>| { | ||
ret = file.lseek(offset, whence.try_into().unwrap()).unwrap(); // TODO: might fail | ||
}); | ||
|
||
ret as isize | ||
} | ||
} |
Oops, something went wrong.