Skip to content

fs: implement unix OpenOptionsExt for OpenOptions #2515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions tokio/src/fs/open_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,12 @@ impl OpenOptions {
let std = asyncify(move || opts.open(path)).await?;
Ok(File::from_std(std))
}

/// Returns a mutable reference to the the underlying std::fs::OpenOptions
#[cfg(unix)]
pub(super) fn as_inner_mut(&mut self) -> &mut std::fs::OpenOptions {
&mut self.0
}
}

impl From<std::fs::OpenOptions> for OpenOptions {
Expand Down
3 changes: 3 additions & 0 deletions tokio/src/fs/os/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
mod symlink;
pub use self::symlink::symlink;

mod open_options_ext;
pub use self::open_options_ext::OpenOptionsExt;

mod dir_builder_ext;
pub use self::dir_builder_ext::DirBuilderExt;
79 changes: 79 additions & 0 deletions tokio/src/fs/os/unix/open_options_ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use crate::fs::open_options::OpenOptions;
use std::os::unix::fs::OpenOptionsExt as StdOpenOptionsExt;

/// Unix-specific extensions to [`fs::OpenOptions`].
///
/// This mirrors the definition of [`std::os::unix::fs::OpenOptionsExt`].
///
///
/// [`fs::OpenOptions`]: crate::fs::OpenOptions
/// [`std::os::unix::fs::OpenOptionsExt`]: std::os::unix::fs::OpenOptionsExt
pub trait OpenOptionsExt {
/// Sets the mode bits that a new file will be created with.
///
/// If a new file is created as part of an `OpenOptions::open` call then this
/// specified `mode` will be used as the permission bits for the new file.
/// If no `mode` is set, the default of `0o666` will be used.
/// The operating system masks out bits with the system's `umask`, to produce
/// the final permissions.
///
/// # Examples
///
/// ```no_run
/// use tokio::fs::OpenOptions;
/// use tokio::fs::os::unix::OpenOptionsExt;
/// use std::io;
///
/// #[tokio::main]
/// async fn main() -> io::Result<()> {
/// let mut options = OpenOptions::new();
/// options.mode(0o644); // Give read/write for owner and read for others.
/// let file = options.open("foo.txt").await?;
///
/// Ok(())
/// }
/// ```
fn mode(&mut self, mode: u32) -> &mut Self;

/// Pass custom flags to the `flags` argument of `open`.
///
/// The bits that define the access mode are masked out with `O_ACCMODE`, to
/// ensure they do not interfere with the access mode set by Rusts options.
///
/// Custom flags can only set flags, not remove flags set by Rusts options.
/// This options overwrites any previously set custom flags.
///
/// # Examples
///
/// ```no_run
/// use libc;
/// use tokio::fs::OpenOptions;
/// use tokio::fs::os::unix::OpenOptionsExt;
/// use std::io;
///
/// #[tokio::main]
/// async fn main() -> io::Result<()> {
/// let mut options = OpenOptions::new();
/// options.write(true);
/// if cfg!(unix) {
/// options.custom_flags(libc::O_NOFOLLOW);
/// }
/// let file = options.open("foo.txt").await?;
///
/// Ok(())
/// }
/// ```
fn custom_flags(&mut self, flags: i32) -> &mut Self;
}

impl OpenOptionsExt for OpenOptions {
fn mode(&mut self, mode: u32) -> &mut OpenOptions {
self.as_inner_mut().mode(mode);
self
}

fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
self.as_inner_mut().custom_flags(flags);
self
}
}