Skip to content

Commit e540425

Browse files
committed
Add a File::create_new constructor
We have `File::create` for creating a file or opening an existing file, but the secure way to guarantee creating a new file requires a longhand invocation via `OpenOptions`. Add `File::create_new` to handle this case, to make it easier for people to do secure file creation.
1 parent 9a6fa4f commit e540425

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

library/std/src/fs.rs

+29
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,35 @@ impl File {
366366
OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())
367367
}
368368

369+
/// Creates a new file in read-write mode; error if the file exists.
370+
///
371+
/// This function will create a file if it does not exist, or return an error if it does. This
372+
/// way, if the call succeeds, the file returned is guaranteed to be new.
373+
///
374+
/// This option is useful because it is atomic. Otherwise between checking whether a file
375+
/// exists and creating a new one, the file may have been created by another process (a TOCTOU
376+
/// race condition / attack).
377+
///
378+
/// This can also be written using
379+
/// `File::options().read(true).write(true).create_new(true).open(...)`.
380+
///
381+
/// # Examples
382+
///
383+
/// ```no_run
384+
/// #![feature(file_create_new)]
385+
///
386+
/// use std::fs::File;
387+
///
388+
/// fn main() -> std::io::Result<()> {
389+
/// let mut f = File::create_new("foo.txt")?;
390+
/// Ok(())
391+
/// }
392+
/// ```
393+
#[unstable(feature = "file_create_new", issue = "none")]
394+
pub fn create_new<P: AsRef<Path>>(path: P) -> io::Result<File> {
395+
OpenOptions::new().read(true).write(true).create_new(true).open(path.as_ref())
396+
}
397+
369398
/// Returns a new OpenOptions object.
370399
///
371400
/// This function returns a new OpenOptions object that you can use to

0 commit comments

Comments
 (0)