From 808709c2889e11b079205fbbf830cd58d1f3711b Mon Sep 17 00:00:00 2001 From: David Cook Date: Sun, 29 Mar 2020 16:03:05 -0500 Subject: [PATCH] Add support for OpenOptions::create_new()/O_EXCL --- src/shims/fs.rs | 9 ++++++++- tests/run-pass/fs.rs | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/shims/fs.rs b/src/shims/fs.rs index 5f8be275b2e4..04ca538f8b6b 100644 --- a/src/shims/fs.rs +++ b/src/shims/fs.rs @@ -288,8 +288,15 @@ fn open( } let o_creat = this.eval_libc_i32("O_CREAT")?; if flag & o_creat != 0 { - options.create(true); mirror |= o_creat; + + let o_excl = this.eval_libc_i32("O_EXCL")?; + if flag & o_excl != 0 { + mirror |= o_excl; + options.create_new(true); + } else { + options.create(true); + } } let o_cloexec = this.eval_libc_i32("O_CLOEXEC")?; if flag & o_cloexec != 0 { diff --git a/tests/run-pass/fs.rs b/tests/run-pass/fs.rs index 104ba46c3e45..d8b6e5b44575 100644 --- a/tests/run-pass/fs.rs +++ b/tests/run-pass/fs.rs @@ -1,13 +1,16 @@ // ignore-windows: File handling is not implemented yet // compile-flags: -Zmiri-disable-isolation -use std::fs::{File, create_dir, read_dir, remove_dir, remove_dir_all, remove_file, rename}; +use std::fs::{ + File, create_dir, OpenOptions, read_dir, remove_dir, remove_dir_all, remove_file, rename, +}; use std::io::{Read, Write, ErrorKind, Result, Seek, SeekFrom}; use std::path::{PathBuf, Path}; fn main() { test_file(); test_file_clone(); + test_file_create_new(); test_seek(); test_metadata(); test_symlink(); @@ -85,6 +88,20 @@ fn test_file_clone() { remove_file(&path).unwrap(); } +fn test_file_create_new() { + let path = prepare("miri_test_fs_file_create_new.txt"); + + // Creating a new file that doesn't yet exist should succeed. + OpenOptions::new().write(true).create_new(true).open(&path).unwrap(); + // Creating a new file that already exists should fail. + assert_eq!(ErrorKind::AlreadyExists, OpenOptions::new().write(true).create_new(true).open(&path).unwrap_err().kind()); + // Optionally creating a new file that already exists should succeed. + OpenOptions::new().write(true).create(true).open(&path).unwrap(); + + // Clean up + remove_file(&path).unwrap(); +} + fn test_seek() { let bytes = b"Hello, entire World!\n"; let path = prepare_with_content("miri_test_fs_seek.txt", bytes);