-
Notifications
You must be signed in to change notification settings - Fork 824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for WASI opening Unix special files #1566
Changes from 5 commits
88c1f6d
6327fa6
ed74a83
ed0acc2
0d16267
e4e41f4
723dd4e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -819,6 +819,56 @@ impl WasiFs { | |||||
relative_path: link_value, | ||||||
} | ||||||
} else { | ||||||
#[cfg(unix)] | ||||||
{ | ||||||
use std::os::unix::fs::FileTypeExt; | ||||||
let file_type: __wasi_filetype_t = if file_type.is_char_device() | ||||||
{ | ||||||
__WASI_FILETYPE_CHARACTER_DEVICE | ||||||
} else if file_type.is_block_device() { | ||||||
__WASI_FILETYPE_BLOCK_DEVICE | ||||||
} else if file_type.is_fifo() { | ||||||
// FIFO doesn't seem to fit any other type, so unknown | ||||||
__WASI_FILETYPE_UNKNOWN | ||||||
} else if file_type.is_socket() { | ||||||
// TODO: how do we know if it's a `__WASI_FILETYPE_SOCKET_STREAM` or | ||||||
// a `__WASI_FILETYPE_SOCKET_DGRAM`? | ||||||
__WASI_FILETYPE_SOCKET_STREAM | ||||||
} else { | ||||||
unimplemented!("state::get_inode_at_path unknown file type: not file, directory, symlink, char device, block device, fifo, or socket"); | ||||||
}; | ||||||
|
||||||
let kind = Kind::File { | ||||||
handle: None, | ||||||
path: file.clone(), | ||||||
fd: None, | ||||||
}; | ||||||
let new_inode = self.create_inode_with_stat( | ||||||
kind, | ||||||
false, | ||||||
file.to_string_lossy().to_string(), | ||||||
__wasi_filestat_t { | ||||||
st_filetype: file_type, | ||||||
..__wasi_filestat_t::default() | ||||||
}, | ||||||
); | ||||||
if let Kind::Dir { | ||||||
ref mut entries, .. | ||||||
} = &mut self.inodes[cur_inode].kind | ||||||
{ | ||||||
entries.insert( | ||||||
component.as_os_str().to_string_lossy().to_string(), | ||||||
new_inode, | ||||||
); | ||||||
} else { | ||||||
unreachable!( | ||||||
"Attempted to insert special device into non-directory" | ||||||
); | ||||||
} | ||||||
// perhaps just continue with symlink resolution and return at the end | ||||||
return Ok(new_inode); | ||||||
} | ||||||
#[cfg(not(unix))] | ||||||
unimplemented!("state::get_inode_at_path unknown file type: not file, directory, or symlink"); | ||||||
}; | ||||||
|
||||||
|
@@ -1178,15 +1228,8 @@ impl WasiFs { | |||||
is_preopened: bool, | ||||||
name: String, | ||||||
) -> Result<Inode, __wasi_errno_t> { | ||||||
let mut stat = self.get_stat_for_kind(&kind).ok_or(__WASI_EIO)?; | ||||||
stat.st_ino = self.get_next_inode_index(); | ||||||
|
||||||
Ok(self.inodes.insert(InodeVal { | ||||||
stat, | ||||||
is_preopened, | ||||||
name, | ||||||
kind, | ||||||
})) | ||||||
let stat = self.get_stat_for_kind(&kind).ok_or(__WASI_EIO)?; | ||||||
Ok(self.create_inode_with_stat(kind, is_preopened, name, stat)) | ||||||
} | ||||||
|
||||||
/// creates an inode and inserts it given a Kind, does not assume the file exists to | ||||||
|
@@ -1196,7 +1239,18 @@ impl WasiFs { | |||||
is_preopened: bool, | ||||||
name: String, | ||||||
) -> Inode { | ||||||
let mut stat = __wasi_filestat_t::default(); | ||||||
let stat = __wasi_filestat_t::default(); | ||||||
self.create_inode_with_stat(kind, is_preopened, name, stat) | ||||||
} | ||||||
|
||||||
/// creates an inode with the given filestat and insert it. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Rule of thumb is that either it's a sentence which starts with a capital and ends with a period (or question or exclamation mark) or it's a sentence fragment and has neither. |
||||||
pub(crate) fn create_inode_with_stat( | ||||||
&mut self, | ||||||
kind: Kind, | ||||||
is_preopened: bool, | ||||||
name: String, | ||||||
mut stat: __wasi_filestat_t, | ||||||
) -> Inode { | ||||||
stat.st_ino = self.get_next_inode_index(); | ||||||
|
||||||
self.inodes.insert(InodeVal { | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,3 +25,8 @@ And here's an example of how to generate these tests: | |
cargo run -- -as # set up the toolchains for all targets | ||
cargo run -- -ag # generate the WASI tests for all targets | ||
``` | ||
|
||
## Updating in Wasmer | ||
|
||
Run | ||
`git subtree pull --prefix tests/wasi-wast [email protected]:wasmerio/wasi-tests master --squash` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
(wasi_test "unix_open_special_files.wasm" | ||
(map_dirs "/dev:/dev") | ||
(assert_return (i64.const 0)) | ||
(assert_stdout "13\n") | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. newline please! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// WASI: | ||
// mapdir: /dev:/dev | ||
|
||
use std::fs; | ||
use std::io::Write; | ||
|
||
fn main() { | ||
let mut f = fs::OpenOptions::new() | ||
.write(true) | ||
.open("/dev/null") | ||
.unwrap(); | ||
let result = f.write(b"hello, world!").unwrap(); | ||
println!("{}", result); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
(wasi_test "unix_open_special_files.wasm" | ||
(map_dirs "/dev:/dev") | ||
(assert_return (i64.const 0)) | ||
(assert_stdout "13\n") | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. newline please There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these are generated files, I can regenerate them all but it'd probably be best to do that separately |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a comment, I'm not sure whether this is reachable or not? If the place in the wasi-fs where the host path is being injected is controlled by the user then it seems like it should be a full Err? Otherwise, if this is part of mirroring the host paths then this is fine as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be reachable without unsafe I believe: it's not possible to put files in the virtual root right now, they have to come from a preopened directory and that directory will be mounted at
/
.