From 51d876a041efde9569b94d29743466ec6841109e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Thu, 29 Apr 2021 09:22:41 -0400 Subject: [PATCH] [2020-02][System.Native] Handle ReadDir EINTR (#21029) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * [System.Native] Handle ReadDir EINTR Handle EINTR for opendir/readdir/closedir. Because of how thread aborts work, we must loop in managed. A thread abort will break syscalls and return EINTR, but mono will not raise a ThreadAbortException until a pinvoke returns. (Despite the documentation, opendir/readdir/closedir sometimes return EINTR on macOS Big Sur.) Related to https://github.com/mono/mono/issues/20799 * bump corefx * [System] on unix, include Interop.ReadDir.Mono.cs on mac it's in corlib, on unix and android it's in System, for some reason * Add newline Co-authored-by: Alexander Köplinger --- external/corefx | 2 +- mcs/class/System/corefx.unix.sources | 1 + mcs/class/System/monodroid_System.dll.sources | 2 ++ mcs/class/System/unix_net_4_x_System.dll.sources | 2 ++ mcs/class/corlib/corefx/Interop.ReadDir.Mono.cs | 45 ++++++++++++++++++++++++ mcs/class/corlib/unix_build_corlib.dll.sources | 1 + 6 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 mcs/class/corlib/corefx/Interop.ReadDir.Mono.cs diff --git a/external/corefx b/external/corefx index 38e9a9317c2..9174bbeb7e1 160000 --- a/external/corefx +++ b/external/corefx @@ -1 +1 @@ -Subproject commit 38e9a9317c2cf78611506c491cf27c5fddf9828c +Subproject commit 9174bbeb7e1e4d3dc51f4f82243cbf4c62c61efa diff --git a/mcs/class/System/corefx.unix.sources b/mcs/class/System/corefx.unix.sources index a56c61a881c..1a1092ae760 100644 --- a/mcs/class/System/corefx.unix.sources +++ b/mcs/class/System/corefx.unix.sources @@ -1,5 +1,6 @@ corefx/Unix/Interop.cs corefx/Unix/Interop.Read.cs + ../../../external/corefx/src/Common/src/Interop/Unix/*.cs ../../../external/corefx/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs diff --git a/mcs/class/System/monodroid_System.dll.sources b/mcs/class/System/monodroid_System.dll.sources index d837f60135d..706ee92f36a 100644 --- a/mcs/class/System/monodroid_System.dll.sources +++ b/mcs/class/System/monodroid_System.dll.sources @@ -19,3 +19,5 @@ Mono.Btls/MonoBtlsX509LookupAndroid.cs ../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Poll.cs ../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Open.cs ../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Close.cs + +../corlib/corefx/Interop.ReadDir.Mono.cs diff --git a/mcs/class/System/unix_net_4_x_System.dll.sources b/mcs/class/System/unix_net_4_x_System.dll.sources index 1264e8ac0b5..a47b0ce3636 100644 --- a/mcs/class/System/unix_net_4_x_System.dll.sources +++ b/mcs/class/System/unix_net_4_x_System.dll.sources @@ -15,3 +15,5 @@ ../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Close.cs ../../../external/corefx/src/Common/src/System/Net/ContextAwareResult.Unix.cs Internal.Cryptography/OidLookup.Managed.cs + +../corlib/corefx/Interop.ReadDir.Mono.cs diff --git a/mcs/class/corlib/corefx/Interop.ReadDir.Mono.cs b/mcs/class/corlib/corefx/Interop.ReadDir.Mono.cs new file mode 100644 index 00000000000..b5fb5495d64 --- /dev/null +++ b/mcs/class/corlib/corefx/Interop.ReadDir.Mono.cs @@ -0,0 +1,45 @@ +// 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; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Sys + { + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_OpenDir", SetLastError = true)] + internal static extern IntPtr OpenDir_native(string path); + + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ReadDirR", SetLastError = false)] + internal static extern unsafe int ReadDirR_native(IntPtr dir, byte* buffer, int bufferSize, out DirectoryEntry outputEntry); + + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_CloseDir", SetLastError = true)] + internal static extern int CloseDir_native(IntPtr dir); + + internal static IntPtr OpenDir (string path) { + IntPtr result; + do { + result = OpenDir_native (path); + } while (result == IntPtr.Zero && Marshal.GetLastWin32Error () == (int) Interop.Error.EINTR); + return result; + } + + internal static int CloseDir (IntPtr dir) { + int result; + do { + result = CloseDir_native (dir); + } while (result < 0 && Marshal.GetLastWin32Error () == (int) Interop.Error.EINTR); + return result; + } + + internal static unsafe int ReadDirR (IntPtr dir, byte* buffer, int bufferSize, out DirectoryEntry outputEntry) { + int result; + do { + result = ReadDirR_native (dir, buffer, bufferSize, out outputEntry); + } while (result == (int) Interop.Error.EINTR); + return result; + } + } +} diff --git a/mcs/class/corlib/unix_build_corlib.dll.sources b/mcs/class/corlib/unix_build_corlib.dll.sources index a3ebc60f09c..1106989dfca 100644 --- a/mcs/class/corlib/unix_build_corlib.dll.sources +++ b/mcs/class/corlib/unix_build_corlib.dll.sources @@ -27,6 +27,7 @@ ../../../external/corefx/src/Common/src/Microsoft/Win32/SafeHandles/SafeDirectoryHandle.Unix.cs corefx/DriveInfoInternal.Unix.cs +corefx/Interop.ReadDir.Mono.cs ../../../external/corefx/src/Common/src/CoreLib/Interop/Unix/System.Native/Interop.GetRandomBytes.cs ../../../external/corefx/src/Common/src/CoreLib/Interop/Unix/System.Native/Interop.ReadDir.cs -- 2.11.4.GIT