|
21 | 21 | mod tests;
|
22 | 22 |
|
23 | 23 | use crate::ffi::OsString;
|
24 |
| -use crate::fmt; |
25 | 24 | use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
|
26 | 25 | use crate::path::{Path, PathBuf};
|
27 | 26 | use crate::sealed::Sealed;
|
28 | 27 | use crate::sync::Arc;
|
29 | 28 | use crate::sys::fs as fs_imp;
|
30 | 29 | use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
|
31 | 30 | use crate::time::SystemTime;
|
| 31 | +use crate::{error, fmt}; |
32 | 32 |
|
33 | 33 | /// An object providing access to an open file on the filesystem.
|
34 | 34 | ///
|
@@ -116,6 +116,22 @@ pub struct File {
|
116 | 116 | inner: fs_imp::File,
|
117 | 117 | }
|
118 | 118 |
|
| 119 | +/// An enumeration of possible errors which can occur while trying to acquire a lock |
| 120 | +/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`]. |
| 121 | +/// |
| 122 | +/// [`try_lock`]: File::try_lock |
| 123 | +/// [`try_lock_shared`]: File::try_lock_shared |
| 124 | +#[unstable(feature = "file_lock", issue = "130994")] |
| 125 | +pub enum TryLockError { |
| 126 | + /// The lock could not be acquired due to an I/O error on the file. The standard library will |
| 127 | + /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`] |
| 128 | + /// |
| 129 | + /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock |
| 130 | + Error(io::Error), |
| 131 | + /// The lock could not be acquired at this time because it is held by another handle/process. |
| 132 | + WouldBlock, |
| 133 | +} |
| 134 | + |
119 | 135 | /// Metadata information about a file.
|
120 | 136 | ///
|
121 | 137 | /// This structure is returned from the [`metadata`] or
|
@@ -352,6 +368,30 @@ pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result
|
352 | 368 | inner(path.as_ref(), contents.as_ref())
|
353 | 369 | }
|
354 | 370 |
|
| 371 | +#[unstable(feature = "file_lock", issue = "130994")] |
| 372 | +impl error::Error for TryLockError {} |
| 373 | + |
| 374 | +#[unstable(feature = "file_lock", issue = "130994")] |
| 375 | +impl fmt::Debug for TryLockError { |
| 376 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 377 | + match self { |
| 378 | + TryLockError::Error(err) => err.fmt(f), |
| 379 | + TryLockError::WouldBlock => "WouldBlock".fmt(f), |
| 380 | + } |
| 381 | + } |
| 382 | +} |
| 383 | + |
| 384 | +#[unstable(feature = "file_lock", issue = "130994")] |
| 385 | +impl fmt::Display for TryLockError { |
| 386 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 387 | + match self { |
| 388 | + TryLockError::Error(_) => "lock acquisition failed due to I/O error", |
| 389 | + TryLockError::WouldBlock => "lock acquisition failed because the operation would block", |
| 390 | + } |
| 391 | + .fmt(f) |
| 392 | + } |
| 393 | +} |
| 394 | + |
355 | 395 | impl File {
|
356 | 396 | /// Attempts to open a file in read-only mode.
|
357 | 397 | ///
|
@@ -734,8 +774,8 @@ impl File {
|
734 | 774 |
|
735 | 775 | /// Try to acquire an exclusive lock on the file.
|
736 | 776 | ///
|
737 |
| - /// Returns `Ok(false)` if a different lock is already held on this file (via another |
738 |
| - /// handle/descriptor). |
| 777 | + /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file |
| 778 | + /// (via another handle/descriptor). |
739 | 779 | ///
|
740 | 780 | /// This acquires an exclusive lock; no other file handle to this file may acquire another lock.
|
741 | 781 | ///
|
@@ -777,23 +817,27 @@ impl File {
|
777 | 817 | ///
|
778 | 818 | /// ```no_run
|
779 | 819 | /// #![feature(file_lock)]
|
780 |
| - /// use std::fs::File; |
| 820 | + /// use std::fs::{File, TryLockError}; |
781 | 821 | ///
|
782 | 822 | /// fn main() -> std::io::Result<()> {
|
783 | 823 | /// let f = File::create("foo.txt")?;
|
784 |
| - /// f.try_lock()?; |
| 824 | + /// match f.try_lock() { |
| 825 | + /// Ok(_) => (), |
| 826 | + /// Err(TryLockError::WouldBlock) => (), // Lock not acquired |
| 827 | + /// Err(TryLockError::Error(err)) => return Err(err), |
| 828 | + /// } |
785 | 829 | /// Ok(())
|
786 | 830 | /// }
|
787 | 831 | /// ```
|
788 | 832 | #[unstable(feature = "file_lock", issue = "130994")]
|
789 |
| - pub fn try_lock(&self) -> io::Result<bool> { |
| 833 | + pub fn try_lock(&self) -> Result<(), TryLockError> { |
790 | 834 | self.inner.try_lock()
|
791 | 835 | }
|
792 | 836 |
|
793 | 837 | /// Try to acquire a shared (non-exclusive) lock on the file.
|
794 | 838 | ///
|
795 |
| - /// Returns `Ok(false)` if an exclusive lock is already held on this file (via another |
796 |
| - /// handle/descriptor). |
| 839 | + /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file |
| 840 | + /// (via another handle/descriptor). |
797 | 841 | ///
|
798 | 842 | /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may
|
799 | 843 | /// hold an exclusive lock at the same time.
|
@@ -834,16 +878,21 @@ impl File {
|
834 | 878 | ///
|
835 | 879 | /// ```no_run
|
836 | 880 | /// #![feature(file_lock)]
|
837 |
| - /// use std::fs::File; |
| 881 | + /// use std::fs::{File, TryLockError}; |
838 | 882 | ///
|
839 | 883 | /// fn main() -> std::io::Result<()> {
|
840 | 884 | /// let f = File::open("foo.txt")?;
|
841 |
| - /// f.try_lock_shared()?; |
| 885 | + /// match f.try_lock_shared() { |
| 886 | + /// Ok(_) => (), |
| 887 | + /// Err(TryLockError::WouldBlock) => (), // Lock not acquired |
| 888 | + /// Err(TryLockError::Error(err)) => return Err(err), |
| 889 | + /// } |
| 890 | + /// |
842 | 891 | /// Ok(())
|
843 | 892 | /// }
|
844 | 893 | /// ```
|
845 | 894 | #[unstable(feature = "file_lock", issue = "130994")]
|
846 |
| - pub fn try_lock_shared(&self) -> io::Result<bool> { |
| 895 | + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { |
847 | 896 | self.inner.try_lock_shared()
|
848 | 897 | }
|
849 | 898 |
|
|
0 commit comments