@@ -11,7 +11,6 @@ use crate::sync::Arc;
1111use crate :: sys:: handle:: Handle ;
1212use crate :: sys:: time:: SystemTime ;
1313use crate :: sys:: { c, cvt} ;
14- pub use crate :: sys_common:: fs:: try_exists;
1514use crate :: sys_common:: FromInner ;
1615
1716use super :: to_u16s;
@@ -945,3 +944,32 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
945944 . map ( drop)
946945 }
947946}
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