Skip to content

Commit

Permalink
Merge #598
Browse files Browse the repository at this point in the history
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
bors[bot] and stlankes authored Dec 3, 2022
2 parents d0cb20e + 66fe26b commit 7c5642f
Show file tree
Hide file tree
Showing 8 changed files with 585 additions and 335 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

124 changes: 124 additions & 0 deletions src/fd/file.rs
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
}
}
Loading

0 comments on commit 7c5642f

Please sign in to comment.