Skip to content
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

Clean up some internal WASI code #2325

Merged
merged 1 commit into from
May 20, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 41 additions & 17 deletions lib/wasi/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ impl WasiFs {
symlink_count += 1;
Kind::Symlink {
base_po_dir: pre_open_dir_fd,
path_to_symlink: relative_path,
path_to_symlink: relative_path.to_owned(),
relative_path: link_value,
}
} else {
Expand Down Expand Up @@ -958,15 +958,37 @@ impl WasiFs {
Ok(cur_inode)
}

/// Splits a path into the preopened directory that has the largest prefix of
/// the given path, if such a preopened directory exists, and the rest of the path.
fn path_into_pre_open_and_relative_path(
/// Finds the preopened directory that is the "best match" for the given path and
/// returns a path relative to this preopened directory.
///
/// The "best match" is the preopened directory that has the longest prefix of the
/// given path. For example, given preopened directories [`a`, `a/b`, `a/c`] and
/// the path `a/b/c/file`, we will return the fd corresponding to the preopened
/// directory, `a/b` and the relative path `c/file`.
///
/// In the case of a tie, the later preopened fd is preferred.
fn path_into_pre_open_and_relative_path<'path>(
&self,
path: &Path,
) -> Result<(__wasi_fd_t, PathBuf), __wasi_errno_t> {
let mut max_prefix_len = 0;
let mut max_stripped_path = None;
let mut max_po_fd = None;
path: &'path Path,
) -> Result<(__wasi_fd_t, &'path Path), __wasi_errno_t> {
enum BaseFdAndRelPath<'a> {
None,
BestMatch {
fd: __wasi_fd_t,
rel_path: &'a Path,
max_seen: usize,
},
}

impl<'a> BaseFdAndRelPath<'a> {
const fn max_seen(&self) -> usize {
match self {
Self::None => 0,
Self::BestMatch { max_seen, .. } => *max_seen,
}
}
}
let mut res = BaseFdAndRelPath::None;
// for each preopened directory
for po_fd in &self.preopen_fds {
let po_inode = self.fd_map[po_fd].inode;
Expand All @@ -981,17 +1003,19 @@ impl WasiFs {
let new_prefix_len = po_path.as_os_str().len();
// we use >= to favor later preopens because we iterate in order
// whereas WASI libc iterates in reverse to get this behavior.
if new_prefix_len >= max_prefix_len {
max_prefix_len = new_prefix_len;
max_stripped_path = Some(stripped_path);
max_po_fd = Some(*po_fd);
if new_prefix_len >= res.max_seen() {
res = BaseFdAndRelPath::BestMatch {
fd: *po_fd,
rel_path: stripped_path,
max_seen: new_prefix_len,
};
}
}
}
if max_prefix_len == 0 {
Err(__WASI_EINVAL) // this may not make sense depending on where it's called
} else {
Ok((max_po_fd.unwrap(), max_stripped_path.unwrap().to_owned()))
match res {
// this error may not make sense depending on where it's called
BaseFdAndRelPath::None => Err(__WASI_EINVAL),
BaseFdAndRelPath::BestMatch { fd, rel_path, .. } => Ok((fd, rel_path)),
}
}

Expand Down