diff --git a/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs b/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs index 85284922454c94..e14b275e1c4baf 100644 --- a/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs +++ b/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs @@ -104,6 +104,9 @@ internal static TSafeHandle CheckIo(TSafeHandle handle, string? pat return handle; } + internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo) => + GetExceptionForIoErrnoCore(errorInfo, path: null, isDirError: false); + /// /// Gets an Exception to represent the supplied error info. /// @@ -111,16 +114,29 @@ internal static TSafeHandle CheckIo(TSafeHandle handle, string? pat /// The path with which this error is associated. This may be null. /// true if error is caused by a directory issue. /// - internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? path = null, bool isDirError = false) + internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? path, bool isDirError = false) + { + // Keep path/directory operations separate from GetExceptionForIoErrnoCore to allow better trimming: + // pathless callers do not pull in Path and Directory APIs. + // For Windows compatibility, throw DirectoryNotFoundException instead of FileNotFoundException + // when the parent folder does not exist. + if (errorInfo.Error == Error.ENOENT && !isDirError && path is not null) + { + string? parentPath = Path.GetDirectoryName(Path.TrimEndingDirectorySeparator(path)); + isDirError = !Directory.Exists(parentPath); + } + + return GetExceptionForIoErrnoCore(errorInfo, path, isDirError); + } + + private static Exception GetExceptionForIoErrnoCore(ErrorInfo errorInfo, string? path, bool isDirError) { // Translate the errno into a known set of exception types. For cases where multiple errnos map // to the same exception type, include an inner exception with the details. switch (errorInfo.Error) { case Error.ENOENT: - // For Windows compatibility, throw DirectoryNotFoundException instead of FileNotFoundException - // when the parent folder does not exist. - if (!isDirError && (path is null || ParentDirectoryExists(path))) + if (!isDirError) { return !string.IsNullOrEmpty(path) ? new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, path), path) : @@ -170,13 +186,6 @@ internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? pa default: return GetIOException(errorInfo, path); - - static bool ParentDirectoryExists(string fullPath) - { - string? parentPath = Path.GetDirectoryName(Path.TrimEndingDirectorySeparator(fullPath)); - - return Directory.Exists(parentPath); - } } }