diff --git a/src/common.cpp b/src/common.cpp index 4896c2d7a..17da93408 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1997,6 +1997,25 @@ void assert_is_locked(void *vmutex, const char *who, const char *caller) { } } +/// Detect if we are Windows Subsystem for Linux by inspecting /proc/sys/kernel/osrelease +/// and checking if "Microsoft" is in the first line. +/// See https://github.com/Microsoft/WSL/issues/423 +bool is_windows_subsystem_for_linux() { + ASSERT_IS_NOT_FORKED_CHILD(); + static bool s_is_wsl = false; + static std::once_flag oflag; + std::call_once(oflag, []() { + // 'e' sets CLOEXEC if possible. + FILE *fp = fopen("/proc/sys/kernel/osrelease", "re"); + if (fp) { + char buff[256]; + if (fgets(buff, sizeof buff, fp)) s_is_wsl = (strstr(buff, "Microsoft") != NULL); + fclose(fp); + } + }); + return s_is_wsl; +} + template static CharType_t **make_null_terminated_array_helper( const std::vector > &argv) { diff --git a/src/common.h b/src/common.h index 1809eab1c..04a53ce76 100644 --- a/src/common.h +++ b/src/common.h @@ -728,6 +728,9 @@ void assert_is_not_forked_child(const char *who); #define ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(x) assert_is_not_forked_child(x) #define ASSERT_IS_NOT_FORKED_CHILD() ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(__FUNCTION__) +/// Return whether we are running in Windows Subsystem for Linux. +bool is_windows_subsystem_for_linux(); + extern "C" { __attribute__((noinline)) void debug_thread_error(void); }