Browse Source

Path symlink follow (#1284)

* Fix the tests for correctly following symlinks.

* Correctly follow symlinks in path_link.
pull/1370/head
Marcin Mielniczuk 5 years ago
committed by GitHub
parent
commit
c50c24e699
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      crates/test-programs/wasi-tests/src/bin/path_link.rs
  2. 4
      crates/wasi-common/src/hostcalls_impl/fs.rs
  3. 13
      crates/wasi-common/src/sys/unix/hostcalls_impl/fs.rs
  4. 6
      crates/wasi-common/src/sys/windows/hostcalls_impl/fs.rs

24
crates/test-programs/wasi-tests/src/bin/path_link.rs

@ -152,26 +152,19 @@ unsafe fn test_path_link(dir_fd: wasi::Fd) {
// Create a link to a dangling symlink
wasi::path_symlink("target", dir_fd, "symlink").expect("creating a dangling symlink");
assert_eq!(
wasi::path_link(dir_fd, 0, "symlink", dir_fd, "link")
.expect_err("creating a link to a dangling symlink should fail")
.raw_error(),
wasi::ERRNO_NOENT,
"errno should be ERRNO_NOENT"
);
// This should succeed, because we're not following symlinks
wasi::path_link(dir_fd, 0, "symlink", dir_fd, "link")
.expect("creating a link to a dangling symlink should succeed");
wasi::path_unlink_file(dir_fd, "symlink").expect("removing a symlink");
wasi::path_unlink_file(dir_fd, "link").expect("removing a hardlink");
// Create a link to a symlink loop
wasi::path_symlink("symlink", dir_fd, "symlink").expect("creating a symlink loop");
assert_eq!(
wasi::path_link(dir_fd, 0, "symlink", dir_fd, "link")
.expect_err("creating a link to a symlink loop")
.raw_error(),
wasi::ERRNO_LOOP,
"errno should be ERRNO_LOOP"
);
wasi::path_link(dir_fd, 0, "symlink", dir_fd, "link")
.expect("creating a link to a symlink loop should succeed");
wasi::path_unlink_file(dir_fd, "symlink").expect("removing a symlink");
wasi::path_unlink_file(dir_fd, "link").expect("removing a hardlink");
// Create a link where target is a dangling symlink
wasi::path_symlink("target", dir_fd, "symlink").expect("creating a dangling symlink");
@ -203,6 +196,7 @@ unsafe fn test_path_link(dir_fd: wasi::Fd) {
// Create a link where target is a dangling symlink following symlinks
wasi::path_symlink("target", dir_fd, "symlink").expect("creating a dangling symlink");
// If we do follow symlinks, this should fail
assert_eq!(
wasi::path_link(
dir_fd,
@ -211,7 +205,7 @@ unsafe fn test_path_link(dir_fd: wasi::Fd) {
dir_fd,
"link",
)
.expect_err("creating a link where target is a dangling symlink following symlinks")
.expect_err("creating a link to a dangling symlink following symlinks should fail")
.raw_error(),
wasi::ERRNO_NOENT,
"errno should be ERRNO_NOENT"

4
crates/wasi-common/src/hostcalls_impl/fs.rs

@ -650,7 +650,9 @@ pub(crate) unsafe fn path_link(
false,
)?;
hostcalls_impl::path_link(resolved_old, resolved_new)
let follow_symlinks = old_flags & wasi::__WASI_LOOKUPFLAGS_SYMLINK_FOLLOW != 0;
hostcalls_impl::path_link(resolved_old, resolved_new, follow_symlinks)
}
pub(crate) unsafe fn path_open(

13
crates/wasi-common/src/sys/unix/hostcalls_impl/fs.rs

@ -71,15 +71,24 @@ pub(crate) fn path_create_directory(base: &File, path: &str) -> WasiResult<()> {
unsafe { mkdirat(base.as_raw_fd(), path, Mode::from_bits_truncate(0o777)) }.map_err(Into::into)
}
pub(crate) fn path_link(resolved_old: PathGet, resolved_new: PathGet) -> WasiResult<()> {
pub(crate) fn path_link(
resolved_old: PathGet,
resolved_new: PathGet,
follow_symlinks: bool,
) -> WasiResult<()> {
use yanix::file::{linkat, AtFlag};
let flags = if follow_symlinks {
AtFlag::SYMLINK_FOLLOW
} else {
AtFlag::empty()
};
unsafe {
linkat(
resolved_old.dirfd().as_raw_fd(),
resolved_old.path(),
resolved_new.dirfd().as_raw_fd(),
resolved_new.path(),
AtFlag::SYMLINK_FOLLOW,
flags,
)
}
.map_err(Into::into)

6
crates/wasi-common/src/sys/windows/hostcalls_impl/fs.rs

@ -129,7 +129,11 @@ pub(crate) fn path_create_directory(file: &File, path: &str) -> WasiResult<()> {
std::fs::create_dir(&path).map_err(Into::into)
}
pub(crate) fn path_link(resolved_old: PathGet, resolved_new: PathGet) -> WasiResult<()> {
pub(crate) fn path_link(
resolved_old: PathGet,
resolved_new: PathGet,
follow_symlinks: bool,
) -> WasiResult<()> {
unimplemented!("path_link")
}

Loading…
Cancel
Save