diff --git a/src/common.cpp b/src/common.cpp index 5b8f628b0..d7935218b 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -31,6 +31,12 @@ #include #endif +#ifdef __linux__ +// Includes for WSL detection +#include +#include +#endif + #ifdef __FreeBSD__ #include #elif __APPLE__ @@ -148,6 +154,31 @@ long convert_hex_digit(wchar_t d) { return -1; } +bool is_windows_subsystem_for_linux() { +#if defined(WSL) + return true; +#elif not defined(__linux__) + return false; +#endif + + // We are purposely not using std::call_once as it may invoke locking, which is an unnecessary + // overhead since there's no actual race condition here - even if multiple threads call this + // routine simultaneously the first time around, we just end up needlessly querying uname(2) one + // more time. + + static bool wsl_state = []() { + utsname info; + uname(&info); + + // Sample utsname.release under WSL: 4.4.0-17763-Microsoft + return strstr(info.release, "Microsoft") != nullptr; + }(); + + // Subsequent calls to this function may take place after fork() and before exec() in + // postfork.cpp. Make sure we never dynamically allocate any memory in the fast path! + return wsl_state; +} + #ifdef HAVE_BACKTRACE_SYMBOLS // This function produces a stack backtrace with demangled function & method names. It is based on // https://gist.github.com/fmela/591333 but adapted to the style of the fish project. diff --git a/src/common.h b/src/common.h index 49fe0572d..1433ad151 100644 --- a/src/common.h +++ b/src/common.h @@ -866,18 +866,10 @@ 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__) -/// Detect if we are Windows Subsystem for Linux by inspecting /proc/sys/kernel/osrelease -/// and checking if "Microsoft" is in the first line. +/// Determines if we are running under Microsoft's Windows Subsystem for Linux to work around +/// some known limitations and/or bugs. /// See https://github.com/Microsoft/WSL/issues/423 and Microsoft/WSL#2997 -constexpr bool is_windows_subsystem_for_linux() { - // This function is called after fork() and before exec() in postfork.cpp. Make sure we - // don't allocate any memory here! -#ifdef WSL - return true; -#else - return false; -#endif -} +bool is_windows_subsystem_for_linux(); /// Detect if we are running under Cygwin or Cgywin64 constexpr bool is_cygwin() {