Skip to content

Commit 7373197

Browse files
committed
Auto merge of rust-lang#2787 - DebugSteven:move-fcntl, r=oli-obk
move reject with isolation logic in fcntl This PR moves the block of logic inside `fcntl` to reject if isolation is enabled into the branch checking if the command is `F_FULLFSYNC` on apple. This allows `fcntl` to duplicate file descriptors while using isolation. This means we can now run the tokio tests with isolation. This PR allows moves the now passing `fcntl` logic from `libc-fs-with-isolation.rs` into two different tests: - `fcntl(1, libc::F_DUPFD, 0)` succeeds with isolation - `fcntl(1, libc::F_FULLFSYNC, 0)` fails with isolation on MacOS
2 parents 8a36889 + 0e2e617 commit 7373197

File tree

7 files changed

+26
-17
lines changed

7 files changed

+26
-17
lines changed

src/tools/miri/src/shims/unix/fs.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -628,13 +628,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
628628
let fd = this.read_scalar(&args[0])?.to_i32()?;
629629
let cmd = this.read_scalar(&args[1])?.to_i32()?;
630630

631-
// Reject if isolation is enabled.
632-
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
633-
this.reject_in_isolation("`fcntl`", reject_with)?;
634-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
635-
return Ok(-1);
636-
}
637-
638631
// We only support getting the flags for a descriptor.
639632
if cmd == this.eval_libc_i32("F_GETFD") {
640633
// Currently this is the only flag that `F_GETFD` returns. It is OK to just return the
@@ -677,6 +670,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
677670
None => this.handle_not_found(),
678671
}
679672
} else if this.tcx.sess.target.os == "macos" && cmd == this.eval_libc_i32("F_FULLFSYNC") {
673+
// Reject if isolation is enabled.
674+
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
675+
this.reject_in_isolation("`fcntl`", reject_with)?;
676+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
677+
return Ok(-1);
678+
}
679+
680680
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
681681
// FIXME: Support fullfsync for all FDs
682682
let FileHandle { file, writable } =
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@only-target-apple: F_FULLFSYNC only on apple systems
2+
//@compile-flags: -Zmiri-isolation-error=warn-nobacktrace
3+
4+
use std::io::Error;
5+
6+
fn main() {
7+
// test `fcntl(F_FULLFSYNC)`
8+
unsafe {
9+
assert_eq!(libc::fcntl(1, libc::F_FULLFSYNC, 0), -1);
10+
assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EPERM));
11+
}
12+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
warning: `fcntl` was made to return an error due to isolation
2+

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ use std::fs;
77
use std::io::{Error, ErrorKind};
88

99
fn main() {
10-
// test `fcntl`
10+
// test `fcntl(F_DUPFD): should work even with isolation.`
1111
unsafe {
12-
assert_eq!(libc::fcntl(1, libc::F_DUPFD, 0), -1);
13-
assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EPERM));
12+
assert!(libc::fcntl(1, libc::F_DUPFD, 0) >= 0);
1413
}
1514

1615
// test `readlink`

src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.stderr

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
warning: `fcntl` was made to return an error due to isolation
2-
31
warning: `readlink` was made to return an error due to isolation
42

53
warning: `$STAT` was made to return an error due to isolation
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance -Zmiri-backtrace=full
1+
//@compile-flags: -Zmiri-permissive-provenance -Zmiri-backtrace=full
22
//@only-target-x86_64-unknown-linux: support for tokio only on linux and x86
33

44
use tokio::time::{sleep, Duration, Instant};
@@ -7,8 +7,6 @@ use tokio::time::{sleep, Duration, Instant};
77
async fn main() {
88
let start = Instant::now();
99
sleep(Duration::from_secs(1)).await;
10-
// It takes 96 millisecond to sleep for 1 millisecond
11-
// It takes 1025 millisecond to sleep for 1 second
1210
let time_elapsed = &start.elapsed().as_millis();
13-
assert!(time_elapsed > &1000, "{}", time_elapsed);
11+
assert!((1000..1100).contains(time_elapsed), "{}", time_elapsed);
1412
}

src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Need to disable preemption to stay on the supported MVP codepath in mio.
2-
//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance
2+
//@compile-flags: -Zmiri-permissive-provenance
33
//@only-target-x86_64-unknown-linux: support for tokio exists only on linux and x86
44

55
#[tokio::main]

0 commit comments

Comments
 (0)