Skip to content

Commit 8c4b365

Browse files
meshcollidersipa
authored andcommitted
Fix WSL file locking by using flock instead of fcntl
Co-authored-by: sipa <[email protected]>
1 parent 189de2f commit 8c4b365

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

src/fs.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
#ifndef WIN32
99
#include <fcntl.h>
10+
#include <string>
11+
#include <sys/file.h>
12+
#include <sys/utsname.h>
1013
#else
1114
#ifndef NOMINMAX
1215
#define NOMINMAX
@@ -49,20 +52,38 @@ FileLock::~FileLock()
4952
}
5053
}
5154

55+
static bool IsWSL()
56+
{
57+
struct utsname uname_data;
58+
return uname(&uname_data) == 0 && std::string(uname_data.version).find("Microsoft") != std::string::npos;
59+
}
60+
5261
bool FileLock::TryLock()
5362
{
5463
if (fd == -1) {
5564
return false;
5665
}
57-
struct flock lock;
58-
lock.l_type = F_WRLCK;
59-
lock.l_whence = SEEK_SET;
60-
lock.l_start = 0;
61-
lock.l_len = 0;
62-
if (fcntl(fd, F_SETLK, &lock) == -1) {
63-
reason = GetErrorReason();
64-
return false;
66+
67+
// Exclusive file locking is broken on WSL using fcntl (issue #18622)
68+
// This workaround can be removed once the bug on WSL is fixed
69+
static const bool is_wsl = IsWSL();
70+
if (is_wsl) {
71+
if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
72+
reason = GetErrorReason();
73+
return false;
74+
}
75+
} else {
76+
struct flock lock;
77+
lock.l_type = F_WRLCK;
78+
lock.l_whence = SEEK_SET;
79+
lock.l_start = 0;
80+
lock.l_len = 0;
81+
if (fcntl(fd, F_SETLK, &lock) == -1) {
82+
reason = GetErrorReason();
83+
return false;
84+
}
6585
}
86+
6687
return true;
6788
}
6889
#else

0 commit comments

Comments
 (0)