diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2021-10-22 15:03:54 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2021-10-22 15:03:54 +0200 |
commit | 33b8b378fae1daa02550bc53c5e43c4dfc6819de (patch) | |
tree | 55546c12f5266ba5a15149997c24d8655d56ee97 | |
parent | 8a3d6e8d1cb04e911eb57019e9a87a106fc6ea99 (diff) |
Fortify fdopen() against Windows ERROR_USER_MAPPED_FILE
-rw-r--r-- | libbutl/fdstream.cxx | 14 |
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; } |