From 8fd277728861916ad47afedf869d8bc2ad7443dc Mon Sep 17 00:00:00 2001 From: Marius Ungureanu Date: Wed, 24 Feb 2021 11:28:36 +0200 Subject: [PATCH 1/3] Fix macOS dir behaviour by providing EINTR handling Fixes #47584 --- .../Native/Unix/System.Native/pal_io.c | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_io.c b/src/libraries/Native/Unix/System.Native/pal_io.c index 3f678db8367e3e..928bfdb1a0779e 100644 --- a/src/libraries/Native/Unix/System.Native/pal_io.c +++ b/src/libraries/Native/Unix/System.Native/pal_io.c @@ -427,7 +427,9 @@ int32_t SystemNative_ReadDirR(DIR* dir, uint8_t* buffer, int32_t bufferSize, Dir return errno == 0 ? -1 : errno; } #else - int error = readdir_r(dir, entry, &result); + int error; + + while ((error = readdir_r(dir, entry, &result)) && error == EINTR); // positive error number returned -> failure if (error != 0) @@ -473,12 +475,24 @@ int32_t SystemNative_ReadDirR(DIR* dir, uint8_t* buffer, int32_t bufferSize, Dir DIR* SystemNative_OpenDir(const char* path) { - return opendir(path); + DIR *result; + + while ((result = opendir(path)) == NULL && errno == EINTR); + + return result; } int32_t SystemNative_CloseDir(DIR* dir) { - return closedir(dir); + int32_t result; + + result = closedir(dir); + if (result < 0 && errno == EINTR) + { + result = 0; + } + + return result; } int32_t SystemNative_Pipe(int32_t pipeFds[2], int32_t flags) From 89605a05642040c135e4e7400c5df7d209cbd04d Mon Sep 17 00:00:00 2001 From: Marius Ungureanu Date: Wed, 24 Feb 2021 14:14:11 +0200 Subject: [PATCH 2/3] Add comments --- src/libraries/Native/Unix/System.Native/pal_io.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/Native/Unix/System.Native/pal_io.c b/src/libraries/Native/Unix/System.Native/pal_io.c index 928bfdb1a0779e..5342f692c67de7 100644 --- a/src/libraries/Native/Unix/System.Native/pal_io.c +++ b/src/libraries/Native/Unix/System.Native/pal_io.c @@ -429,6 +429,7 @@ int32_t SystemNative_ReadDirR(DIR* dir, uint8_t* buffer, int32_t bufferSize, Dir #else int error; + // EINTR isn't documented, happens in practice on macOS. while ((error = readdir_r(dir, entry, &result)) && error == EINTR); // positive error number returned -> failure @@ -477,6 +478,7 @@ DIR* SystemNative_OpenDir(const char* path) { DIR *result; + // EINTR isn't documented, happens in practice on macOS. while ((result = opendir(path)) == NULL && errno == EINTR); return result; @@ -487,6 +489,8 @@ int32_t SystemNative_CloseDir(DIR* dir) int32_t result; result = closedir(dir); + + // EINTR isn't documented, happens in practice on macOS. if (result < 0 && errno == EINTR) { result = 0; From 82fa4114a7719413f085d12b5ab1af7d4ef458bc Mon Sep 17 00:00:00 2001 From: Marius Ungureanu Date: Thu, 25 Feb 2021 14:11:32 +0200 Subject: [PATCH 3/3] Use errno instead of error for looping. --- src/libraries/Native/Unix/System.Native/pal_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_io.c b/src/libraries/Native/Unix/System.Native/pal_io.c index 5342f692c67de7..f1191e0bd49d78 100644 --- a/src/libraries/Native/Unix/System.Native/pal_io.c +++ b/src/libraries/Native/Unix/System.Native/pal_io.c @@ -430,7 +430,7 @@ int32_t SystemNative_ReadDirR(DIR* dir, uint8_t* buffer, int32_t bufferSize, Dir int error; // EINTR isn't documented, happens in practice on macOS. - while ((error = readdir_r(dir, entry, &result)) && error == EINTR); + while ((error = readdir_r(dir, entry, &result)) && errno == EINTR); // positive error number returned -> failure if (error != 0)