output realpath as a path, and remove a bogus test
This commit is contained in:
parent
b43bede938
commit
8356f4cc23
@ -42,6 +42,7 @@ impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mi
|
|||||||
(AlreadyExists, "EEXIST"),
|
(AlreadyExists, "EEXIST"),
|
||||||
(WouldBlock, "EWOULDBLOCK"),
|
(WouldBlock, "EWOULDBLOCK"),
|
||||||
(DirectoryNotEmpty, "ENOTEMPTY"),
|
(DirectoryNotEmpty, "ENOTEMPTY"),
|
||||||
|
(FilesystemLoop, "ELOOP"),
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -250,6 +250,19 @@ fn write_path_to_wide_str(
|
|||||||
this.write_os_str_to_wide_str(&os_str, ptr, size)
|
this.write_os_str_to_wide_str(&os_str, ptr, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocate enough memory to store a Path as a null-terminated sequence of bytes,
|
||||||
|
/// adjusting path separators if needed.
|
||||||
|
fn alloc_path_as_c_str(
|
||||||
|
&mut self,
|
||||||
|
path: &Path,
|
||||||
|
memkind: MemoryKind<MiriMemoryKind>,
|
||||||
|
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||||
|
let this = self.eval_context_mut();
|
||||||
|
let os_str = this
|
||||||
|
.convert_path_separator(Cow::Borrowed(path.as_os_str()), PathConversion::HostToTarget);
|
||||||
|
this.alloc_os_str_as_c_str(&os_str, memkind)
|
||||||
|
}
|
||||||
|
|
||||||
fn convert_path_separator<'a>(
|
fn convert_path_separator<'a>(
|
||||||
&self,
|
&self,
|
||||||
os_str: Cow<'a, OsStr>,
|
os_str: Cow<'a, OsStr>,
|
||||||
|
@ -1700,7 +1700,7 @@ fn realpath(
|
|||||||
// the resolved pathname, and returns a pointer to this buffer. The
|
// the resolved pathname, and returns a pointer to this buffer. The
|
||||||
// caller should deallocate this buffer using free(3)."
|
// caller should deallocate this buffer using free(3)."
|
||||||
// <https://man7.org/linux/man-pages/man3/realpath.3.html>
|
// <https://man7.org/linux/man-pages/man3/realpath.3.html>
|
||||||
this.alloc_os_str_as_c_str(resolved.as_os_str(), MiriMemoryKind::C.into())?
|
this.alloc_path_as_c_str(&resolved, MiriMemoryKind::C.into())?
|
||||||
} else {
|
} else {
|
||||||
let (wrote_path, _) =
|
let (wrote_path, _) =
|
||||||
this.write_path_to_c_str(&resolved, processed_ptr, path_max)?;
|
this.write_path_to_c_str(&resolved, processed_ptr, path_max)?;
|
||||||
|
@ -23,7 +23,6 @@ fn tmp() -> PathBuf {
|
|||||||
fn test_posix_realpath_alloc() {
|
fn test_posix_realpath_alloc() {
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::fs::{remove_file, File};
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
use std::os::unix::ffi::OsStringExt;
|
use std::os::unix::ffi::OsStringExt;
|
||||||
|
|
||||||
@ -51,7 +50,6 @@ fn test_posix_realpath_alloc() {
|
|||||||
/// Test non-allocating variant of `realpath`.
|
/// Test non-allocating variant of `realpath`.
|
||||||
fn test_posix_realpath_noalloc() {
|
fn test_posix_realpath_noalloc() {
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::fs::{remove_file, File};
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
let path = tmp().join("miri_test_libc_posix_realpath_noalloc");
|
let path = tmp().join("miri_test_libc_posix_realpath_noalloc");
|
||||||
@ -78,12 +76,8 @@ fn test_posix_realpath_noalloc() {
|
|||||||
|
|
||||||
/// Test failure cases for `realpath`.
|
/// Test failure cases for `realpath`.
|
||||||
fn test_posix_realpath_errors() {
|
fn test_posix_realpath_errors() {
|
||||||
use std::convert::TryInto;
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fs::{create_dir_all, remove_dir_all};
|
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
use std::os::unix::ffi::OsStrExt;
|
|
||||||
use std::os::unix::fs::symlink;
|
|
||||||
|
|
||||||
// Test non-existent path returns an error.
|
// Test non-existent path returns an error.
|
||||||
let c_path = CString::new("./nothing_to_see_here").expect("CString::new failed");
|
let c_path = CString::new("./nothing_to_see_here").expect("CString::new failed");
|
||||||
@ -92,48 +86,6 @@ fn test_posix_realpath_errors() {
|
|||||||
let e = std::io::Error::last_os_error();
|
let e = std::io::Error::last_os_error();
|
||||||
assert_eq!(e.raw_os_error(), Some(libc::ENOENT));
|
assert_eq!(e.raw_os_error(), Some(libc::ENOENT));
|
||||||
assert_eq!(e.kind(), ErrorKind::NotFound);
|
assert_eq!(e.kind(), ErrorKind::NotFound);
|
||||||
|
|
||||||
// Test that a long path returns an error.
|
|
||||||
//
|
|
||||||
// Linux first checks if the path exists and macos does not.
|
|
||||||
// Using an existing path ensures all platforms return `ENAMETOOLONG` given a long path.
|
|
||||||
//
|
|
||||||
// Rather than creating a bunch of directories, we create two directories containing symlinks.
|
|
||||||
// Sadly we can't avoid creating directories and instead use a path like "./././././" or "./../../" as linux
|
|
||||||
// appears to collapse "." and ".." before checking path length.
|
|
||||||
let path = tmp().join("posix_realpath_errors");
|
|
||||||
// Cleanup before test.
|
|
||||||
remove_dir_all(&path).ok();
|
|
||||||
|
|
||||||
// The directories we will put symlinks in.
|
|
||||||
let x = path.join("x/");
|
|
||||||
let y = path.join("y/");
|
|
||||||
|
|
||||||
// The symlinks in each directory pointing to each other.
|
|
||||||
let yx_sym = y.join("x");
|
|
||||||
let xy_sym = x.join("y");
|
|
||||||
|
|
||||||
// Create directories.
|
|
||||||
create_dir_all(&x).expect("dir x");
|
|
||||||
create_dir_all(&y).expect("dir y");
|
|
||||||
|
|
||||||
// Create symlinks between directories.
|
|
||||||
symlink(&x, &yx_sym).expect("symlink x");
|
|
||||||
symlink(&y, &xy_sym).expect("symlink y ");
|
|
||||||
|
|
||||||
// This path exists due to the symlinks created above.
|
|
||||||
let too_long = path.join("x/y/".repeat(libc::PATH_MAX.try_into().unwrap()));
|
|
||||||
|
|
||||||
let c_path = CString::new(too_long.into_os_string().as_bytes()).expect("CString::new failed");
|
|
||||||
let r = unsafe { libc::realpath(c_path.as_ptr(), std::ptr::null_mut()) };
|
|
||||||
let e = std::io::Error::last_os_error();
|
|
||||||
|
|
||||||
assert!(r.is_null());
|
|
||||||
assert_eq!(e.raw_os_error(), Some(libc::ENAMETOOLONG));
|
|
||||||
assert_eq!(e.kind(), ErrorKind::InvalidFilename);
|
|
||||||
|
|
||||||
// Cleanup after test.
|
|
||||||
remove_dir_all(&path).ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||||
|
Loading…
Reference in New Issue
Block a user