syserror.cpp raw

   1  // Copyright (c) 2020-2022 The Limenka developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #include <limenka-build-config.h> // IWYU pragma: keep
   6  
   7  #include <tinyformat.h>
   8  #include <util/syserror.h>
   9  
  10  #include <cstring>
  11  #include <string>
  12  
  13  #if defined(WIN32)
  14  #include <windows.h>
  15  #include <locale>
  16  #include <codecvt>
  17  #endif
  18  
  19  std::string SysErrorString(int err)
  20  {
  21      char buf[1024];
  22      /* Too bad there are three incompatible implementations of the
  23       * thread-safe strerror. */
  24      const char *s = nullptr;
  25  #ifdef WIN32
  26      if (strerror_s(buf, sizeof(buf), err) == 0) s = buf;
  27  #else
  28  #ifdef STRERROR_R_CHAR_P /* GNU variant can return a pointer outside the passed buffer */
  29      s = strerror_r(err, buf, sizeof(buf));
  30  #else /* POSIX variant always returns message in buffer */
  31      if (strerror_r(err, buf, sizeof(buf)) == 0) s = buf;
  32  #endif
  33  #endif
  34      if (s != nullptr) {
  35          return strprintf("%s (%d)", s, err);
  36      } else {
  37          return strprintf("Unknown error (%d)", err);
  38      }
  39  }
  40  
  41  #if defined(WIN32)
  42  std::string Win32ErrorString(int err)
  43  {
  44      wchar_t buf[256];
  45      buf[0] = 0;
  46      if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
  47                         nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  48                         buf, ARRAYSIZE(buf), nullptr))
  49      {
  50          return strprintf("%s (%d)", std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().to_bytes(buf), err);
  51      }
  52      else
  53      {
  54          return strprintf("Unknown error (%d)", err);
  55      }
  56  }
  57  #endif
  58