aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-10-22 15:03:54 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-10-22 15:03:54 +0200
commit33b8b378fae1daa02550bc53c5e43c4dfc6819de (patch)
tree55546c12f5266ba5a15149997c24d8655d56ee97
parent8a3d6e8d1cb04e911eb57019e9a87a106fc6ea99 (diff)
Fortify fdopen() against Windows ERROR_USER_MAPPED_FILE
-rw-r--r--libbutl/fdstream.cxx14
1 files changed, 10 insertions, 4 deletions
diff --git a/libbutl/fdstream.cxx b/libbutl/fdstream.cxx
index 85459de..fb2c8d1 100644
--- a/libbutl/fdstream.cxx
+++ b/libbutl/fdstream.cxx
@@ -1114,6 +1114,11 @@ namespace butl
// underlying CreateFile() function call (see mventry() for details). If
// that's the case, we will keep trying to open the file for two seconds.
//
+ // Also, it turns out, if someone memory-maps a file, it takes Windows
+ // some time to realize it's been unmapped and until then any attempt to
+ // open it results in EINVAL POSIX error, ERROR_USER_MAPPED_FILE system
+ // error. So we retry those as well.
+ //
for (size_t i (0); i < 21; ++i)
{
// Sleep 100 milliseconds before the open retry.
@@ -1133,10 +1138,11 @@ namespace butl
// Note that MinGW's _sopen() is just a stub forwarding the call to the
// (publicly available) MSVCRT's implementation.
//
- if (!(fd == -1 &&
- out &&
- errno == EACCES &&
- GetLastError () == ERROR_SHARING_VIOLATION))
+ if (!(fd == -1 &&
+ out &&
+ (errno == EACCES || errno == EINVAL) &&
+ (GetLastError () == ERROR_SHARING_VIOLATION ||
+ GetLastError () == ERROR_USER_MAPPED_FILE)))
break;
}