Skip to content

Commit 42ebf28

Browse files
committed
Add unsetting test
1 parent 1724128 commit 42ebf28

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

src/shims/unix/unnamed_socket.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use std::collections::VecDeque;
77
use std::io;
88
use std::io::ErrorKind;
99

10+
use libc::O_NONBLOCK;
11+
1012
use crate::concurrency::VClock;
1113
use crate::shims::files::{
1214
EvalContextExt as _, FileDescription, FileDescriptionRef, WeakFileDescriptionRef,
@@ -152,14 +154,25 @@ impl FileDescription for AnonSocket {
152154

153155
fn set_flags<'tcx>(
154156
&self,
155-
flag: i32,
157+
mut flag: i32,
156158
ecx: &mut MiriInterpCx<'tcx>,
157159
) -> InterpResult<'tcx, Scalar> {
158160
// FIXME: File access mode and file creation flags should be ignored.
159-
// TODO: support flag unset
160-
if flag == ecx.eval_libc_i32("O_NONBLOCK") {
161+
162+
let o_nonblock = ecx.eval_libc_i32("O_NONBLOCK");
163+
164+
// TODO: this is kind of bad and subtle, add a comment in the pr
165+
if flag & o_nonblock == o_nonblock {
166+
// If there is O_NONBLOCK flag
161167
self.is_nonblock.set(true);
168+
flag &= !O_NONBLOCK;
162169
} else {
170+
// If there is no O_NONBLOCK flag
171+
self.is_nonblock.set(false);
172+
}
173+
174+
// Fail if there is unsupported flag.
175+
if flag & o_nonblock != 0 {
163176
throw_unsup_format!("fcntl: only O_NONBLOCK is supported for F_SETFL")
164177
}
165178

tests/pass-dep/libc/libc-fs-with-isolation.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,19 @@ fn test_socketpair_setfl_getfl() {
5353
let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) };
5454
assert_eq!(res, new_flag);
5555

56-
// THe other side remains unchanged.
56+
// Test unset flag
57+
let res = unsafe { libc::fcntl(fds[0], libc::F_SETFL, 0) };
58+
assert_eq!(res, 0);
59+
let new_flag = libc::O_RDWR;
60+
let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) };
61+
assert_eq!(res, new_flag);
62+
63+
// The other side remains unchanged.
5764
let res = unsafe { libc::fcntl(fds[1], libc::F_GETFL) };
5865
assert_eq!(res, libc::O_RDWR);
5966
}
6067

68+
/// Basic test for pipe fcntl's F_SETFL and F_GETFL flag.
6169
fn test_pipe_setfl_getfl() {
6270
let mut fds = [-1, -1];
6371
let res = unsafe { libc::pipe(fds.as_mut_ptr()) };
@@ -78,6 +86,13 @@ fn test_pipe_setfl_getfl() {
7886
let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) };
7987
assert_eq!(res, new_flag);
8088

89+
// Test unset flag.
90+
let res = unsafe { libc::fcntl(fds[0], libc::F_SETFL, 0) };
91+
assert_eq!(res, 0);
92+
let new_flag = libc::O_RDONLY;
93+
let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) };
94+
assert_eq!(res, new_flag);
95+
8196
// THe other side remains unchanged.
8297
let res = unsafe { libc::fcntl(fds[1], libc::F_GETFL) };
8398
assert_eq!(res, libc::O_WRONLY);

0 commit comments

Comments
 (0)