Skip to content

Commit

Permalink
Stop returning NOTCAPABLE errors from WASI calls.
Browse files Browse the repository at this point in the history
`ENOTCAPABLE` was an error code that is used as part of the rights
system, from CloudABI. There is a set of flags associated with each file
descriptor listing which operations can be performed with the file
descriptor, and if an attempt is made to perform an operation with a
file descriptor that isn't permitted by its rights flags, it fails with
`ENOTCAPABLE`.

WASI is removing the rights system. For example, WebAssembly/wasi-libc#294
removed support for translating `ENOTCAPABLE` into POSIX error codes, on
the assumption that engines should stop using it.

So as another step to migrating away from the rights system, remove uses
of the `ENOTCAPABLE` error.
  • Loading branch information
sunfishcode committed Aug 9, 2022
1 parent 4d2a2cf commit 7138042
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ unsafe fn try_read_file(dir_fd: wasi::Fd) {
wasi::fd_read(fd, &[iovec])
.expect_err("reading bytes from file should fail")
.raw_error(),
wasi::ERRNO_NOTCAPABLE
wasi::ERRNO_BADF
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ unsafe fn test_truncation_rights(dir_fd: wasi::Fd) {
wasi::path_open(dir_fd, 0, "file", wasi::OFLAGS_TRUNC, 0, 0, 0)
.expect_err("truncating a file without path_filestat_set_size right")
.raw_error(),
wasi::ERRNO_NOTCAPABLE
wasi::ERRNO_PERM
);
}

Expand Down
15 changes: 12 additions & 3 deletions crates/wasi-common/src/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,24 @@ impl DirEntry {
if self.caps.contains(caps) {
Ok(())
} else {
Err(Error::not_capable().context(format!("desired {:?}, has {:?}", caps, self.caps,)))
let missing = caps & !self.caps;
if missing.intersects(DirCaps::READDIR) {
Err(Error::not_dir()
.context(format!("desired rights {:?}, has {:?}", caps, self.caps)))
} else {
Err(Error::perm()
.context(format!("desired rights {:?}, has {:?}", caps, self.caps)))
}
}
}
pub fn capable_of_file(&self, caps: FileCaps) -> Result<(), Error> {
if self.file_caps.contains(caps) {
Ok(())
} else {
Err(Error::not_capable()
.context(format!("desired {:?}, has {:?}", caps, self.file_caps)))
Err(Error::perm().context(format!(
"desired rights {:?}, has {:?}",
caps, self.file_caps
)))
}
}
pub fn drop_caps_to(&mut self, caps: DirCaps, file_caps: FileCaps) -> Result<(), Error> {
Expand Down
9 changes: 6 additions & 3 deletions crates/wasi-common/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ pub enum ErrorKind {
/// Errno::Spipe: Invalid seek
#[error("Spipe: Invalid seek")]
Spipe,
/// Errno::Perm: Permission denied
#[error("Permission denied")]
Perm,
/// Errno::NotCapable: Not capable
#[error("Not capable")]
NotCapable,
Expand All @@ -92,7 +95,7 @@ pub trait ErrorExt {
fn overflow() -> Self;
fn range() -> Self;
fn seek_pipe() -> Self;
fn not_capable() -> Self;
fn perm() -> Self;
}

impl ErrorExt for Error {
Expand Down Expand Up @@ -138,7 +141,7 @@ impl ErrorExt for Error {
fn seek_pipe() -> Self {
ErrorKind::Spipe.into()
}
fn not_capable() -> Self {
ErrorKind::NotCapable.into()
fn perm() -> Self {
ErrorKind::Perm.into()
}
}
12 changes: 11 additions & 1 deletion crates/wasi-common/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,17 @@ impl FileEntry {
if self.caps.contains(caps) {
Ok(())
} else {
Err(Error::not_capable().context(format!("desired {:?}, has {:?}", caps, self.caps,)))
let missing = caps & !self.caps;
if missing.intersects(FileCaps::READ | FileCaps::WRITE) {
// `EBADF` is a little surprising here because it's also used
// for unknown-file-descriptor errors, but it's what POSIX uses
// in this situation.
Err(Error::badf()
.context(format!("desired rights {:?}, has {:?}", caps, self.caps)))
} else {
Err(Error::perm()
.context(format!("desired rights {:?}, has {:?}", caps, self.caps)))
}
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/wasi-common/src/snapshots/preview_1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl From<ErrorKind> for types::Errno {
ErrorKind::Range => Errno::Range,
ErrorKind::Spipe => Errno::Spipe,
ErrorKind::NotCapable => Errno::Notcapable,
ErrorKind::Perm => Errno::Perm,
}
}
}
Expand Down

0 comments on commit 7138042

Please sign in to comment.