]> git.lizzy.rs Git - rust.git/commitdiff
Add support for OpenOptions::create_new()/O_EXCL
authorDavid Cook <divergentdave@gmail.com>
Sun, 29 Mar 2020 21:03:05 +0000 (16:03 -0500)
committerDavid Cook <divergentdave@gmail.com>
Sun, 29 Mar 2020 21:06:41 +0000 (16:06 -0500)
src/shims/fs.rs
tests/run-pass/fs.rs

index 5f8be275b2e43ea205fb42b51700da5090d45d58..04ca538f8b6bb751def00d4962055ba54172068c 100644 (file)
@@ -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 {
index 104ba46c3e458f839bde5dfff06ae9b0a90042b9..d8b6e5b4457554dd4f36809490242e581bce1b1d 100644 (file)
@@ -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);