diff --git a/library/std/src/sys/unix/ext/fs.rs b/library/std/src/sys/unix/ext/fs.rs index 4b9f4ceb29c49..83cbe25d41bde 100644 --- a/library/std/src/sys/unix/ext/fs.rs +++ b/library/std/src/sys/unix/ext/fs.rs @@ -348,6 +348,31 @@ pub trait OpenOptionsExt { /// ``` #[stable(feature = "open_options_ext", since = "1.10.0")] fn custom_flags(&mut self, flags: i32) -> &mut Self; + + /// Get the flags as [`libc::c_int`]. + /// + /// This method allows the reuse of the OpenOptions as flags argument for [`libc::open`]. + /// + /// [`libc::c_int`]: https://docs.rs/libc/*/libc/type.c_int.html + /// [`libc::open`]: https://docs.rs/libc/*/libc/fn.open.html + /// + /// # Examples + /// + /// ```no_run + /// # #![feature(rustc_private)] + /// #![feature(open_options_ext_as_flags)] + /// extern crate libc; + /// use std::ffi::CString; + /// use std::fs::OpenOptions; + /// use std::os::unix::fs::OpenOptionsExt; + /// + /// let mut options = OpenOptions::new(); + /// options.write(true).read(true); + /// let file_name = CString::new("foo.txt").unwrap(); + /// let file = unsafe { libc::open(file_name.as_c_str().as_ptr(), options.as_flags().unwrap()) }; + /// ``` + #[unstable(feature = "open_options_ext_as_flags", issue = "76801")] + fn as_flags(&self) -> io::Result; } #[stable(feature = "fs_ext", since = "1.1.0")] @@ -361,6 +386,10 @@ impl OpenOptionsExt for OpenOptions { self.as_inner_mut().custom_flags(flags); self } + + fn as_flags(&self) -> io::Result { + self.as_inner().as_flags() + } } /// Unix-specific extensions to [`fs::Metadata`]. diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 566ac0920dc8f..09954f0c43c56 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -656,6 +656,12 @@ impl OpenOptions { self.mode = mode as mode_t; } + pub fn as_flags(&self) -> io::Result { + let access_mode = self.get_access_mode()?; + let creation_mode = self.get_creation_mode()?; + Ok(creation_mode | access_mode | self.custom_flags) + } + fn get_access_mode(&self) -> io::Result { match (self.read, self.write, self.append) { (true, false, false) => Ok(libc::O_RDONLY),