fs: use cfgs on fns instead of OS ext traits (#3264)

Instead of using OS specific extension traits, OS specific methods are
moved onto the structs themselves and guarded with `cfg`. The API
documentation should highlight the function is platform specific.

Closes #2925
This commit is contained in:
Carl Lerche
2020-12-14 09:29:10 -08:00
committed by GitHub
parent 48961fac89
commit 3f29212cb7
15 changed files with 328 additions and 418 deletions
+24 -4
View File
@@ -5,14 +5,10 @@ use std::path::Path;
/// A builder for creating directories in various manners.
///
/// Additional Unix-specific options are available via importing the
/// [`DirBuilderExt`] trait.
///
/// This is a specialized version of [`std::fs::DirBuilder`] for usage on
/// the Tokio runtime.
///
/// [std::fs::DirBuilder]: std::fs::DirBuilder
/// [`DirBuilderExt`]: crate::fs::os::unix::DirBuilderExt
#[derive(Debug, Default)]
pub struct DirBuilder {
/// Indicates whether to create parent directories if they are missing.
@@ -115,3 +111,27 @@ impl DirBuilder {
asyncify(move || builder.create(path)).await
}
}
feature! {
#![unix]
impl DirBuilder {
/// Sets the mode to create new directories with.
///
/// This option defaults to 0o777.
///
/// # Examples
///
///
/// ```no_run
/// use tokio::fs::DirBuilder;
///
/// let mut builder = DirBuilder::new();
/// builder.mode(0o775);
/// ```
pub fn mode(&mut self, mode: u32) -> &mut Self {
self.mode = Some(mode);
self
}
}
}
+17 -2
View File
@@ -48,8 +48,6 @@ pub use self::metadata::metadata;
mod open_options;
pub use self::open_options::OpenOptions;
pub mod os;
mod read;
pub use self::read::read;
@@ -86,6 +84,23 @@ pub use self::write::write;
mod copy;
pub use self::copy::copy;
feature! {
#![unix]
mod symlink;
pub use self::symlink::symlink;
}
feature! {
#![windows]
mod symlink_dir;
pub use self::symlink_dir::symlink_dir;
mod symlink_file;
pub use self::symlink_file::symlink_file;
}
use std::io;
pub(crate) async fn asyncify<F, T>(f: F) -> io::Result<T>
+256
View File
@@ -389,6 +389,262 @@ impl OpenOptions {
}
}
feature! {
#![unix]
use std::os::unix::fs::OpenOptionsExt;
impl OpenOptions {
/// 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 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(())
/// }
/// ```
pub fn mode(&mut self, mode: u32) -> &mut OpenOptions {
self.as_inner_mut().mode(mode);
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 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(())
/// }
/// ```
pub fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
self.as_inner_mut().custom_flags(flags);
self
}
}
}
feature! {
#![windows]
use std::os::windows::fs::OpenOptionsExt;
impl OpenOptions {
/// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`]
/// with the specified value.
///
/// This will override the `read`, `write`, and `append` flags on the
/// `OpenOptions` structure. This method provides fine-grained control over
/// the permissions to read, write and append data, attributes (like hidden
/// and system), and extended attributes.
///
/// # Examples
///
/// ```no_run
/// use tokio::fs::OpenOptions;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// // Open without read and write permission, for example if you only need
/// // to call `stat` on the file
/// let file = OpenOptions::new().access_mode(0).open("foo.txt").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
pub fn access_mode(&mut self, access: u32) -> &mut OpenOptions {
self.as_inner_mut().access_mode(access);
self
}
/// Overrides the `dwShareMode` argument to the call to [`CreateFile`] with
/// the specified value.
///
/// By default `share_mode` is set to
/// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. This allows
/// other processes to read, write, and delete/rename the same file
/// while it is open. Removing any of the flags will prevent other
/// processes from performing the corresponding operation until the file
/// handle is closed.
///
/// # Examples
///
/// ```no_run
/// use tokio::fs::OpenOptions;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// // Do not allow others to read or modify this file while we have it open
/// // for writing.
/// let file = OpenOptions::new()
/// .write(true)
/// .share_mode(0)
/// .open("foo.txt").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
pub fn share_mode(&mut self, share: u32) -> &mut OpenOptions {
self.as_inner_mut().share_mode(share);
self
}
/// Sets extra flags for the `dwFileFlags` argument to the call to
/// [`CreateFile2`] to the specified value (or combines it with
/// `attributes` and `security_qos_flags` to set the `dwFlagsAndAttributes`
/// for [`CreateFile`]).
///
/// Custom flags can only set flags, not remove flags set by Rust's options.
/// This option overwrites any previously set custom flags.
///
/// # Examples
///
/// ```no_run
/// use winapi::um::winbase::FILE_FLAG_DELETE_ON_CLOSE;
/// use tokio::fs::OpenOptions;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// let file = OpenOptions::new()
/// .create(true)
/// .write(true)
/// .custom_flags(FILE_FLAG_DELETE_ON_CLOSE)
/// .open("foo.txt").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
/// [`CreateFile2`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2
pub fn custom_flags(&mut self, flags: u32) -> &mut OpenOptions {
self.as_inner_mut().custom_flags(flags);
self
}
/// Sets the `dwFileAttributes` argument to the call to [`CreateFile2`] to
/// the specified value (or combines it with `custom_flags` and
/// `security_qos_flags` to set the `dwFlagsAndAttributes` for
/// [`CreateFile`]).
///
/// If a _new_ file is created because it does not yet exist and
/// `.create(true)` or `.create_new(true)` are specified, the new file is
/// given the attributes declared with `.attributes()`.
///
/// If an _existing_ file is opened with `.create(true).truncate(true)`, its
/// existing attributes are preserved and combined with the ones declared
/// with `.attributes()`.
///
/// In all other cases the attributes get ignored.
///
/// # Examples
///
/// ```no_run
/// use winapi::um::winnt::FILE_ATTRIBUTE_HIDDEN;
/// use tokio::fs::OpenOptions;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// let file = OpenOptions::new()
/// .write(true)
/// .create(true)
/// .attributes(FILE_ATTRIBUTE_HIDDEN)
/// .open("foo.txt").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
/// [`CreateFile2`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2
pub fn attributes(&mut self, attributes: u32) -> &mut OpenOptions {
self.as_inner_mut().attributes(attributes);
self
}
/// Sets the `dwSecurityQosFlags` argument to the call to [`CreateFile2`] to
/// the specified value (or combines it with `custom_flags` and `attributes`
/// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
///
/// By default `security_qos_flags` is not set. It should be specified when
/// opening a named pipe, to control to which degree a server process can
/// act on behalf of a client process (security impersonation level).
///
/// When `security_qos_flags` is not set, a malicious program can gain the
/// elevated privileges of a privileged Rust process when it allows opening
/// user-specified paths, by tricking it into opening a named pipe. So
/// arguably `security_qos_flags` should also be set when opening arbitrary
/// paths. However the bits can then conflict with other flags, specifically
/// `FILE_FLAG_OPEN_NO_RECALL`.
///
/// For information about possible values, see [Impersonation Levels] on the
/// Windows Dev Center site. The `SECURITY_SQOS_PRESENT` flag is set
/// automatically when using this method.
///
/// # Examples
///
/// ```no_run
/// use winapi::um::winbase::SECURITY_IDENTIFICATION;
/// use tokio::fs::OpenOptions;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// let file = OpenOptions::new()
/// .write(true)
/// .create(true)
///
/// // Sets the flag value to `SecurityIdentification`.
/// .security_qos_flags(SECURITY_IDENTIFICATION)
///
/// .open(r"\\.\pipe\MyPipe").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
/// [`CreateFile2`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2
/// [Impersonation Levels]:
/// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
pub fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions {
self.as_inner_mut().security_qos_flags(flags);
self
}
}
}
impl From<std::fs::OpenOptions> for OpenOptions {
fn from(options: std::fs::OpenOptions) -> OpenOptions {
OpenOptions(options)
-7
View File
@@ -1,7 +0,0 @@
//! OS-specific functionality.
#[cfg(unix)]
pub mod unix;
#[cfg(windows)]
pub mod windows;
-36
View File
@@ -1,36 +0,0 @@
use crate::fs::dir_builder::DirBuilder;
/// Unix-specific extensions to [`DirBuilder`].
///
/// [`DirBuilder`]: crate::fs::DirBuilder
pub trait DirBuilderExt: sealed::Sealed {
/// Sets the mode to create new directories with.
///
/// This option defaults to 0o777.
///
/// # Examples
///
///
/// ```no_run
/// use tokio::fs::DirBuilder;
/// use tokio::fs::os::unix::DirBuilderExt;
///
/// let mut builder = DirBuilder::new();
/// builder.mode(0o775);
/// ```
fn mode(&mut self, mode: u32) -> &mut Self;
}
impl DirBuilderExt for DirBuilder {
fn mode(&mut self, mode: u32) -> &mut Self {
self.mode = Some(mode);
self
}
}
impl sealed::Sealed for DirBuilder {}
pub(crate) mod sealed {
#[doc(hidden)]
pub trait Sealed {}
}
-44
View File
@@ -1,44 +0,0 @@
use crate::fs::DirEntry;
use std::os::unix::fs::DirEntryExt as _;
/// Unix-specific extension methods for [`fs::DirEntry`].
///
/// This mirrors the definition of [`std::os::unix::fs::DirEntryExt`].
///
/// [`fs::DirEntry`]: crate::fs::DirEntry
/// [`std::os::unix::fs::DirEntryExt`]: std::os::unix::fs::DirEntryExt
pub trait DirEntryExt: sealed::Sealed {
/// Returns the underlying `d_ino` field in the contained `dirent`
/// structure.
///
/// # Examples
///
/// ```
/// use tokio::fs;
/// use tokio::fs::os::unix::DirEntryExt;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// let mut entries = fs::read_dir(".").await?;
/// while let Some(entry) = entries.next_entry().await? {
/// // Here, `entry` is a `DirEntry`.
/// println!("{:?}: {}", entry.file_name(), entry.ino());
/// }
/// # Ok(())
/// # }
/// ```
fn ino(&self) -> u64;
}
impl DirEntryExt for DirEntry {
fn ino(&self) -> u64 {
self.as_inner().ino()
}
}
impl sealed::Sealed for DirEntry {}
pub(crate) mod sealed {
#[doc(hidden)]
pub trait Sealed {}
}
-13
View File
@@ -1,13 +0,0 @@
//! Unix-specific extensions to primitives in the `tokio_fs` module.
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;
mod dir_entry_ext;
pub use self::dir_entry_ext::DirEntryExt;
-85
View File
@@ -1,85 +0,0 @@
use crate::fs::open_options::OpenOptions;
use std::os::unix::fs::OpenOptionsExt as _;
/// 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: sealed::Sealed {
/// 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
}
}
impl sealed::Sealed for OpenOptions {}
pub(crate) mod sealed {
#[doc(hidden)]
pub trait Sealed {}
}
-10
View File
@@ -1,10 +0,0 @@
//! Windows-specific extensions for the primitives in the `tokio_fs` module.
mod symlink_dir;
pub use self::symlink_dir::symlink_dir;
mod symlink_file;
pub use self::symlink_file::symlink_file;
mod open_options_ext;
pub use self::open_options_ext::OpenOptionsExt;
-214
View File
@@ -1,214 +0,0 @@
use crate::fs::open_options::OpenOptions;
use std::os::windows::fs::OpenOptionsExt as _;
/// Unix-specific extensions to [`fs::OpenOptions`].
///
/// This mirrors the definition of [`std::os::windows::fs::OpenOptionsExt`].
///
/// [`fs::OpenOptions`]: crate::fs::OpenOptions
/// [`std::os::windows::fs::OpenOptionsExt`]: std::os::windows::fs::OpenOptionsExt
pub trait OpenOptionsExt: sealed::Sealed {
/// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`]
/// with the specified value.
///
/// This will override the `read`, `write`, and `append` flags on the
/// `OpenOptions` structure. This method provides fine-grained control over
/// the permissions to read, write and append data, attributes (like hidden
/// and system), and extended attributes.
///
/// # Examples
///
/// ```no_run
/// use tokio::fs::OpenOptions;
/// use tokio::fs::os::windows::OpenOptionsExt;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// // Open without read and write permission, for example if you only need
/// // to call `stat` on the file
/// let file = OpenOptions::new().access_mode(0).open("foo.txt").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
fn access_mode(&mut self, access: u32) -> &mut Self;
/// Overrides the `dwShareMode` argument to the call to [`CreateFile`] with
/// the specified value.
///
/// By default `share_mode` is set to
/// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. This allows
/// other processes to read, write, and delete/rename the same file
/// while it is open. Removing any of the flags will prevent other
/// processes from performing the corresponding operation until the file
/// handle is closed.
///
/// # Examples
///
/// ```no_run
/// use tokio::fs::OpenOptions;
/// use tokio::fs::os::windows::OpenOptionsExt;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// // Do not allow others to read or modify this file while we have it open
/// // for writing.
/// let file = OpenOptions::new()
/// .write(true)
/// .share_mode(0)
/// .open("foo.txt").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
fn share_mode(&mut self, val: u32) -> &mut Self;
/// Sets extra flags for the `dwFileFlags` argument to the call to
/// [`CreateFile2`] to the specified value (or combines it with
/// `attributes` and `security_qos_flags` to set the `dwFlagsAndAttributes`
/// for [`CreateFile`]).
///
/// Custom flags can only set flags, not remove flags set by Rust's options.
/// This option overwrites any previously set custom flags.
///
/// # Examples
///
/// ```no_run
/// use winapi::um::winbase::FILE_FLAG_DELETE_ON_CLOSE;
/// use tokio::fs::OpenOptions;
/// use tokio::fs::os::windows::OpenOptionsExt;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// let file = OpenOptions::new()
/// .create(true)
/// .write(true)
/// .custom_flags(FILE_FLAG_DELETE_ON_CLOSE)
/// .open("foo.txt").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
/// [`CreateFile2`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2
fn custom_flags(&mut self, flags: u32) -> &mut Self;
/// Sets the `dwFileAttributes` argument to the call to [`CreateFile2`] to
/// the specified value (or combines it with `custom_flags` and
/// `security_qos_flags` to set the `dwFlagsAndAttributes` for
/// [`CreateFile`]).
///
/// If a _new_ file is created because it does not yet exist and
/// `.create(true)` or `.create_new(true)` are specified, the new file is
/// given the attributes declared with `.attributes()`.
///
/// If an _existing_ file is opened with `.create(true).truncate(true)`, its
/// existing attributes are preserved and combined with the ones declared
/// with `.attributes()`.
///
/// In all other cases the attributes get ignored.
///
/// # Examples
///
/// ```no_run
/// use winapi::um::winnt::FILE_ATTRIBUTE_HIDDEN;
/// use tokio::fs::OpenOptions;
/// use tokio::fs::os::windows::OpenOptionsExt;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// let file = OpenOptions::new()
/// .write(true)
/// .create(true)
/// .attributes(FILE_ATTRIBUTE_HIDDEN)
/// .open("foo.txt").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
/// [`CreateFile2`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2
fn attributes(&mut self, val: u32) -> &mut Self;
/// Sets the `dwSecurityQosFlags` argument to the call to [`CreateFile2`] to
/// the specified value (or combines it with `custom_flags` and `attributes`
/// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
///
/// By default `security_qos_flags` is not set. It should be specified when
/// opening a named pipe, to control to which degree a server process can
/// act on behalf of a client process (security impersonation level).
///
/// When `security_qos_flags` is not set, a malicious program can gain the
/// elevated privileges of a privileged Rust process when it allows opening
/// user-specified paths, by tricking it into opening a named pipe. So
/// arguably `security_qos_flags` should also be set when opening arbitrary
/// paths. However the bits can then conflict with other flags, specifically
/// `FILE_FLAG_OPEN_NO_RECALL`.
///
/// For information about possible values, see [Impersonation Levels] on the
/// Windows Dev Center site. The `SECURITY_SQOS_PRESENT` flag is set
/// automatically when using this method.
///
/// # Examples
///
/// ```no_run
/// use winapi::um::winbase::SECURITY_IDENTIFICATION;
/// use tokio::fs::OpenOptions;
/// use tokio::fs::os::windows::OpenOptionsExt;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// let file = OpenOptions::new()
/// .write(true)
/// .create(true)
///
/// // Sets the flag value to `SecurityIdentification`.
/// .security_qos_flags(SECURITY_IDENTIFICATION)
///
/// .open(r"\\.\pipe\MyPipe").await?;
/// # Ok(())
/// # }
/// ```
///
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
/// [`CreateFile2`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2
/// [Impersonation Levels]:
/// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
fn security_qos_flags(&mut self, flags: u32) -> &mut Self;
}
impl OpenOptionsExt for OpenOptions {
fn access_mode(&mut self, access: u32) -> &mut OpenOptions {
self.as_inner_mut().access_mode(access);
self
}
fn share_mode(&mut self, share: u32) -> &mut OpenOptions {
self.as_inner_mut().share_mode(share);
self
}
fn custom_flags(&mut self, flags: u32) -> &mut OpenOptions {
self.as_inner_mut().custom_flags(flags);
self
}
fn attributes(&mut self, attributes: u32) -> &mut OpenOptions {
self.as_inner_mut().attributes(attributes);
self
}
fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions {
self.as_inner_mut().security_qos_flags(flags);
self
}
}
impl sealed::Sealed for OpenOptions {}
pub(crate) mod sealed {
#[doc(hidden)]
pub trait Sealed {}
}
+30
View File
@@ -81,6 +81,36 @@ impl ReadDir {
}
}
feature! {
#![unix]
use std::os::unix::fs::DirEntryExt;
impl DirEntry {
/// Returns the underlying `d_ino` field in the contained `dirent`
/// structure.
///
/// # Examples
///
/// ```
/// use tokio::fs;
///
/// # #[tokio::main]
/// # async fn main() -> std::io::Result<()> {
/// let mut entries = fs::read_dir(".").await?;
/// while let Some(entry) = entries.next_entry().await? {
/// // Here, `entry` is a `DirEntry`.
/// println!("{:?}: {}", entry.file_name(), entry.ino());
/// }
/// # Ok(())
/// # }
/// ```
pub fn ino(&self) -> u64 {
self.as_inner().ino()
}
}
}
#[cfg(feature = "stream")]
impl crate::stream::Stream for ReadDir {
type Item = io::Result<DirEntry>;
+1 -3
View File
@@ -48,9 +48,7 @@ async fn test_symlink() {
let src_2 = src.clone();
let dst_2 = dst.clone();
assert!(fs::os::unix::symlink(src_2.clone(), dst_2.clone())
.await
.is_ok());
assert!(fs::symlink(src_2.clone(), dst_2.clone()).await.is_ok());
let mut content = String::new();