feat(storage): scoped grants (subtree, ro/rw), narrow-only, release revokes all holders; IPC KEEP_DELEGATE opt-in; shell cd/pwd, programs get ro cwd
This commit is contained in:
@@ -24,6 +24,8 @@ pub enum FsError {
|
||||
ReadOnly,
|
||||
/// A path longer than the server accepts.
|
||||
PathTooLong,
|
||||
/// Outside this connection's scope, or beyond its rights.
|
||||
Denied,
|
||||
/// The server refused, or the call itself failed.
|
||||
Failed,
|
||||
}
|
||||
@@ -76,6 +78,7 @@ impl Storage {
|
||||
match r[0] {
|
||||
reply::NOT_FOUND => Err(FsError::NotFound),
|
||||
reply::READ_ONLY => Err(FsError::ReadOnly),
|
||||
reply::DENIED => Err(FsError::Denied),
|
||||
reply::ERROR | reply::NOT_ATTACHED => Err(FsError::Failed),
|
||||
_ => Ok(r),
|
||||
}
|
||||
@@ -100,6 +103,20 @@ impl Storage {
|
||||
self.expect([opcode, len, 0, 0], tag)
|
||||
}
|
||||
|
||||
/// A storage capability to `path` inside this connection's scope,
|
||||
/// writable only if `write` and this one is. It can be passed on;
|
||||
/// `release` takes it back.
|
||||
pub fn grant(&mut self, path: &[u8], write: bool) -> Result<CapSlot> {
|
||||
let len = self.put_path(path)?;
|
||||
let reply = syscall::call(self.ep, [op::GRANT, len, usize::from(write), 0], None)
|
||||
.map_err(|_| FsError::Failed)?;
|
||||
match (reply.words()[0], reply) {
|
||||
(reply::GRANTED, syscall::Received::Message { cap: Some(cap), .. }) => Ok(cap),
|
||||
(reply::DENIED, _) => Err(FsError::Denied),
|
||||
_ => Err(FsError::Failed),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open(&mut self, path: &[u8]) -> Result<FileHandle> {
|
||||
self.with_path(op::OPEN, path, reply::HANDLE).map(|h| FileHandle(h as u16))
|
||||
}
|
||||
@@ -181,3 +198,13 @@ impl Storage {
|
||||
Ok(count)
|
||||
}
|
||||
}
|
||||
|
||||
/// Takes back `grant` and everything granted from it, from every holder;
|
||||
/// the slot is empty afterwards.
|
||||
pub fn release(grant: CapSlot) -> Result<()> {
|
||||
match syscall::request(grant, [op::RELEASE, 0, 0, 0]) {
|
||||
Ok([reply::OK, ..]) => Ok(()),
|
||||
Ok([reply::DENIED, ..]) => Err(FsError::Denied),
|
||||
_ => Err(FsError::Failed),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user