@@ -11,7 +11,6 @@ use crate::sync::Arc;
11
11
use crate :: sys:: handle:: Handle ;
12
12
use crate :: sys:: time:: SystemTime ;
13
13
use crate :: sys:: { c, cvt} ;
14
- pub use crate :: sys_common:: fs:: try_exists;
15
14
use crate :: sys_common:: FromInner ;
16
15
17
16
use super :: to_u16s;
@@ -945,3 +944,32 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
945
944
. map ( drop)
946
945
}
947
946
}
947
+
948
+ // Try to see if a file exists but, unlike `exists`, report I/O errors.
949
+ pub fn try_exists ( path : & Path ) -> io:: Result < bool > {
950
+ // Open the file to ensure any symlinks are followed to their target.
951
+ let mut opts = OpenOptions :: new ( ) ;
952
+ // No read, write, etc access rights are needed.
953
+ opts. access_mode ( 0 ) ;
954
+ // Backup semantics enables opening directories as well as files.
955
+ opts. custom_flags ( c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
956
+ match File :: open ( path, & opts) {
957
+ Err ( e) => match e. kind ( ) {
958
+ // The file definitely does not exist
959
+ io:: ErrorKind :: NotFound => Ok ( false ) ,
960
+
961
+ // `ERROR_SHARING_VIOLATION` means that the file has been locked by
962
+ // another process. This is often temporary so we simply report it
963
+ // as the file existing.
964
+ io:: ErrorKind :: Other if e. raw_os_error ( ) == Some ( c:: ERROR_SHARING_VIOLATION as i32 ) => {
965
+ Ok ( true )
966
+ }
967
+ // Other errors such as `ERROR_ACCESS_DENIED` may indicate that the
968
+ // file exists. However, these types of errors are usually more
969
+ // permanent so we report them here.
970
+ _ => Err ( e) ,
971
+ } ,
972
+ // The file was opened successfully therefore it must exist,
973
+ Ok ( _) => Ok ( true ) ,
974
+ }
975
+ }
0 commit comments