Skip to content

Commit 0500cdc

Browse files
authored
Merge pull request #4881 from RalfJung/setfl
ignore file mode and creation flags in F_SETFL
2 parents 1472b9f + 7dc80de commit 0500cdc

3 files changed

Lines changed: 31 additions & 9 deletions

File tree

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
196196
let [flag] = check_min_vararg_count("fcntl(fd, F_SETFL, ...)", varargs)?;
197197
let flag = this.read_scalar(flag)?.to_i32()?;
198198

199-
fd.set_flags(flag, this)
199+
// Ignore flags that never get stored by SETFL.
200+
// "File access mode (O_RDONLY, O_WRONLY, O_RDWR) and file
201+
// creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC)
202+
// in arg are ignored."
203+
let ignored_flags = this.eval_libc_i32("O_RDONLY")
204+
| this.eval_libc_i32("O_WRONLY")
205+
| this.eval_libc_i32("O_RDWR")
206+
| this.eval_libc_i32("O_CREAT")
207+
| this.eval_libc_i32("O_EXCL")
208+
| this.eval_libc_i32("O_NOCTTY")
209+
| this.eval_libc_i32("O_TRUNC");
210+
211+
fd.set_flags(flag & !ignored_flags, this)
200212
}
201213
cmd if this.tcx.sess.target.os == Os::MacOs
202214
&& cmd == this.eval_libc_i32("F_FULLFSYNC") =>

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,7 @@ impl FileDescription for AnonSocket {
170170
mut flag: i32,
171171
ecx: &mut MiriInterpCx<'tcx>,
172172
) -> InterpResult<'tcx, Scalar> {
173-
// FIXME: File creation flags should be ignored.
174-
175173
let o_nonblock = ecx.eval_libc_i32("O_NONBLOCK");
176-
let o_rdonly = ecx.eval_libc_i32("O_RDONLY");
177-
let o_wronly = ecx.eval_libc_i32("O_WRONLY");
178-
let o_rdwr = ecx.eval_libc_i32("O_RDWR");
179174

180175
// O_NONBLOCK flag can be set / unset by user.
181176
if flag & o_nonblock == o_nonblock {
@@ -185,9 +180,6 @@ impl FileDescription for AnonSocket {
185180
self.is_nonblock.set(false);
186181
}
187182

188-
// Ignore all file access mode flags.
189-
flag &= !(o_rdonly | o_wronly | o_rdwr);
190-
191183
// Throw error if there is any unsupported flag.
192184
if flag != 0 {
193185
throw_unsup_format!(

src/tools/miri/tests/pass-dep/libc/libc-pipe.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,24 @@ fn test_pipe_setfl_getfl() {
148148
errno_result(unsafe { libc::fcntl(fds[0], libc::F_GETFL) }).unwrap(),
149149
libc::O_RDONLY
150150
);
151+
152+
// Test if ignored flags are indeed ignored.
153+
errno_check(unsafe {
154+
libc::fcntl(
155+
fds[0],
156+
libc::F_SETFL,
157+
libc::O_RDWR
158+
| libc::O_CREAT
159+
| libc::O_EXCL
160+
| libc::O_NOCTTY
161+
| libc::O_TRUNC
162+
| libc::O_NONBLOCK,
163+
)
164+
});
165+
assert_eq!(
166+
errno_result(unsafe { libc::fcntl(fds[0], libc::F_GETFL) }).unwrap(),
167+
libc::O_NONBLOCK | libc::O_RDONLY
168+
);
151169
}
152170

153171
/// Test the behaviour of F_SETFL/F_GETFL when a fd is blocking.

0 commit comments

Comments
 (0)