Skip to content

Commit

Permalink
Merge pull request #1566 from wasmerio/feature/wasi-unix-special-files
Browse files Browse the repository at this point in the history
Add support for WASI opening Unix special files
  • Loading branch information
MarkMcCaskey authored Aug 31, 2020
2 parents fb49acd + 723dd4e commit 686ea59
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Changelog

## **[Unreleased]**
- [#1566](https://github.com/wasmerio/wasmer/pull/1566) Add support for opening special Unix files to the WASI FS

## TODO: 1.0.0-alpha1.0
- Wasmer refactor lands

## TODO: 17...

- [#1554](https://github.com/wasmerio/wasmer/pull/1554) Update supported stable Rust version to 1.45.2.
- [#1552](https://github.com/wasmerio/wasmer/pull/1552) Disable `sigint` handler by default.
Expand Down
13 changes: 11 additions & 2 deletions Cargo.lock

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

76 changes: 65 additions & 11 deletions lib/wasi/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
};

Expand Down Expand Up @@ -1178,25 +1228,29 @@ 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
/// Creates an inode and inserts it given a Kind, does not assume the file exists.
pub(crate) fn create_inode_with_default_stat(
&mut self,
kind: Kind,
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 inserts it.
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 {
Expand Down
4 changes: 4 additions & 0 deletions tests/ignores.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,7 @@ wasitests::unstable::file_metadata on windows
wasitests::unstable::fseek on windows
wasitests::unstable::path_link on windows
wasitests::unstable::path_symlink on windows

# This test is meant to only run on Unix
wasitests::unstable::unix_open_special_files on windows
wasitests::snapshot1::unix_open_special_files on windows
5 changes: 5 additions & 0 deletions tests/wasi-wast/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 git@github.com:wasmerio/wasi-tests master --squash`
Binary file not shown.
5 changes: 5 additions & 0 deletions tests/wasi-wast/wasi/snapshot1/unix_open_special_files.wast
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")
)
14 changes: 14 additions & 0 deletions tests/wasi-wast/wasi/tests/unix_open_special_files.rs
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);
}
Binary file not shown.
5 changes: 5 additions & 0 deletions tests/wasi-wast/wasi/unstable/unix_open_special_files.wast
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")
)

0 comments on commit 686ea59

Please sign in to comment.