Skip to content

Commit 352b210

Browse files
committed
move things out of libc-misc that have a better home; make libc-misc work on illumos
1 parent 12b98de commit 352b210

File tree

6 files changed

+362
-364
lines changed

6 files changed

+362
-364
lines changed

src/tools/miri/ci/ci.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ case $HOST_TARGET in
146146
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus
147147
MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus
148148
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal $VERY_BASIC hello panic/panic
149-
MIRI_TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync
150-
# TODO fix solaris stack guard
149+
MIRI_TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync libc-misc
150+
# TODO fix solaris stack guard
151151
# MIRI_TEST_TARGET=x86_64-pc-solaris run_tests_minimal $VERY_BASIC hello panic/panic pthread-sync
152152
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal $VERY_BASIC wasm
153153
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal $VERY_BASIC wasm

src/tools/miri/src/shims/unix/solarish/foreign_items.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ pub fn is_dyn_sym(_name: &str) -> bool {
1010

1111
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
1212
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
13-
#[allow(warnings)]
1413
fn emulate_foreign_item_inner(
1514
&mut self,
1615
link_name: Symbol,
@@ -20,6 +19,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2019
) -> InterpResult<'tcx, EmulateItemResult> {
2120
let this = self.eval_context_mut();
2221
match link_name.as_str() {
22+
// Miscellaneous
23+
"___errno" => {
24+
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
25+
let errno_place = this.last_error_place()?;
26+
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
27+
}
28+
2329
_ => return Ok(EmulateItemResult::NotSupported),
2430
}
2531
Ok(EmulateItemResult::NeedsJumping)

src/tools/miri/tests/pass-dep/shims/libc-fs.rs

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
#![feature(io_error_more)]
55
#![feature(io_error_uncategorized)]
66

7-
use std::ffi::CString;
7+
use std::ffi::{CStr, CString, OsString};
88
use std::fs::{canonicalize, remove_dir_all, remove_file, File};
99
use std::io::{Error, ErrorKind, Write};
1010
use std::os::unix::ffi::OsStrExt;
11+
use std::os::unix::io::AsRawFd;
1112
use std::path::PathBuf;
1213

1314
#[path = "../../utils/mod.rs"]
@@ -27,6 +28,14 @@ fn main() {
2728
#[cfg(target_os = "linux")]
2829
test_o_tmpfile_flag();
2930
test_posix_mkstemp();
31+
test_posix_realpath_alloc();
32+
test_posix_realpath_noalloc();
33+
test_posix_realpath_errors();
34+
#[cfg(target_os = "linux")]
35+
test_posix_fadvise();
36+
#[cfg(target_os = "linux")]
37+
test_sync_file_range();
38+
test_isatty();
3039
}
3140

3241
/// Prepare: compute filename and make sure the file does not exist.
@@ -256,3 +265,166 @@ fn test_posix_mkstemp() {
256265
assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
257266
}
258267
}
268+
269+
/// Test allocating variant of `realpath`.
270+
fn test_posix_realpath_alloc() {
271+
use std::os::unix::ffi::OsStrExt;
272+
use std::os::unix::ffi::OsStringExt;
273+
274+
let buf;
275+
let path = utils::tmp().join("miri_test_libc_posix_realpath_alloc");
276+
let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed");
277+
278+
// Cleanup before test.
279+
remove_file(&path).ok();
280+
// Create file.
281+
drop(File::create(&path).unwrap());
282+
unsafe {
283+
let r = libc::realpath(c_path.as_ptr(), std::ptr::null_mut());
284+
assert!(!r.is_null());
285+
buf = CStr::from_ptr(r).to_bytes().to_vec();
286+
libc::free(r as *mut _);
287+
}
288+
let canonical = PathBuf::from(OsString::from_vec(buf));
289+
assert_eq!(path.file_name(), canonical.file_name());
290+
291+
// Cleanup after test.
292+
remove_file(&path).unwrap();
293+
}
294+
295+
/// Test non-allocating variant of `realpath`.
296+
fn test_posix_realpath_noalloc() {
297+
use std::ffi::{CStr, CString};
298+
use std::os::unix::ffi::OsStrExt;
299+
300+
let path = utils::tmp().join("miri_test_libc_posix_realpath_noalloc");
301+
let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed");
302+
303+
let mut v = vec![0; libc::PATH_MAX as usize];
304+
305+
// Cleanup before test.
306+
remove_file(&path).ok();
307+
// Create file.
308+
drop(File::create(&path).unwrap());
309+
unsafe {
310+
let r = libc::realpath(c_path.as_ptr(), v.as_mut_ptr());
311+
assert!(!r.is_null());
312+
}
313+
let c = unsafe { CStr::from_ptr(v.as_ptr()) };
314+
let canonical = PathBuf::from(c.to_str().expect("CStr to str"));
315+
316+
assert_eq!(path.file_name(), canonical.file_name());
317+
318+
// Cleanup after test.
319+
remove_file(&path).unwrap();
320+
}
321+
322+
/// Test failure cases for `realpath`.
323+
fn test_posix_realpath_errors() {
324+
use std::ffi::CString;
325+
use std::io::ErrorKind;
326+
327+
// Test nonexistent path returns an error.
328+
let c_path = CString::new("./nothing_to_see_here").expect("CString::new failed");
329+
let r = unsafe { libc::realpath(c_path.as_ptr(), std::ptr::null_mut()) };
330+
assert!(r.is_null());
331+
let e = std::io::Error::last_os_error();
332+
assert_eq!(e.raw_os_error(), Some(libc::ENOENT));
333+
assert_eq!(e.kind(), ErrorKind::NotFound);
334+
}
335+
336+
#[cfg(target_os = "linux")]
337+
fn test_posix_fadvise() {
338+
use std::io::Write;
339+
340+
let path = utils::tmp().join("miri_test_libc_posix_fadvise.txt");
341+
// Cleanup before test
342+
remove_file(&path).ok();
343+
344+
// Set up an open file
345+
let mut file = File::create(&path).unwrap();
346+
let bytes = b"Hello, World!\n";
347+
file.write(bytes).unwrap();
348+
349+
// Test calling posix_fadvise on a file.
350+
let result = unsafe {
351+
libc::posix_fadvise(
352+
file.as_raw_fd(),
353+
0,
354+
bytes.len().try_into().unwrap(),
355+
libc::POSIX_FADV_DONTNEED,
356+
)
357+
};
358+
drop(file);
359+
remove_file(&path).unwrap();
360+
assert_eq!(result, 0);
361+
}
362+
363+
#[cfg(target_os = "linux")]
364+
fn test_sync_file_range() {
365+
use std::io::Write;
366+
367+
let path = utils::tmp().join("miri_test_libc_sync_file_range.txt");
368+
// Cleanup before test.
369+
remove_file(&path).ok();
370+
371+
// Write to a file.
372+
let mut file = File::create(&path).unwrap();
373+
let bytes = b"Hello, World!\n";
374+
file.write(bytes).unwrap();
375+
376+
// Test calling sync_file_range on the file.
377+
let result_1 = unsafe {
378+
libc::sync_file_range(
379+
file.as_raw_fd(),
380+
0,
381+
0,
382+
libc::SYNC_FILE_RANGE_WAIT_BEFORE
383+
| libc::SYNC_FILE_RANGE_WRITE
384+
| libc::SYNC_FILE_RANGE_WAIT_AFTER,
385+
)
386+
};
387+
drop(file);
388+
389+
// Test calling sync_file_range on a file opened for reading.
390+
let file = File::open(&path).unwrap();
391+
let result_2 = unsafe {
392+
libc::sync_file_range(
393+
file.as_raw_fd(),
394+
0,
395+
0,
396+
libc::SYNC_FILE_RANGE_WAIT_BEFORE
397+
| libc::SYNC_FILE_RANGE_WRITE
398+
| libc::SYNC_FILE_RANGE_WAIT_AFTER,
399+
)
400+
};
401+
drop(file);
402+
403+
remove_file(&path).unwrap();
404+
assert_eq!(result_1, 0);
405+
assert_eq!(result_2, 0);
406+
}
407+
408+
fn test_isatty() {
409+
// Testing whether our isatty shim returns the right value would require controlling whether
410+
// these streams are actually TTYs, which is hard.
411+
// For now, we just check that these calls are supported at all.
412+
unsafe {
413+
libc::isatty(libc::STDIN_FILENO);
414+
libc::isatty(libc::STDOUT_FILENO);
415+
libc::isatty(libc::STDERR_FILENO);
416+
417+
// But when we open a file, it is definitely not a TTY.
418+
let path = utils::tmp().join("notatty.txt");
419+
// Cleanup before test.
420+
remove_file(&path).ok();
421+
let file = File::create(&path).unwrap();
422+
423+
assert_eq!(libc::isatty(file.as_raw_fd()), 0);
424+
assert_eq!(std::io::Error::last_os_error().raw_os_error().unwrap(), libc::ENOTTY);
425+
426+
// Cleanup after test.
427+
drop(file);
428+
remove_file(&path).unwrap();
429+
}
430+
}

0 commit comments

Comments
 (0)