mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 16:20:49 +00:00
implement happy path of fd_open
This commit is contained in:
parent
f70b75e552
commit
b80dd072a1
@ -31,7 +31,7 @@ pub enum Kind {
|
||||
Dir {
|
||||
handle: File,
|
||||
/// The entries of a directory are lazily filled.
|
||||
entries: Vec<Inode>,
|
||||
entries: HashMap<String, Inode>,
|
||||
},
|
||||
Symlink {
|
||||
forwarded: Inode,
|
||||
@ -123,7 +123,7 @@ impl WasiFs {
|
||||
FileType::File => Kind::File { handle: file },
|
||||
FileType::Dir => Kind::Dir {
|
||||
handle: file,
|
||||
entries: Vec::new(),
|
||||
entries: HashMap::new(),
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -240,6 +240,28 @@ impl WasiFs {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn create_fd(
|
||||
&mut self,
|
||||
rights: __wasi_rights_t,
|
||||
rights_inheriting: __wasi_rights_t,
|
||||
flags: __wasi_fdflags_t,
|
||||
inode: Inode,
|
||||
) -> Result<u32, __wasi_errno_t> {
|
||||
let idx = self.next_fd.get();
|
||||
self.next_fd.set(idx + 1);
|
||||
self.fd_map.insert(
|
||||
idx,
|
||||
Fd {
|
||||
rights,
|
||||
rights_inheriting,
|
||||
flags,
|
||||
offset: 0,
|
||||
inode,
|
||||
},
|
||||
);
|
||||
Ok(idx)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WasiState<'a> {
|
||||
|
@ -1076,22 +1076,102 @@ pub fn path_open(
|
||||
}
|
||||
|
||||
// check for __WASI_RIGHT_PATH_OPEN somewhere, probably via dirfd
|
||||
let fd_cell = wasi_try!(fd.deref(memory));
|
||||
let path_cells = wasi_try!(path.deref(memory, 0, path_len));
|
||||
let state = get_wasi_state(ctx);
|
||||
|
||||
if let (Ok(fd_cell), Ok(path_cell)) = (fd.deref(memory), path.deref(memory, 0, path_len)) {
|
||||
// o_flags:
|
||||
// - __WASI_O_FLAG_CREAT (create if it does not exist)
|
||||
// - __WASI_O_DIRECTORY (fail if not dir)
|
||||
// - __WASI_O_EXCL (fail if file exists)
|
||||
// - __WASI_O_TRUNC (truncate size to 0)
|
||||
if (o_flags & __WASI_O_DIRECTORY) != 0 {
|
||||
// fail if fd is not a dir
|
||||
// need to check and be able to clean up
|
||||
}
|
||||
// o_flags:
|
||||
// - __WASI_O_FLAG_CREAT (create if it does not exist)
|
||||
// - __WASI_O_DIRECTORY (fail if not dir)
|
||||
// - __WASI_O_EXCL (fail if file exists)
|
||||
// - __WASI_O_TRUNC (truncate size to 0)
|
||||
|
||||
unimplemented!();
|
||||
} else {
|
||||
__WASI_EFAULT
|
||||
let working_dir = wasi_try!(state.fs.fd_map.get(&dirfd).ok_or(__WASI_EBADF));
|
||||
|
||||
// ASSUMPTION: open rights cascade down
|
||||
if !has_rights(working_dir.rights, __WASI_RIGHT_PATH_OPEN) {
|
||||
return __WASI_EACCES;
|
||||
}
|
||||
|
||||
let path_vec =
|
||||
wasi_try!(
|
||||
::std::str::from_utf8(unsafe { &*(path_cells as *const [_] as *const [u8]) })
|
||||
.map_err(|_| __WASI_EINVAL)
|
||||
)
|
||||
.split('/')
|
||||
.map(|str| str.to_string())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
if path_vec.is_empty() {
|
||||
return __WASI_EINVAL;
|
||||
}
|
||||
|
||||
let working_dir_inode = &mut state.fs.inodes[working_dir.inode];
|
||||
|
||||
let mut cur_dir = working_dir;
|
||||
|
||||
// TODO: refactor single path segment logic out and do traversing before
|
||||
// as necessary
|
||||
let out_fd = if path_vec.len() == 1 {
|
||||
// just the file or dir
|
||||
if let Kind::Dir { entries, .. } = &mut working_dir_inode.kind {
|
||||
if let Some(child) = entries.get(&path_vec[0]).cloned() {
|
||||
let child_inode_val = &state.fs.inodes[child];
|
||||
// early return based on flags
|
||||
if o_flags & __WASI_O_EXCL != 0 {
|
||||
return __WASI_EEXIST;
|
||||
}
|
||||
if o_flags & __WASI_O_DIRECTORY != 0 {
|
||||
match &child_inode_val.kind {
|
||||
Kind::Dir { .. } => (),
|
||||
Kind::Symlink { .. } => unimplemented!(),
|
||||
_ => return __WASI_ENOTDIR,
|
||||
}
|
||||
}
|
||||
// do logic on child
|
||||
wasi_try!(state
|
||||
.fs
|
||||
.create_fd(fs_rights_base, fs_rights_inheriting, fs_flags, child))
|
||||
} else {
|
||||
// entry does not exist in parent directory
|
||||
// check to see if we should create it
|
||||
if o_flags & __WASI_O_CREAT != 0 {
|
||||
// insert in to directory and set values
|
||||
//entries.insert(path_segment[0], )
|
||||
unimplemented!()
|
||||
} else {
|
||||
// no entry and can't create it
|
||||
return __WASI_ENOENT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// working_dir is not a directory
|
||||
return __WASI_ENOTDIR;
|
||||
}
|
||||
} else {
|
||||
// traverse the pieces of the path
|
||||
// TODO: lots of testing on this
|
||||
for path_segment in &path_vec[..(path_vec.len() - 1)] {
|
||||
match &working_dir_inode.kind {
|
||||
Kind::Dir { entries, .. } => {
|
||||
if let Some(child) = entries.get(path_segment) {
|
||||
unimplemented!();
|
||||
} else {
|
||||
// Is __WASI_O_FLAG_CREAT recursive?
|
||||
// ASSUMPTION: it's not
|
||||
return __WASI_EINVAL;
|
||||
}
|
||||
}
|
||||
Kind::Symlink { .. } => unimplemented!(),
|
||||
_ => return __WASI_ENOTDIR,
|
||||
}
|
||||
}
|
||||
unimplemented!()
|
||||
};
|
||||
|
||||
fd_cell.set(out_fd);
|
||||
|
||||
__WASI_ESUCCESS
|
||||
}
|
||||
|
||||
pub fn path_readlink(
|
||||
|
Loading…
x
Reference in New Issue
Block a user