diff options
author | Jeremy Kuhne <jeremy.kuhne@microsoft.com> | 2018-02-13 00:56:17 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-13 00:56:17 +0300 |
commit | c9100ffc2988a0faf0e92898762a445ccb3c0e13 (patch) | |
tree | f77f54ae8959ba60acfed3312d80979e059583fd /src/System.IO.FileSystem | |
parent | efcb7c2bfa98941d641c59187cdab721ada625db (diff) |
Switch from using SafeHandle for Unix enumeration (#27052)
* Switch from using SafeHandle for Unix enumeration
* Address feedback
* Fix faceplant, dispose in test.
Diffstat (limited to 'src/System.IO.FileSystem')
3 files changed, 54 insertions, 12 deletions
diff --git a/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs b/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs index b37dd2a963..7e9bbd6e4c 100644 --- a/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs +++ b/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs @@ -4,9 +4,8 @@ using System.Buffers; using System.Collections.Generic; -using System.Diagnostics; using System.Runtime.ConstrainedExecution; -using Microsoft.Win32.SafeHandles; +using System.Threading; namespace System.IO.Enumeration { @@ -22,7 +21,7 @@ namespace System.IO.Enumeration private readonly object _lock = new object(); private string _currentPath; - private SafeDirectoryHandle _directoryHandle; + private IntPtr _directoryHandle; private bool _lastEntryFound; private Queue<string> _pending; @@ -48,7 +47,7 @@ namespace System.IO.Enumeration // We need to initialize the directory handle up front to ensure // we immediately throw IO exceptions for missing directory/etc. _directoryHandle = CreateDirectoryHandle(_rootDirectory); - if (_directoryHandle == null) + if (_directoryHandle == IntPtr.Zero) _lastEntryFound = true; _currentPath = _rootDirectory; @@ -67,18 +66,16 @@ namespace System.IO.Enumeration } } - private SafeDirectoryHandle CreateDirectoryHandle(string path) + private IntPtr CreateDirectoryHandle(string path) { - // TODO: https://github.com/dotnet/corefx/issues/26715 - // - Use IntPtr handle directly - SafeDirectoryHandle handle = Interop.Sys.OpenDir(path); - if (handle.IsInvalid) + IntPtr handle = Interop.Sys.OpenDir(path); + if (handle == IntPtr.Zero) { Interop.ErrorInfo info = Interop.Sys.GetLastErrorInfo(); if ((_options.IgnoreInaccessible && IsAccessError(info.RawErrno)) || ContinueOnError(info.RawErrno)) { - return null; + return IntPtr.Zero; } throw Interop.GetExceptionForIoErrno(info, path, isDirectory: true); } @@ -87,8 +84,9 @@ namespace System.IO.Enumeration private void CloseDirectoryHandle() { - _directoryHandle?.Dispose(); - _directoryHandle = null; + IntPtr handle = Interlocked.Exchange(ref _directoryHandle, IntPtr.Zero); + if (handle != IntPtr.Zero) + Interop.Sys.CloseDir(handle); } public bool MoveNext() diff --git a/src/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.netcoreapp.cs b/src/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.netcoreapp.cs new file mode 100644 index 0000000000..24f07f8911 --- /dev/null +++ b/src/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.netcoreapp.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.IO.Enumeration; +using Xunit; + +namespace System.IO.Tests +{ + public class ErrorHandlingTests : FileSystemTest + { + private class IgnoreErrors : FileSystemEnumerator<string> + { + public IgnoreErrors(string directory) + : base(directory) + { } + + public int ErrorCount { get; private set; } + + protected override string TransformEntry(ref FileSystemEntry entry) + { + throw new NotImplementedException(); + } + + protected override bool ContinueOnError(int error) + { + ErrorCount++; + return true; + } + } + + [Fact] + public void OpenErrorDoesNotHappenAgainOnMoveNext() + { + using (IgnoreErrors ie = new IgnoreErrors(Path.GetRandomFileName())) + { + Assert.Equal(1, ie.ErrorCount); + Assert.False(ie.MoveNext()); + Assert.Equal(1, ie.ErrorCount); + } + } + } +} diff --git a/src/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj b/src/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj index 471bf4cd52..63a4b2c7cf 100644 --- a/src/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj +++ b/src/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj @@ -59,6 +59,7 @@ <Compile Include="Enumeration\DosMatcherTests.netcoreapp.cs" /> <Compile Include="Enumeration\MatchCasingTests.netcoreapp.cs" /> <Compile Include="Enumeration\TrimmedPaths.netcoreapp.cs" /> + <Compile Include="Enumeration\ErrorHandlingTests.netcoreapp.cs" /> </ItemGroup> <ItemGroup> <!-- Rewritten --> |