Path symlink follow (#1284)
* Fix the tests for correctly following symlinks. * Correctly follow symlinks in path_link.
This commit is contained in:
committed by
GitHub
parent
bcddce5fe0
commit
c50c24e699
@@ -152,26 +152,19 @@ unsafe fn test_path_link(dir_fd: wasi::Fd) {
|
|||||||
// Create a link to a dangling symlink
|
// Create a link to a dangling symlink
|
||||||
wasi::path_symlink("target", dir_fd, "symlink").expect("creating a dangling symlink");
|
wasi::path_symlink("target", dir_fd, "symlink").expect("creating a dangling symlink");
|
||||||
|
|
||||||
assert_eq!(
|
// This should succeed, because we're not following symlinks
|
||||||
wasi::path_link(dir_fd, 0, "symlink", dir_fd, "link")
|
wasi::path_link(dir_fd, 0, "symlink", dir_fd, "link")
|
||||||
.expect_err("creating a link to a dangling symlink should fail")
|
.expect("creating a link to a dangling symlink should succeed");
|
||||||
.raw_error(),
|
|
||||||
wasi::ERRNO_NOENT,
|
|
||||||
"errno should be ERRNO_NOENT"
|
|
||||||
);
|
|
||||||
wasi::path_unlink_file(dir_fd, "symlink").expect("removing a symlink");
|
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
|
// Create a link to a symlink loop
|
||||||
wasi::path_symlink("symlink", dir_fd, "symlink").expect("creating 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")
|
wasi::path_link(dir_fd, 0, "symlink", dir_fd, "link")
|
||||||
.expect_err("creating a link to a symlink loop")
|
.expect("creating a link to a symlink loop should succeed");
|
||||||
.raw_error(),
|
|
||||||
wasi::ERRNO_LOOP,
|
|
||||||
"errno should be ERRNO_LOOP"
|
|
||||||
);
|
|
||||||
wasi::path_unlink_file(dir_fd, "symlink").expect("removing a symlink");
|
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
|
// Create a link where target is a dangling symlink
|
||||||
wasi::path_symlink("target", dir_fd, "symlink").expect("creating 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
|
// Create a link where target is a dangling symlink following symlinks
|
||||||
wasi::path_symlink("target", dir_fd, "symlink").expect("creating a dangling symlink");
|
wasi::path_symlink("target", dir_fd, "symlink").expect("creating a dangling symlink");
|
||||||
|
|
||||||
|
// If we do follow symlinks, this should fail
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
wasi::path_link(
|
wasi::path_link(
|
||||||
dir_fd,
|
dir_fd,
|
||||||
@@ -211,7 +205,7 @@ unsafe fn test_path_link(dir_fd: wasi::Fd) {
|
|||||||
dir_fd,
|
dir_fd,
|
||||||
"link",
|
"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(),
|
.raw_error(),
|
||||||
wasi::ERRNO_NOENT,
|
wasi::ERRNO_NOENT,
|
||||||
"errno should be ERRNO_NOENT"
|
"errno should be ERRNO_NOENT"
|
||||||
|
|||||||
@@ -650,7 +650,9 @@ pub(crate) unsafe fn path_link(
|
|||||||
false,
|
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(
|
pub(crate) unsafe fn path_open(
|
||||||
|
|||||||
@@ -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)
|
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};
|
use yanix::file::{linkat, AtFlag};
|
||||||
|
let flags = if follow_symlinks {
|
||||||
|
AtFlag::SYMLINK_FOLLOW
|
||||||
|
} else {
|
||||||
|
AtFlag::empty()
|
||||||
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
linkat(
|
linkat(
|
||||||
resolved_old.dirfd().as_raw_fd(),
|
resolved_old.dirfd().as_raw_fd(),
|
||||||
resolved_old.path(),
|
resolved_old.path(),
|
||||||
resolved_new.dirfd().as_raw_fd(),
|
resolved_new.dirfd().as_raw_fd(),
|
||||||
resolved_new.path(),
|
resolved_new.path(),
|
||||||
AtFlag::SYMLINK_FOLLOW,
|
flags,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
|
|||||||
@@ -129,7 +129,11 @@ pub(crate) fn path_create_directory(file: &File, path: &str) -> WasiResult<()> {
|
|||||||
std::fs::create_dir(&path).map_err(Into::into)
|
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")
|
unimplemented!("path_link")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user