diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 11f439b9996de..a4c76a248974d 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -21,6 +21,7 @@ mod tests; use crate::ffi::OsString; +use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write}; use crate::path::{Path, PathBuf}; use crate::sealed::Sealed; @@ -28,7 +29,6 @@ use crate::sync::Arc; use crate::sys::fs as fs_imp; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::time::SystemTime; -use crate::{error, fmt}; /// An object providing access to an open file on the filesystem. /// @@ -116,22 +116,6 @@ pub struct File { inner: fs_imp::File, } -/// An enumeration of possible errors which can occur while trying to acquire a lock -/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`]. -/// -/// [`try_lock`]: File::try_lock -/// [`try_lock_shared`]: File::try_lock_shared -#[unstable(feature = "file_lock", issue = "130994")] -pub enum TryLockError { - /// The lock could not be acquired due to an I/O error on the file. The standard library will - /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`] - /// - /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock - Error(io::Error), - /// The lock could not be acquired at this time because it is held by another handle/process. - WouldBlock, -} - /// Metadata information about a file. /// /// This structure is returned from the [`metadata`] or @@ -368,30 +352,6 @@ pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result inner(path.as_ref(), contents.as_ref()) } -#[unstable(feature = "file_lock", issue = "130994")] -impl error::Error for TryLockError {} - -#[unstable(feature = "file_lock", issue = "130994")] -impl fmt::Debug for TryLockError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TryLockError::Error(err) => err.fmt(f), - TryLockError::WouldBlock => "WouldBlock".fmt(f), - } - } -} - -#[unstable(feature = "file_lock", issue = "130994")] -impl fmt::Display for TryLockError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TryLockError::Error(_) => "lock acquisition failed due to I/O error", - TryLockError::WouldBlock => "lock acquisition failed because the operation would block", - } - .fmt(f) - } -} - impl File { /// Attempts to open a file in read-only mode. /// @@ -774,7 +734,7 @@ impl File { /// Try to acquire an exclusive lock on the file. /// - /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file + /// Returns an error with kind [`WouldBlock`] if a different lock is already held on this file /// (via another handle/descriptor). /// /// This acquires an exclusive lock; no other file handle to this file may acquire another lock. @@ -812,31 +772,28 @@ impl File { /// [`unlock`]: File::unlock /// [`read`]: Read::read /// [`write`]: Write::write + /// [`WouldBlock`]: io::ErrorKind::WouldBlock /// /// # Examples /// /// ```no_run /// #![feature(file_lock)] - /// use std::fs::{File, TryLockError}; + /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { /// let f = File::create("foo.txt")?; - /// match f.try_lock() { - /// Ok(_) => (), - /// Err(TryLockError::WouldBlock) => (), // Lock not acquired - /// Err(TryLockError::Error(err)) => return Err(err), - /// } + /// f.try_lock()?; /// Ok(()) /// } /// ``` #[unstable(feature = "file_lock", issue = "130994")] - pub fn try_lock(&self) -> Result<(), TryLockError> { + pub fn try_lock(&self) -> io::Result<()> { self.inner.try_lock() } /// Try to acquire a shared (non-exclusive) lock on the file. /// - /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file + /// Returns an error with kind [`WouldBlock`] if a different lock is already held on this file /// (via another handle/descriptor). /// /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may @@ -873,26 +830,23 @@ impl File { /// [`unlock`]: File::unlock /// [`read`]: Read::read /// [`write`]: Write::write + /// [`WouldBlock`]: io::ErrorKind::WouldBlock /// /// # Examples /// /// ```no_run /// #![feature(file_lock)] - /// use std::fs::{File, TryLockError}; + /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { /// let f = File::open("foo.txt")?; - /// match f.try_lock_shared() { - /// Ok(_) => (), - /// Err(TryLockError::WouldBlock) => (), // Lock not acquired - /// Err(TryLockError::Error(err)) => return Err(err), - /// } + /// f.try_lock_shared()?; /// /// Ok(()) /// } /// ``` #[unstable(feature = "file_lock", issue = "130994")] - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { + pub fn try_lock_shared(&self) -> io::Result<()> { self.inner.try_lock_shared() } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 46b0d832fec45..686c8d9c23f6f 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -9,14 +9,6 @@ use rand::RngCore; ))] use crate::assert_matches::assert_matches; use crate::char::MAX_LEN_UTF8; -#[cfg(any( - windows, - target_os = "freebsd", - target_os = "linux", - target_os = "netbsd", - target_vendor = "apple", -))] -use crate::fs::TryLockError; use crate::fs::{self, File, FileTimes, OpenOptions}; use crate::io::prelude::*; use crate::io::{BorrowedBuf, ErrorKind, SeekFrom}; @@ -259,12 +251,12 @@ fn file_lock_blocking() { // Check that shared locks block exclusive locks check!(f1.lock_shared()); - assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); + assert_matches!(f2.try_lock().unwrap_err().kind(), ErrorKind::WouldBlock); check!(f1.unlock()); // Check that exclusive locks block shared locks check!(f1.lock()); - assert_matches!(f2.try_lock_shared(), Err(TryLockError::WouldBlock)); + assert_matches!(f2.try_lock_shared().unwrap_err().kind(), ErrorKind::WouldBlock); } #[test] @@ -283,7 +275,7 @@ fn file_lock_drop() { // Check that locks are released when the File is dropped check!(f1.lock_shared()); - assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); + assert_matches!(f2.try_lock().unwrap_err().kind(), ErrorKind::WouldBlock); drop(f1); check!(f2.try_lock()); } @@ -304,10 +296,10 @@ fn file_lock_dup() { // Check that locks are not dropped if the File has been cloned check!(f1.lock_shared()); - assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); + assert_matches!(f2.try_lock().unwrap_err().kind(), ErrorKind::WouldBlock); let cloned = check!(f1.try_clone()); drop(f1); - assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); + assert_matches!(f2.try_lock().unwrap_err().kind(), ErrorKind::WouldBlock); drop(cloned) } @@ -323,7 +315,7 @@ fn file_lock_double_unlock() { // Check that both are released by unlock() check!(f1.lock()); check!(f1.lock_shared()); - assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); + assert_matches!(f2.try_lock().unwrap_err().kind(), ErrorKind::WouldBlock); check!(f1.unlock()); check!(f2.try_lock()); } @@ -366,6 +358,28 @@ fn file_lock_blocking_async() { t.join().unwrap(); } +#[test] +#[cfg(windows)] +fn file_try_lock_async() { + const FILE_FLAG_OVERLAPPED: u32 = 0x40000000; + + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_try_lock_async.txt"); + let f1 = check!(File::create(filename)); + let f2 = + check!(OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).write(true).open(filename)); + + // Check that shared locks block exclusive locks + check!(f1.lock_shared()); + assert_matches!(f2.try_lock().unwrap_err().kind(), ErrorKind::WouldBlock); + check!(f1.unlock()); + + // Check that exclusive locks block all locks + check!(f1.lock()); + assert_matches!(f2.try_lock().unwrap_err().kind(), ErrorKind::WouldBlock); + assert_matches!(f2.try_lock_shared().unwrap_err().kind(), ErrorKind::WouldBlock); +} + #[test] fn file_test_io_seek_shakedown() { // 01234567890123 diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index a9774bef9e338..6496d9cae5594 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -1,5 +1,4 @@ use crate::ffi::{CStr, OsStr, OsString, c_char}; -use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; use crate::os::hermit::ffi::OsStringExt; use crate::os::hermit::hermit_abi::{ @@ -13,7 +12,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::fd::FileDesc; pub use crate::sys::fs::common::{copy, exists}; use crate::sys::time::SystemTime; -use crate::sys::{cvt, unsupported, unsupported_err}; +use crate::sys::{cvt, unsupported}; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{fmt, mem}; @@ -367,12 +366,12 @@ impl File { unsupported() } - pub fn try_lock(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(unsupported_err())) + pub fn try_lock(&self) -> io::Result<()> { + unsupported() } - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(unsupported_err())) + pub fn try_lock_shared(&self) -> io::Result<()> { + unsupported() } pub fn unlock(&self) -> io::Result<()> { diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index 3bfb39bac95bc..482dd6cb048e2 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -2,7 +2,6 @@ use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; -use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::mem::MaybeUninit; use crate::os::raw::{c_int, c_short}; @@ -12,7 +11,7 @@ use crate::sync::Arc; pub use crate::sys::fs::common::exists; use crate::sys::pal::{abi, error}; use crate::sys::time::SystemTime; -use crate::sys::{unsupported, unsupported_err}; +use crate::sys::unsupported; use crate::sys_common::ignore_notfound; type CIntNotMinusOne = core::num::niche_types::NotAllOnes; @@ -353,12 +352,12 @@ impl File { unsupported() } - pub fn try_lock(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(unsupported_err())) + pub fn try_lock(&self) -> io::Result<()> { + unsupported() } - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(unsupported_err())) + pub fn try_lock_shared(&self) -> io::Result<()> { + unsupported() } pub fn unlock(&self) -> io::Result<()> { diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 416c90b98b6d3..8a6554e0588be 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -2,7 +2,6 @@ use r_efi::protocols::file; use crate::ffi::OsString; use crate::fmt; -use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; @@ -228,11 +227,11 @@ impl File { self.0 } - pub fn try_lock(&self) -> Result<(), TryLockError> { + pub fn try_lock(&self) -> io::Result<()> { self.0 } - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { + pub fn try_lock_shared(&self) -> io::Result<()> { self.0 } diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 863358596c199..6e8a09764af50 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -75,7 +75,6 @@ use libc::{dirent64, fstat64, ftruncate64, lseek64, lstat64, off64_t, open64, st use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt::{self, Write as _}; -use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd}; use crate::os::unix::prelude::*; @@ -1311,17 +1310,9 @@ impl File { target_os = "netbsd", target_vendor = "apple", ))] - pub fn try_lock(&self) -> Result<(), TryLockError> { - let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) }); - if let Err(err) = result { - if err.kind() == io::ErrorKind::WouldBlock { - Err(TryLockError::WouldBlock) - } else { - Err(TryLockError::Error(err)) - } - } else { - Ok(()) - } + pub fn try_lock(&self) -> io::Result<()> { + cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) })?; + return Ok(()); } #[cfg(not(any( @@ -1331,11 +1322,8 @@ impl File { target_os = "netbsd", target_vendor = "apple", )))] - pub fn try_lock(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(io::const_error!( - io::ErrorKind::Unsupported, - "try_lock() not supported" - ))) + pub fn try_lock(&self) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock() not supported")) } #[cfg(any( @@ -1345,17 +1333,9 @@ impl File { target_os = "netbsd", target_vendor = "apple", ))] - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { - let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH | libc::LOCK_NB) }); - if let Err(err) = result { - if err.kind() == io::ErrorKind::WouldBlock { - Err(TryLockError::WouldBlock) - } else { - Err(TryLockError::Error(err)) - } - } else { - Ok(()) - } + pub fn try_lock_shared(&self) -> io::Result<()> { + cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH | libc::LOCK_NB) })?; + return Ok(()); } #[cfg(not(any( @@ -1365,11 +1345,8 @@ impl File { target_os = "netbsd", target_vendor = "apple", )))] - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(io::const_error!( - io::ErrorKind::Unsupported, - "try_lock_shared() not supported" - ))) + pub fn try_lock_shared(&self) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported")) } #[cfg(any( diff --git a/library/std/src/sys/fs/unsupported.rs b/library/std/src/sys/fs/unsupported.rs index 0ff9533c04734..c209c4958f2c9 100644 --- a/library/std/src/sys/fs/unsupported.rs +++ b/library/std/src/sys/fs/unsupported.rs @@ -1,6 +1,5 @@ use crate::ffi::OsString; use crate::fmt; -use crate::fs::TryLockError; use crate::hash::{Hash, Hasher}; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; @@ -207,11 +206,11 @@ impl File { self.0 } - pub fn try_lock(&self) -> Result<(), TryLockError> { + pub fn try_lock(&self) -> io::Result<()> { self.0 } - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { + pub fn try_lock_shared(&self) -> io::Result<()> { self.0 } diff --git a/library/std/src/sys/fs/wasi.rs b/library/std/src/sys/fs/wasi.rs index ebfc7377a2ead..82666bdfebddf 100644 --- a/library/std/src/sys/fs/wasi.rs +++ b/library/std/src/sys/fs/wasi.rs @@ -1,5 +1,4 @@ use crate::ffi::{CStr, OsStr, OsString}; -use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::mem::{self, ManuallyDrop}; use crate::os::raw::c_int; @@ -11,7 +10,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::fd::WasiFd; pub use crate::sys::fs::common::exists; use crate::sys::time::SystemTime; -use crate::sys::{unsupported, unsupported_err}; +use crate::sys::unsupported; use crate::sys_common::{AsInner, FromInner, IntoInner, ignore_notfound}; use crate::{fmt, iter, ptr}; @@ -462,12 +461,12 @@ impl File { unsupported() } - pub fn try_lock(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(unsupported_err())) + pub fn try_lock(&self) -> io::Result<()> { + unsupported() } - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(unsupported_err())) + pub fn try_lock_shared(&self) -> io::Result<()> { + unsupported() } pub fn unlock(&self) -> io::Result<()> { diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index 9039fd00f5d62..0c9b7ccb5adb0 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -3,7 +3,6 @@ use crate::alloc::{Layout, alloc, dealloc}; use crate::borrow::Cow; use crate::ffi::{OsStr, OsString, c_void}; -use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; use crate::mem::{self, MaybeUninit, offset_of}; use crate::os::windows::io::{AsHandle, BorrowedHandle}; @@ -400,7 +399,7 @@ impl File { self.acquire_lock(0) } - pub fn try_lock(&self) -> Result<(), TryLockError> { + pub fn try_lock(&self) -> io::Result<()> { let result = cvt(unsafe { let mut overlapped = mem::zeroed(); c::LockFileEx( @@ -415,17 +414,14 @@ impl File { match result { Ok(_) => Ok(()), - Err(err) - if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) - || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => - { - Err(TryLockError::WouldBlock) + Err(err) if err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => { + Err(io::ErrorKind::WouldBlock.into()) } - Err(err) => Err(TryLockError::Error(err)), + Err(err) => Err(err), } } - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { + pub fn try_lock_shared(&self) -> io::Result<()> { let result = cvt(unsafe { let mut overlapped = mem::zeroed(); c::LockFileEx( @@ -440,13 +436,10 @@ impl File { match result { Ok(_) => Ok(()), - Err(err) - if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) - || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => - { - Err(TryLockError::WouldBlock) + Err(err) if err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => { + Err(io::ErrorKind::WouldBlock.into()) } - Err(err) => Err(TryLockError::Error(err)), + Err(err) => Err(err), } }