about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-22 13:02:02 +0000
committerbors <bors@rust-lang.org>2020-09-22 13:02:02 +0000
commite0bc267512fc0cb49c86978192857e8187017f0b (patch)
treef81490c021e11fb3dc7ecf55104fa9f6519d8ef2 /library/std/src
parentcbc5e4d4d5715cfe111def11bbd1d8afae2ea80e (diff)
parent2f5192280f57ab859a2414ff2e9b6f6398d3feb7 (diff)
downloadrust-e0bc267512fc0cb49c86978192857e8187017f0b.tar.gz
rust-e0bc267512fc0cb49c86978192857e8187017f0b.zip
Auto merge of #76110 - FedericoPonzi:convert-openoptions-cint, r=JoshTriplett
Function to convert OpenOptions to c_int

Fixes: #74943
The creation_mode and access_mode function were already available in the OpenOptions struct, but currently private. I've added a new free functions to unix/fs.rs which takes the OpenOptions, and returns the c_int to be used as parameter for the `open` call.
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/sys/unix/ext/fs.rs29
-rw-r--r--library/std/src/sys/unix/fs.rs6
2 files changed, 35 insertions, 0 deletions
diff --git a/library/std/src/sys/unix/ext/fs.rs b/library/std/src/sys/unix/ext/fs.rs
index 4b9f4ceb29c..83cbe25d41b 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<libc::c_int>;
 }
 
 #[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<libc::c_int> {
+        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 566ac0920dc..09954f0c43c 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<c_int> {
+        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<c_int> {
         match (self.read, self.write, self.append) {
             (true, false, false) => Ok(libc::O_RDONLY),