Skip to content

Commit 319f2dd

Browse files
committed
Auto merge of #1279 - divergentdave:open_O_EXCL, r=RalfJung
Add support for OpenOptions::create_new()/O_EXCL This PR extends the POSIX shim for `open` to support the `O_EXCL` flag, when it is used alongside `O_CREAT`, and exercises it by testing `OpenOptions::create_new`.
2 parents 7743a73 + 808709c commit 319f2dd

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

src/shims/fs.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
288288
}
289289
let o_creat = this.eval_libc_i32("O_CREAT")?;
290290
if flag & o_creat != 0 {
291-
options.create(true);
292291
mirror |= o_creat;
292+
293+
let o_excl = this.eval_libc_i32("O_EXCL")?;
294+
if flag & o_excl != 0 {
295+
mirror |= o_excl;
296+
options.create_new(true);
297+
} else {
298+
options.create(true);
299+
}
293300
}
294301
let o_cloexec = this.eval_libc_i32("O_CLOEXEC")?;
295302
if flag & o_cloexec != 0 {

tests/run-pass/fs.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
// ignore-windows: File handling is not implemented yet
22
// compile-flags: -Zmiri-disable-isolation
33

4-
use std::fs::{File, create_dir, read_dir, remove_dir, remove_dir_all, remove_file, rename};
4+
use std::fs::{
5+
File, create_dir, OpenOptions, read_dir, remove_dir, remove_dir_all, remove_file, rename,
6+
};
57
use std::io::{Read, Write, ErrorKind, Result, Seek, SeekFrom};
68
use std::path::{PathBuf, Path};
79

810
fn main() {
911
test_file();
1012
test_file_clone();
13+
test_file_create_new();
1114
test_seek();
1215
test_metadata();
1316
test_symlink();
@@ -85,6 +88,20 @@ fn test_file_clone() {
8588
remove_file(&path).unwrap();
8689
}
8790

91+
fn test_file_create_new() {
92+
let path = prepare("miri_test_fs_file_create_new.txt");
93+
94+
// Creating a new file that doesn't yet exist should succeed.
95+
OpenOptions::new().write(true).create_new(true).open(&path).unwrap();
96+
// Creating a new file that already exists should fail.
97+
assert_eq!(ErrorKind::AlreadyExists, OpenOptions::new().write(true).create_new(true).open(&path).unwrap_err().kind());
98+
// Optionally creating a new file that already exists should succeed.
99+
OpenOptions::new().write(true).create(true).open(&path).unwrap();
100+
101+
// Clean up
102+
remove_file(&path).unwrap();
103+
}
104+
88105
fn test_seek() {
89106
let bytes = b"Hello, entire World!\n";
90107
let path = prepare_with_content("miri_test_fs_seek.txt", bytes);

0 commit comments

Comments
 (0)