Skip to content

Commit 8356f4c

Browse files
committed
output realpath as a path, and remove a bogus test
1 parent b43bede commit 8356f4c

File tree

4 files changed

+15
-49
lines changed

4 files changed

+15
-49
lines changed

src/helpers.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const UNIX_IO_ERROR_TABLE: &[(std::io::ErrorKind, &str)] = {
4242
(AlreadyExists, "EEXIST"),
4343
(WouldBlock, "EWOULDBLOCK"),
4444
(DirectoryNotEmpty, "ENOTEMPTY"),
45+
(FilesystemLoop, "ELOOP"),
4546
]
4647
};
4748

src/shims/os_str.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
250250
this.write_os_str_to_wide_str(&os_str, ptr, size)
251251
}
252252

253+
/// Allocate enough memory to store a Path as a null-terminated sequence of bytes,
254+
/// adjusting path separators if needed.
255+
fn alloc_path_as_c_str(
256+
&mut self,
257+
path: &Path,
258+
memkind: MemoryKind<MiriMemoryKind>,
259+
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
260+
let this = self.eval_context_mut();
261+
let os_str = this
262+
.convert_path_separator(Cow::Borrowed(path.as_os_str()), PathConversion::HostToTarget);
263+
this.alloc_os_str_as_c_str(&os_str, memkind)
264+
}
265+
253266
fn convert_path_separator<'a>(
254267
&self,
255268
os_str: Cow<'a, OsStr>,

src/shims/unix/fs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1700,7 +1700,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
17001700
// the resolved pathname, and returns a pointer to this buffer. The
17011701
// caller should deallocate this buffer using free(3)."
17021702
// <https://man7.org/linux/man-pages/man3/realpath.3.html>
1703-
this.alloc_os_str_as_c_str(resolved.as_os_str(), MiriMemoryKind::C.into())?
1703+
this.alloc_path_as_c_str(&resolved, MiriMemoryKind::C.into())?
17041704
} else {
17051705
let (wrote_path, _) =
17061706
this.write_path_to_c_str(&resolved, processed_ptr, path_max)?;

tests/pass/libc.rs

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ fn tmp() -> PathBuf {
2323
fn test_posix_realpath_alloc() {
2424
use std::ffi::OsString;
2525
use std::ffi::{CStr, CString};
26-
use std::fs::{remove_file, File};
2726
use std::os::unix::ffi::OsStrExt;
2827
use std::os::unix::ffi::OsStringExt;
2928

@@ -51,7 +50,6 @@ fn test_posix_realpath_alloc() {
5150
/// Test non-allocating variant of `realpath`.
5251
fn test_posix_realpath_noalloc() {
5352
use std::ffi::{CStr, CString};
54-
use std::fs::{remove_file, File};
5553
use std::os::unix::ffi::OsStrExt;
5654

5755
let path = tmp().join("miri_test_libc_posix_realpath_noalloc");
@@ -78,12 +76,8 @@ fn test_posix_realpath_noalloc() {
7876

7977
/// Test failure cases for `realpath`.
8078
fn test_posix_realpath_errors() {
81-
use std::convert::TryInto;
8279
use std::ffi::CString;
83-
use std::fs::{create_dir_all, remove_dir_all};
8480
use std::io::ErrorKind;
85-
use std::os::unix::ffi::OsStrExt;
86-
use std::os::unix::fs::symlink;
8781

8882
// Test non-existent path returns an error.
8983
let c_path = CString::new("./nothing_to_see_here").expect("CString::new failed");
@@ -92,48 +86,6 @@ fn test_posix_realpath_errors() {
9286
let e = std::io::Error::last_os_error();
9387
assert_eq!(e.raw_os_error(), Some(libc::ENOENT));
9488
assert_eq!(e.kind(), ErrorKind::NotFound);
95-
96-
// Test that a long path returns an error.
97-
//
98-
// Linux first checks if the path exists and macos does not.
99-
// Using an existing path ensures all platforms return `ENAMETOOLONG` given a long path.
100-
//
101-
// Rather than creating a bunch of directories, we create two directories containing symlinks.
102-
// Sadly we can't avoid creating directories and instead use a path like "./././././" or "./../../" as linux
103-
// appears to collapse "." and ".." before checking path length.
104-
let path = tmp().join("posix_realpath_errors");
105-
// Cleanup before test.
106-
remove_dir_all(&path).ok();
107-
108-
// The directories we will put symlinks in.
109-
let x = path.join("x/");
110-
let y = path.join("y/");
111-
112-
// The symlinks in each directory pointing to each other.
113-
let yx_sym = y.join("x");
114-
let xy_sym = x.join("y");
115-
116-
// Create directories.
117-
create_dir_all(&x).expect("dir x");
118-
create_dir_all(&y).expect("dir y");
119-
120-
// Create symlinks between directories.
121-
symlink(&x, &yx_sym).expect("symlink x");
122-
symlink(&y, &xy_sym).expect("symlink y ");
123-
124-
// This path exists due to the symlinks created above.
125-
let too_long = path.join("x/y/".repeat(libc::PATH_MAX.try_into().unwrap()));
126-
127-
let c_path = CString::new(too_long.into_os_string().as_bytes()).expect("CString::new failed");
128-
let r = unsafe { libc::realpath(c_path.as_ptr(), std::ptr::null_mut()) };
129-
let e = std::io::Error::last_os_error();
130-
131-
assert!(r.is_null());
132-
assert_eq!(e.raw_os_error(), Some(libc::ENAMETOOLONG));
133-
assert_eq!(e.kind(), ErrorKind::InvalidFilename);
134-
135-
// Cleanup after test.
136-
remove_dir_all(&path).ok();
13789
}
13890

13991
#[cfg(any(target_os = "linux", target_os = "freebsd"))]

0 commit comments

Comments
 (0)