diff options
author | Billy Donahue <billy.donahue@mongodb.com> | 2022-04-28 07:39:29 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-04-28 08:28:54 +0000 |
commit | 5b17ba836945f2b7cbcc77a643311f41fe7b7b6e (patch) | |
tree | 11aa849763d123d755eb0d9c30215904acdef4c2 /src/mongo/util | |
parent | 30260c79d9e09dee6c68637f87db6c4bdf16cbfe (diff) | |
download | mongo-5b17ba836945f2b7cbcc77a643311f41fe7b7b6e.tar.gz |
SERVER-41353 replace errnoWithDescription with an API based on std::error_code
Diffstat (limited to 'src/mongo/util')
29 files changed, 559 insertions, 454 deletions
diff --git a/src/mongo/util/concurrency/thread_name.cpp b/src/mongo/util/concurrency/thread_name.cpp index 1a950c24bfa..b5f81ea16cf 100644 --- a/src/mongo/util/concurrency/thread_name.cpp +++ b/src/mongo/util/concurrency/thread_name.cpp @@ -144,7 +144,7 @@ void setOSThreadName(StringData threadName) { LOGV2(23102, "Ignoring error from setting thread name: {error}", "Ignoring error from setting thread name", - "error"_attr = errnoWithDescription(error)); + "error"_attr = errorMessage(posixError(error))); } #elif defined(__linux__) && defined(MONGO_CONFIG_HAVE_PTHREAD_SETNAME_NP) // Do not set thread name on the main() thread. Setting the name on main thread breaks @@ -168,7 +168,7 @@ void setOSThreadName(StringData threadName) { LOGV2(23103, "Ignoring error from setting thread name: {error}", "Ignoring error from setting thread name", - "error"_attr = errnoWithDescription(error)); + "error"_attr = errorMessage(posixError(error))); } } #endif diff --git a/src/mongo/util/concurrency/ticketholder.cpp b/src/mongo/util/concurrency/ticketholder.cpp index 30523f97f0f..fa413e52133 100644 --- a/src/mongo/util/concurrency/ticketholder.cpp +++ b/src/mongo/util/concurrency/ticketholder.cpp @@ -54,7 +54,7 @@ namespace { void failWithErrno(int err) { LOGV2_FATAL(28604, "error in Ticketholder: {errnoWithDescription_err}", - "errnoWithDescription_err"_attr = errnoWithDescription(err)); + "errnoWithDescription_err"_attr = errorMessage(posixError(err))); } /* diff --git a/src/mongo/util/dns_query_windows-impl.h b/src/mongo/util/dns_query_windows-impl.h index 84653c7a486..ebb97bf520e 100644 --- a/src/mongo/util/dns_query_windows-impl.h +++ b/src/mongo/util/dns_query_windows-impl.h @@ -279,16 +279,16 @@ public: const DNSQueryClass class_, const DNSQueryType type) { PDNS_RECORDA queryResults; - auto ec = DnsQuery_UTF8(service.c_str(), - WORD(type), - DNS_QUERY_BYPASS_CACHE, - nullptr, - reinterpret_cast<PDNS_RECORD*>(&queryResults), - nullptr); - - if (ec) { + auto e = DnsQuery_UTF8(service.c_str(), + WORD(type), + DNS_QUERY_BYPASS_CACHE, + nullptr, + reinterpret_cast<PDNS_RECORD*>(&queryResults), + nullptr); + if (e) { + auto ec = systemError(e); uasserted(ErrorCodes::DNSHostNotFound, - "Failed to look up service \""s + "\":"s + errnoWithDescription(ec)); + "Failed to look up service \""s + "\":"s + errorMessage(ec)); } return DNSResponse{service, queryResults}; } diff --git a/src/mongo/util/errno_util.cpp b/src/mongo/util/errno_util.cpp index 6e75b4b511a..a9c326f3ae8 100644 --- a/src/mongo/util/errno_util.cpp +++ b/src/mongo/util/errno_util.cpp @@ -33,10 +33,34 @@ #include <fmt/format.h> #include <system_error> +#ifndef _WIN32 +#include <netdb.h> +#endif + namespace mongo { using namespace fmt::literals; +class AddrInfoErrorCategory : public std::error_category { +public: + const char* name() const noexcept override { + return "getaddrinfo"; + } + + std::string message(int e) const override { +#ifdef _WIN32 + return systemError(e).message(); +#else + return gai_strerror(e); +#endif + } +}; + +const std::error_category& addrInfoCategory() { + static auto p = new AddrInfoErrorCategory; + return *p; +} + std::string errorMessage(std::error_code ec) { std::string r = ec.message(); bool vague = false; diff --git a/src/mongo/util/errno_util.h b/src/mongo/util/errno_util.h index 0464c38a409..408cebf528c 100644 --- a/src/mongo/util/errno_util.h +++ b/src/mongo/util/errno_util.h @@ -37,6 +37,29 @@ namespace mongo { /** + * Returns category to use for POSIX errno error codes. + * On POSIX, `errno` codes are the `std::system_category`. + * On Windows, the `errno` codes are the `std::generic_category`. + */ +inline const std::error_category& posixCategory() { +#ifdef _WIN32 + return std::generic_category(); +#else + return std::system_category(); +#endif +} + +/** Wraps POSIX `errno` value in an appropriate `std::error_code`. */ +inline std::error_code posixError(int e) { + return std::error_code(e, posixCategory()); +} + +/** Wraps `e` in a `std::error_code` with `std::system_category`. */ +inline std::error_code systemError(int e) { + return std::error_code(e, std::system_category()); +} + +/** * Returns `{errno, std::generic_category()}`. * Windows has both Windows errors and POSIX errors. That is, there's a * `GetLastError` and an `errno`. They are tracked separately, and unrelated to @@ -48,22 +71,25 @@ namespace mongo { * On POSIX systems, `std::system_category` is potentially a superset of * `std::generic_category`, so `lastSystemError` should be preferred for * handling system errors. + * + * Guaranteed to not modify `errno`. */ inline std::error_code lastPosixError() { - return std::error_code(errno, std::generic_category()); + return posixError(errno); } /** * On POSIX, returns `{errno, std::system_category()}`. * On Windows, returns `{GetLastError(), std::system_category()}`, but see `lastPosixError`. + * + * Guaranteed to not modify the system error code variable. */ inline std::error_code lastSystemError() { #ifdef _WIN32 - int e = GetLastError(); + return systemError(GetLastError()); #else - int e = errno; + return systemError(errno); #endif - return std::error_code(e, std::system_category()); } /** @@ -77,14 +103,30 @@ inline std::error_code lastSystemError() { */ std::string errorMessage(std::error_code ec); -/** A system error code's error message. */ -inline std::string errnoWithDescription(int e) { - return errorMessage(std::error_code{e, std::system_category()}); +/** + * A category for `getaddrinfo` or `getnameinfo` (i.e. the netdb.h library) + * results. Uses `gai_error` on Unix systems. On Windows, these errors are + * compatible with the system error space. + */ +const std::error_category& addrInfoCategory(); + +/** Wrap `e` in a `std::error_code` with `addrInfoCategory`. */ +inline std::error_code addrInfoError(int e) { + return std::error_code(e, addrInfoCategory()); } -/** The last system error code's error message. */ -inline std::string errnoWithDescription() { - return errorMessage(lastSystemError()); +/** + * Portable wrapper for socket API calls. On POSIX platforms this is just + * `lastSystemError`. On Windows, Winsock API callers must query last error with + * `WSAGetLastError` instead of `GetLastError`. The Winsock errors can use the + * same error code category as other Windows API calls. + */ +inline std::error_code lastSocketError() { +#ifdef _WIN32 + return systemError(WSAGetLastError()); +#else + return lastSystemError(); +#endif } } // namespace mongo diff --git a/src/mongo/util/errno_util_test.cpp b/src/mongo/util/errno_util_test.cpp index e39a8b66175..670b7c7304d 100644 --- a/src/mongo/util/errno_util_test.cpp +++ b/src/mongo/util/errno_util_test.cpp @@ -37,37 +37,49 @@ #include "mongo/unittest/unittest.h" #include "mongo/util/errno_util.h" +namespace mongo { namespace { -using namespace mongo; const std::string kUnknownError = "Unknown error"; -TEST(ErrnoWithDescription, CommonErrors) { +/** Force a predictable error message language. */ +void initLanguage() { #if defined(_WIN32) - // Force error messages to be returned in en-US. LANGID lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); ASSERT_EQ(SetThreadUILanguage(lang), lang); - - ASSERT_STRING_OMITS(errnoWithDescription(ERROR_SUCCESS), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(ERROR_FILE_NOT_FOUND), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(ERROR_PATH_NOT_FOUND), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(ERROR_TOO_MANY_OPEN_FILES), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(ERROR_ACCESS_DENIED), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(ERROR_PRIVILEGE_NOT_HELD), kUnknownError); #else - // Force the minimal locale to ensure the standard error message localization text. ASSERT(setlocale(LC_MESSAGES, "C")); +#endif +} - ASSERT_STRING_OMITS(errnoWithDescription(EPERM), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(ENOENT), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(EIO), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(EBADF), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(ENOMEM), kUnknownError); - ASSERT_STRING_OMITS(errnoWithDescription(EACCES), kUnknownError); +TEST(ErrnoWithDescription, CommonErrors) { +#if defined(_WIN32) + static const std::array knownErrors{ + ERROR_SUCCESS, + ERROR_FILE_NOT_FOUND, + ERROR_PATH_NOT_FOUND, + ERROR_TOO_MANY_OPEN_FILES, + ERROR_ACCESS_DENIED, + ERROR_PRIVILEGE_NOT_HELD, + }; +#else + static const std::array knownErrors{ + EPERM, + ENOENT, + EIO, + EBADF, + ENOMEM, + EACCES, + }; #endif - // INT_MAX is currently invalid. In the unlikely event that it becomes valid, then this check - // will have to be removed or adjusted. - ASSERT_STRING_CONTAINS(errnoWithDescription(INT_MAX), kUnknownError); + initLanguage(); + + for (auto e : knownErrors) + ASSERT_STRING_OMITS(errorMessage(systemError(e)), kUnknownError); + + // Update if INT_MAX becomes a valid code. + ASSERT_STRING_CONTAINS(errorMessage(systemError(INT_MAX)), kUnknownError); } } // namespace +} // namespace mongo diff --git a/src/mongo/util/exception_filter_win32.cpp b/src/mongo/util/exception_filter_win32.cpp index ce8e30ebbdb..a78820335a5 100644 --- a/src/mongo/util/exception_filter_win32.cpp +++ b/src/mongo/util/exception_filter_win32.cpp @@ -62,11 +62,11 @@ void doMinidumpWithException(struct _EXCEPTION_POINTERS* exceptionInfo) { DWORD ret = GetModuleFileNameW(nullptr, &moduleFileName[0], ARRAYSIZE(moduleFileName)); if (ret == 0) { - int gle = GetLastError(); + auto ec = lastSystemError(); LOGV2(23130, "GetModuleFileName failed {error}", "GetModuleFileName failed", - "error"_attr = errnoWithDescription(gle)); + "error"_attr = errorMessage(ec)); // Fallback name wcscpy_s(moduleFileName, L"mongo"); @@ -88,12 +88,12 @@ void doMinidumpWithException(struct _EXCEPTION_POINTERS* exceptionInfo) { HANDLE hFile = CreateFileW( dumpName.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (INVALID_HANDLE_VALUE == hFile) { - DWORD lasterr = GetLastError(); + auto ec = lastSystemError(); LOGV2(23131, "Failed to open minidump file {dumpName}: {error}", "Failed to open minidump file", "dumpName"_attr = toUtf8String(dumpName.c_str()), - "error"_attr = errnoWithDescription(lasterr)); + "error"_attr = errorMessage(ec)); return; } @@ -122,11 +122,11 @@ void doMinidumpWithException(struct _EXCEPTION_POINTERS* exceptionInfo) { nullptr, nullptr); if (FALSE == bstatus) { - DWORD lasterr = GetLastError(); + auto ec = lastSystemError(); LOGV2(23133, "Failed to create minidump: {error}", "Failed to create minidump", - "error"_attr = errnoWithDescription(lasterr)); + "error"_attr = errorMessage(ec)); } CloseHandle(hFile); diff --git a/src/mongo/util/file.cpp b/src/mongo/util/file.cpp index 42af8332d4b..69570df96fa 100644 --- a/src/mongo/util/file.cpp +++ b/src/mongo/util/file.cpp @@ -71,23 +71,23 @@ intmax_t File::freeSpace(const std::string& path) { nullptr)) { // ptr to returned total free return avail.QuadPart; } - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2(23140, "In File::freeSpace(), GetDiskFreeSpaceEx for '{path}' failed with {error}", "In File::freeSpace(), GetDiskFreeSpaceEx failed", "path"_attr = path, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); return -1; } void File::fsync() const { if (FlushFileBuffers(_handle) == 0) { - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2(23141, "In File::fsync(), FlushFileBuffers for '{fileName}' failed with {error}", "In File::fsync(), FlushFileBuffers failed", "fileName"_attr = _name, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); } } @@ -101,12 +101,12 @@ fileofs File::len() { return li.QuadPart; } _bad = true; - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2(23142, "In File::len(), GetFileSizeEx for '{fileName}' failed with {error}", "In File::len(), GetFileSizeEx failed", "fileName"_attr = _name, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); return 0; } @@ -121,12 +121,12 @@ void File::open(const char* filename, bool readOnly, bool direct) { nullptr); // template _bad = !is_open(); if (_bad) { - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2(23143, "In File::open(), CreateFileW for '{fileName}' failed with {error}", "In File::open(), CreateFileW failed", "fileName"_attr = _name, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); } } @@ -135,25 +135,25 @@ void File::read(fileofs o, char* data, unsigned len) { li.QuadPart = o; if (SetFilePointerEx(_handle, li, nullptr, FILE_BEGIN) == 0) { _bad = true; - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2(23144, "In File::read(), SetFilePointerEx for '{fileName}' tried to set the file pointer to " "{failPointer} but failed with {error}", "In File::read(), SetFilePointerEx failed to set file pointer", "fileName"_attr = _name, "failPointer"_attr = o, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); return; } DWORD bytesRead; if (!ReadFile(_handle, data, len, &bytesRead, 0)) { _bad = true; - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2(23145, "In File::read(), ReadFile for '{fileName}' failed with {error}", "In File::read(), ReadFile failed", "fileName"_attr = _name, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); } else if (bytesRead != len) { _bad = true; msgasserted(10438, @@ -171,24 +171,24 @@ void File::truncate(fileofs size) { li.QuadPart = size; if (SetFilePointerEx(_handle, li, nullptr, FILE_BEGIN) == 0) { _bad = true; - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2(23146, "In File::truncate(), SetFilePointerEx for '{fileName}' tried to set the file " "pointer to {filePointer} but failed with {error}", "In File::truncate(), SetFilePointerEx failed to set file pointer", "fileName"_attr = _name, "filePointer"_attr = size, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); return; } if (SetEndOfFile(_handle) == 0) { _bad = true; - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2(23147, "In File::truncate(), SetEndOfFile for '{fileName}' failed with {error}", "In File::truncate(), SetEndOfFile failed", "fileName"_attr = _name, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); } } @@ -197,7 +197,7 @@ void File::write(fileofs o, const char* data, unsigned len) { li.QuadPart = o; if (SetFilePointerEx(_handle, li, nullptr, FILE_BEGIN) == 0) { _bad = true; - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2( 23148, "In File::write(), SetFilePointerEx for '{fileName}' tried to set the file pointer to " @@ -205,13 +205,13 @@ void File::write(fileofs o, const char* data, unsigned len) { "In File::write(), SetFilePointerEx failed to set file pointer", "fileName"_attr = _name, "filePointer"_attr = o, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); return; } DWORD bytesWritten; if (WriteFile(_handle, data, len, &bytesWritten, nullptr) == 0) { _bad = true; - DWORD dosError = GetLastError(); + auto ec = lastSystemError(); LOGV2(23149, "In File::write(), WriteFile for '{fileName}' tried to write {bytesToWrite} bytes " "but only wrote {bytesWritten} bytes, failing with {error}", @@ -219,7 +219,7 @@ void File::write(fileofs o, const char* data, unsigned len) { "fileName"_attr = _name, "bytesToWrite"_attr = len, "bytesWritten"_attr = bytesWritten, - "error"_attr = errnoWithDescription(dosError)); + "error"_attr = errorMessage(ec)); } } @@ -239,21 +239,23 @@ intmax_t File::freeSpace(const std::string& path) { if (statvfs(path.c_str(), &info) == 0) { return static_cast<intmax_t>(info.f_bavail) * info.f_frsize; } + auto ec = lastSystemError(); LOGV2(23150, "In File::freeSpace(), statvfs for '{path}' failed with {error}", "In File::freeSpace(), statvfs failed", "path"_attr = path, - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); return -1; } void File::fsync() const { if (::fsync(_fd)) { + auto ec = lastSystemError(); LOGV2(23151, "In File::fsync(), ::fsync for '{fileName}' failed with {error}", "In File::fsync(), ::fsync failed", "fileName"_attr = _name, - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); } } @@ -267,11 +269,12 @@ fileofs File::len() { return o; } _bad = true; + auto ec = lastSystemError(); LOGV2(23152, "In File::len(), lseek for '{fileName}' failed with {error}", "In File::len(), lseek failed", "fileName"_attr = _name, - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); return 0; } @@ -290,23 +293,25 @@ void File::open(const char* filename, bool readOnly, bool direct) { S_IRUSR | S_IWUSR); _bad = !is_open(); if (_bad) { + auto ec = lastSystemError(); LOGV2(23153, "In File::open(), ::open for '{fileName}' failed with {error}", "In File::open(), ::open failed", "fileName"_attr = _name, - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); } } void File::read(fileofs o, char* data, unsigned len) { ssize_t bytesRead = ::pread(_fd, data, len, o); if (bytesRead == -1) { + auto ec = lastSystemError(); _bad = true; LOGV2(23154, "In File::read(), ::pread for '{fileName}' failed with {error}", "In File::read(), ::pread failed", "fileName"_attr = _name, - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); } else if (bytesRead != static_cast<ssize_t>(len)) { _bad = true; msgasserted(16569, @@ -321,6 +326,7 @@ void File::truncate(fileofs size) { return; } if (ftruncate(_fd, size) != 0) { + auto ec = lastSystemError(); _bad = true; LOGV2(23155, "In File::truncate(), ftruncate for '{fileName}' tried to set the file pointer to " @@ -328,7 +334,7 @@ void File::truncate(fileofs size) { "In File::truncate(), ftruncate failed to set file pointer", "fileName"_attr = _name, "filePointer"_attr = size, - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); return; } } @@ -336,6 +342,9 @@ void File::truncate(fileofs size) { void File::write(fileofs o, const char* data, unsigned len) { ssize_t bytesWritten = ::pwrite(_fd, data, len, o); if (bytesWritten != static_cast<ssize_t>(len)) { + std::error_code ec; + if (bytesWritten == -1) + ec = lastSystemError(); _bad = true; LOGV2(23156, "In File::write(), ::pwrite for '{fileName}' tried to write {bytesToWrite} bytes but " @@ -344,7 +353,7 @@ void File::write(fileofs o, const char* data, unsigned len) { "fileName"_attr = _name, "bytesToWrite"_attr = len, "bytesWritten"_attr = bytesWritten, - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); } } diff --git a/src/mongo/util/net/hostname_canonicalization.cpp b/src/mongo/util/net/hostname_canonicalization.cpp index f11ee345480..e43979b0711 100644 --- a/src/mongo/util/net/hostname_canonicalization.cpp +++ b/src/mongo/util/net/hostname_canonicalization.cpp @@ -91,15 +91,15 @@ StatusWith<std::vector<std::string>> getHostFQDNs(std::string hostName, int err; auto nativeHostName = shim_toNativeString(hostName.c_str()); if ((err = shim_getaddrinfo(nativeHostName.c_str(), nullptr, &hints, &info)) != 0) { - auto errorStr = getAddrInfoStrError(err); + auto ec = addrInfoError(err); LOGV2_DEBUG(23170, 3, "Failed to obtain address information for host {hostName}: {error}", "Failed to obtain address information for host", "hostName"_attr = hostName, - "error"_attr = errorStr); + "error"_attr = errorMessage(ec)); - return Status(ErrorCodes::BadValue, errorStr); + return Status(ErrorCodes::BadValue, errorMessage(ec)); } const ScopeGuard guard(shim_freeaddrinfo); @@ -137,7 +137,7 @@ StatusWith<std::vector<std::string>> getHostFQDNs(std::string hostName, getNameInfoError << "Unknown address family: " << p->ai_family; } - getNameInfoError << ": \"" << getAddrInfoStrError(err); + getNameInfoError << ": \"" << errorMessage(addrInfoError(err)); } getNameInfoErrors.push_back(getNameInfoError.str()); } diff --git a/src/mongo/util/net/http_client_winhttp.cpp b/src/mongo/util/net/http_client_winhttp.cpp index d972e60065e..993dfa9ab72 100644 --- a/src/mongo/util/net/http_client_winhttp.cpp +++ b/src/mongo/util/net/http_client_winhttp.cpp @@ -175,9 +175,11 @@ public: MONGO_UNREACHABLE; } - const auto uassertWithErrno = [](StringData reason, bool ok) { - const auto msg = errnoWithDescription(GetLastError()); - uassert(ErrorCodes::OperationFailed, str::stream() << reason << ": " << msg, ok); + const auto uassertWithLastSystemError = [](StringData reason, bool ok) { + auto ec = lastSystemError(); + uassert(ErrorCodes::OperationFailed, + str::stream() << reason << ": " << errorMessage(ec), + ok); }; // Break down URL for handling below. @@ -210,23 +212,24 @@ public: WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); - uassertWithErrno("Failed creating an HTTP session", session); + uassertWithLastSystemError("Failed creating an HTTP session", session); DWORD setting; DWORD settingLength = sizeof(setting); setting = WINHTTP_OPTION_REDIRECT_POLICY_NEVER; - uassertWithErrno( + uassertWithLastSystemError( "Failed setting HTTP session option", WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &setting, settingLength)); DWORD connectTimeout = durationCount<Milliseconds>(_connectTimeout); DWORD totalTimeout = durationCount<Milliseconds>(_timeout); - uassertWithErrno("Failed setting HTTP timeout", - WinHttpSetTimeouts( - session, connectTimeout, connectTimeout, totalTimeout, totalTimeout)); + uassertWithLastSystemError( + "Failed setting HTTP timeout", + WinHttpSetTimeouts( + session, connectTimeout, connectTimeout, totalTimeout, totalTimeout)); connect = WinHttpConnect(session, url.hostname.c_str(), url.port, 0); - uassertWithErrno("Failed connecting to remote host", connect); + uassertWithLastSystemError("Failed connecting to remote host", connect); request = WinHttpOpenRequest(connect, method, @@ -235,7 +238,7 @@ public: WINHTTP_NO_REFERER, const_cast<LPCWSTR*>(kAcceptTypes), url.https ? WINHTTP_FLAG_SECURE : 0); - uassertWithErrno("Failed initializing HTTP request", request); + uassertWithLastSystemError("Failed initializing HTTP request", request); if (!url.username.empty() || !url.password.empty()) { auto result = WinHttpSetCredentials(request, @@ -244,50 +247,50 @@ public: url.username.c_str(), url.password.c_str(), 0); - uassertWithErrno("Failed setting authentication credentials", result); + uassertWithLastSystemError("Failed setting authentication credentials", result); } - uassertWithErrno( + uassertWithLastSystemError( "Failed sending HTTP request", WinHttpSendRequest(request, _headers.c_str(), -1L, data, data_len, data_len, 0)); if (!WinHttpReceiveResponse(request, nullptr)) { // Carve out timeout which doesn't translate well. - const auto err = GetLastError(); - if (err == ERROR_WINHTTP_TIMEOUT) { + auto ec = lastSystemError(); + if (ec == systemError(ERROR_WINHTTP_TIMEOUT)) { uasserted(ErrorCodes::OperationFailed, "Timeout was reached"); } - const auto msg = errnoWithDescription(err); uasserted(ErrorCodes::OperationFailed, str::stream() << "Failed receiving response from server" - << ": " << msg); + << ": " << errorMessage(ec)); } DWORD statusCode = 0; DWORD statusCodeLength = sizeof(statusCode); - uassertWithErrno("Error querying status from server", - WinHttpQueryHeaders(request, - WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, - WINHTTP_HEADER_NAME_BY_INDEX, - &statusCode, - &statusCodeLength, - WINHTTP_NO_HEADER_INDEX)); + uassertWithLastSystemError( + "Error querying status from server", + WinHttpQueryHeaders(request, + WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, + WINHTTP_HEADER_NAME_BY_INDEX, + &statusCode, + &statusCodeLength, + WINHTTP_NO_HEADER_INDEX)); DWORD len = 0; std::vector<char> buffer; DataBuilder ret(4096); for (;;) { len = 0; - uassertWithErrno("Failed receiving response data", - WinHttpQueryDataAvailable(request, &len)); + uassertWithLastSystemError("Failed receiving response data", + WinHttpQueryDataAvailable(request, &len)); if (!len) { break; } buffer.resize(len); - uassertWithErrno("Failed reading response data", - WinHttpReadData(request, buffer.data(), len, &len)); + uassertWithLastSystemError("Failed reading response data", + WinHttpReadData(request, buffer.data(), len, &len)); ConstDataRange cdr(buffer.data(), len); ret.writeAndAdvance(cdr); @@ -302,13 +305,13 @@ public: WINHTTP_NO_HEADER_INDEX) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { buffer.resize(len); - uassertWithErrno("Error querying headers from server", - WinHttpQueryHeaders(request, - WINHTTP_QUERY_RAW_HEADERS_CRLF, - WINHTTP_HEADER_NAME_BY_INDEX, - &buffer[0], - &len, - WINHTTP_NO_HEADER_INDEX)); + uassertWithLastSystemError("Error querying headers from server", + WinHttpQueryHeaders(request, + WINHTTP_QUERY_RAW_HEADERS_CRLF, + WINHTTP_HEADER_NAME_BY_INDEX, + &buffer[0], + &len, + WINHTTP_NO_HEADER_INDEX)); headers.writeAndAdvance(ConstDataRange(buffer.data(), len)); } diff --git a/src/mongo/util/net/sock.cpp b/src/mongo/util/net/sock.cpp index 3a42470524a..9420f7d7946 100644 --- a/src/mongo/util/net/sock.cpp +++ b/src/mongo/util/net/sock.cpp @@ -96,13 +96,9 @@ bool setBlock(int fd, bool block) { #endif } -void networkWarnWithDescription(const Socket& socket, StringData call, int errorCode = -1) { -#ifdef _WIN32 - if (errorCode == -1) { - errorCode = WSAGetLastError(); - } -#endif - auto ewd = errnoWithDescription(errorCode); +void networkWarnWithDescription(const Socket& socket, + StringData call, + std::error_code ec = lastSocketError()) { LOGV2_WARNING(23190, "failed to connect to {remoteSocketAddress}:{remoteSocketAddressPort}, " "in({call}), reason: {error}", @@ -110,7 +106,7 @@ void networkWarnWithDescription(const Socket& socket, StringData call, int error "remoteSocketAddress"_attr = socket.remoteAddr().getAddr(), "remoteSocketAddressPort"_attr = socket.remoteAddr().getPort(), "call"_attr = call, - "error"_attr = ewd); + "error"_attr = errorMessage(ec)); } const double kMaxConnectTimeoutMS = 5000; @@ -122,18 +118,22 @@ void setSockTimeouts(int sock, double secs) { DWORD timeout = secs * 1000; // Windows timeout is a DWORD, in milliseconds. int status = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<char*>(&timeout), sizeof(DWORD)); - if (report && (status == SOCKET_ERROR)) + if (report && (status == SOCKET_ERROR)) { + auto ec = lastSocketError(); LOGV2(23177, "unable to set SO_RCVTIMEO: {reason}", "Unable to set SO_RCVTIMEO", - "reason"_attr = errnoWithDescription(WSAGetLastError())); + "reason"_attr = errorMessage(ec)); + } status = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<char*>(&timeout), sizeof(DWORD)); - if (kDebugBuild && report && (status == SOCKET_ERROR)) + if (kDebugBuild && report && (status == SOCKET_ERROR)) { + auto ec = lastSocketError(); LOGV2(23178, "unable to set SO_SNDTIMEO: {reason}", "Unable to set SO_SNDTIME0", - "reason"_attr = errnoWithDescription(WSAGetLastError())); + "reason"_attr = errorMessage(ec)); + } #else struct timeval tv; tv.tv_sec = (int)secs; @@ -157,41 +157,37 @@ void disableNagle(int sock) { const int level = SOL_SOCKET; #endif - if (setsockopt(sock, level, TCP_NODELAY, (char*)&x, sizeof(x))) + if (setsockopt(sock, level, TCP_NODELAY, (char*)&x, sizeof(x))) { + auto ec = lastSocketError(); LOGV2_ERROR(23195, "disableNagle failed: {error}", "DisableNagle failed", - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); + } #ifdef SO_KEEPALIVE - if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&x, sizeof(x))) + if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&x, sizeof(x))) { + auto ec = lastSocketError(); LOGV2_ERROR(23196, "SO_KEEPALIVE failed: {error}", "SO_KEEPALIVE failed", - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); + } #endif setSocketKeepAliveParams(sock, logv2::LogSeverity::Error()); } -int socketGetLastError() { -#ifdef _WIN32 - return WSAGetLastError(); -#else - return errno; -#endif -} - SockAddr getLocalAddrForBoundSocketFd(int fd) { SockAddr result; - int rc = getsockname(fd, result.raw(), &result.addressSize); - if (rc != 0) { + if (getsockname(fd, result.raw(), &result.addressSize)) { + auto ec = lastSocketError(); LOGV2_WARNING(23191, "Could not resolve local address for socket with fd {fd}: " "{error}", "Could not resolve local address for socket with fd", "fd"_attr = fd, - "error"_attr = getAddrInfoStrError(socketGetLastError())); + "error"_attr = errorMessage(ec)); result = SockAddr(); } return result; @@ -323,14 +319,15 @@ bool Socket::connect(const SockAddr& remote, Milliseconds connectTimeoutMillis) bool connectSucceeded = ::connect(_fd, _remote.raw(), _remote.addressSize) == 0; if (!connectSucceeded) { + auto ec = lastSocketError(); #ifdef _WIN32 - if (WSAGetLastError() != WSAEWOULDBLOCK) { - networkWarnWithDescription(*this, "connect"); + if (ec != systemError(WSAEWOULDBLOCK)) { + networkWarnWithDescription(*this, "connect", ec); return false; } #else - if (errno != EINTR && errno != EINPROGRESS) { - networkWarnWithDescription(*this, "connect"); + if (ec != posixError(EINTR) && ec != posixError(EINPROGRESS)) { + networkWarnWithDescription(*this, "connect", ec); return false; } #endif @@ -380,7 +377,8 @@ bool Socket::connect(const SockAddr& remote, Milliseconds connectTimeoutMillis) return false; } if (optVal != 0) { - networkWarnWithDescription(*this, "checking socket for error after poll", optVal); + networkWarnWithDescription( + *this, "checking socket for error after poll", systemError(optVal)); return false; } @@ -570,13 +568,15 @@ int Socket::_recv(char* buf, int max) { } void Socket::handleSendError(int ret, const char* context) { + const auto ec = lastSocketError(); + auto isTimeoutCode = [](std::error_code e) { #if defined(_WIN32) - const int mongo_errno = WSAGetLastError(); - if (mongo_errno == WSAETIMEDOUT && _timeout != 0) { + return e == systemError(WSAETIMEDOUT); #else - const int mongo_errno = errno; - if ((mongo_errno == EAGAIN || mongo_errno == EWOULDBLOCK) && _timeout != 0) { + return e == posixError(EAGAIN) || e == posixError(EWOULDBLOCK); #endif + }; + if (isTimeoutCode(ec) && _timeout != 0) { LOGV2_DEBUG(23181, _logLevel.toInt(), "Socket {context} send() timed out {remoteHost}", @@ -584,13 +584,13 @@ void Socket::handleSendError(int ret, const char* context) { "context"_attr = context, "remoteHost"_attr = remoteString()); throwSocketError(SocketErrorKind::SEND_TIMEOUT, remoteString()); - } else if (mongo_errno != EINTR) { + } else if (ec != posixError(EINTR)) { LOGV2_DEBUG(23182, _logLevel.toInt(), "Socket {context} send() {error} {remoteHost}", "Socket send() to remote host failed", "context"_attr = context, - "error"_attr = errnoWithDescription(mongo_errno), + "error"_attr = errorMessage(ec), "remoteHost"_attr = remoteString()); throwSocketError(SocketErrorKind::SEND_ERROR, remoteString()); } @@ -606,24 +606,20 @@ void Socket::handleRecvError(int ret, int len) { throwSocketError(SocketErrorKind::CLOSED, remoteString()); } -// ret < 0 -#if defined(_WIN32) - int e = WSAGetLastError(); -#else - int e = errno; + // ret < 0 + auto ec = lastSocketError(); #if defined(EINTR) - if (e == EINTR) { + if (ec == posixError(EINTR)) { return; } #endif -#endif + if ((ec == posixError(EAGAIN) #if defined(_WIN32) - // Windows - if ((e == EAGAIN || e == WSAETIMEDOUT) && _timeout > 0) { -#else - if (e == EAGAIN && _timeout > 0) { + || ec == systemError(WSAETIMEDOUT) #endif + ) && + _timeout > 0) { // this is a timeout LOGV2_DEBUG(23184, _logLevel.toInt(), @@ -637,7 +633,7 @@ void Socket::handleRecvError(int ret, int len) { _logLevel.toInt(), "Socket recv() {error} {remoteHost}", "Socket recv() error", - "error"_attr = errnoWithDescription(e), + "error"_attr = errorMessage(ec), "remoteHost"_attr = remoteString()); throwSocketError(SocketErrorKind::RECV_ERROR, remoteString()); } @@ -689,6 +685,7 @@ bool Socket::isStillConnected() { // Poll( info[], size, timeout ) - timeout == 0 => nonblocking int nEvents = socketPoll(&pollInfo, 1, 0); + auto ec = lastSocketError(); LOGV2_DEBUG( 23186, 2, @@ -709,7 +706,7 @@ bool Socket::isStillConnected() { "Socket poll() to remote host failed during connectivity check", "idleTimeSecs"_attr = idleTimeSecs, "remoteHost"_attr = remoteString(), - "error"_attr = causedBy(errnoWithDescription())); + "error"_attr = causedBy(errorMessage(ec))); // Return true since it's not clear that we're disconnected. return true; @@ -731,6 +728,7 @@ bool Socket::isStillConnected() { int recvd = ::recv(_fd, testBuf, testBufLength, portRecvFlags); if (recvd < 0) { + auto ec = lastSocketError(); // An error occurred during recv, warn and log errno LOGV2_WARNING(23194, "Socket recv() failed during connectivity check (idle {idleTimeSecs} " @@ -738,7 +736,7 @@ bool Socket::isStillConnected() { "Socket recv() failed during connectivity check", "idleTimeSecs"_attr = idleTimeSecs, "remoteHost"_attr = remoteString(), - "error"_attr = causedBy(errnoWithDescription())); + "error"_attr = causedBy(errorMessage(ec))); } else if (recvd > 0) { // We got nonzero data from this socket, very weird? // Log and warn at runtime, log and abort at devtime diff --git a/src/mongo/util/net/sockaddr.cpp b/src/mongo/util/net/sockaddr.cpp index 1a2b058cbf3..a3a0ae8753d 100644 --- a/src/mongo/util/net/sockaddr.cpp +++ b/src/mongo/util/net/sockaddr.cpp @@ -97,8 +97,8 @@ AddrInfoPtr resolveAddrInfo(StringData hostOrIp, int port, sa_family_t familyHin }; auto validateResolution = [](AddrError addrErr) -> AddrInfoPtr { - uassert(ErrorCodes::HostUnreachable, getAddrInfoStrError(addrErr.err), addrErr.err == 0); - + auto ec = addrInfoError(addrErr.err); + uassert(ErrorCodes::HostUnreachable, errorMessage(ec), !ec); return std::move(addrErr.addr); }; @@ -117,15 +117,6 @@ AddrInfoPtr resolveAddrInfo(StringData hostOrIp, int port, sa_family_t familyHin } // namespace -std::string getAddrInfoStrError(int code) { -#if !defined(_WIN32) - return gai_strerror(code); -#else - /* gai_strerrorA is not threadsafe on windows. don't use it. */ - return errnoWithDescription(code); -#endif -} - SockAddr::SockAddr() { addressSize = sizeof(sa); memset(&sa, 0, sizeof(sa)); @@ -308,8 +299,9 @@ std::string SockAddr::getAddr() const { const int buflen = 128; char buffer[buflen]; int ret = getnameinfo(raw(), addressSize, buffer, buflen, nullptr, 0, NI_NUMERICHOST); - massert( - 13082, str::stream() << "getnameinfo error " << getAddrInfoStrError(ret), ret == 0); + massert(13082, + str::stream() << "getnameinfo error " << errorMessage(addrInfoError(ret)), + ret == 0); return buffer; } diff --git a/src/mongo/util/net/sockaddr.h b/src/mongo/util/net/sockaddr.h index 66b985274c2..79e08ba1045 100644 --- a/src/mongo/util/net/sockaddr.h +++ b/src/mongo/util/net/sockaddr.h @@ -63,9 +63,6 @@ struct sockaddr_un { #endif // _WIN32 -// Generate a string representation for getaddrinfo return codes -std::string getAddrInfoStrError(int code); - /** * Wrapper around os representation of network address. */ diff --git a/src/mongo/util/net/socket_utils.cpp b/src/mongo/util/net/socket_utils.cpp index d4236cafa28..f15bb3ca96b 100644 --- a/src/mongo/util/net/socket_utils.cpp +++ b/src/mongo/util/net/socket_utils.cpp @@ -69,11 +69,11 @@ namespace mongo { const struct WinsockInit { WinsockInit() { WSADATA d; - if (WSAStartup(MAKEWORD(2, 2), &d) != 0) { + if (int e = WSAStartup(MAKEWORD(2, 2), &d)) { LOGV2(23201, "ERROR: wsastartup failed {error}", "ERROR: wsastartup failed", - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(systemError(e))); quickExit(EXIT_NTSERVICE_ERROR); } } @@ -150,12 +150,12 @@ void setSocketKeepAliveParams(int sock, &sent, nullptr, nullptr)) { - int wsaErr = WSAGetLastError(); + auto ec = lastSocketError(); LOGV2_DEBUG(23204, logSeverity, "failed setting keepalive values: {error}", "Failed setting keepalive values", - "error"_attr = errnoWithDescription(wsaErr)); + "error"_attr = errorMessage(ec)); } } #elif defined(__APPLE__) || defined(__linux__) @@ -165,13 +165,13 @@ void setSocketKeepAliveParams(int sock, socklen_t optValLen = sizeof(rawOptVal); if (getsockopt(sock, level, optnum, reinterpret_cast<char*>(&rawOptVal), &optValLen)) { - int savedErrno = errno; + auto ec = lastSystemError(); LOGV2_DEBUG(23205, logSeverity, "can't get {optname}: {error}", "Can't get socket option", "optname"_attr = optname, - "error"_attr = errnoWithDescription(savedErrno)); + "error"_attr = errorMessage(ec)); } if (optVal > maxVal) { @@ -179,13 +179,13 @@ void setSocketKeepAliveParams(int sock, socklen_t maxValLen = sizeof(rawMaxVal); if (setsockopt(sock, level, optnum, reinterpret_cast<char*>(&rawMaxVal), maxValLen)) { - int savedErrno = errno; + auto ec = lastSystemError(); LOGV2_DEBUG(23206, logSeverity, "can't set {optname}: {error}", "Can't set socket option", "optname"_attr = optname, - "error"_attr = errnoWithDescription(savedErrno)); + "error"_attr = errorMessage(ec)); } } }; @@ -234,10 +234,11 @@ std::string getHostName() { char buf[256]; int ec = gethostname(buf, 127); if (ec || *buf == 0) { + auto ec = lastSocketError(); LOGV2(23202, "can't get this server's hostname {error}", "Can't get this server's hostname", - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); return ""; } return buf; diff --git a/src/mongo/util/net/ssl/impl/error.ipp b/src/mongo/util/net/ssl/impl/error.ipp index abe179c33a7..fd2c5f5c2c2 100644 --- a/src/mongo/util/net/ssl/impl/error.ipp +++ b/src/mongo/util/net/ssl/impl/error.ipp @@ -40,7 +40,7 @@ public: if (value == asio::ssl::error::no_renegotiation) { return "peer requested renegotiation, which is not supported"; } - return mongo::errnoWithDescription(value); + return std::system_category().message(value); } #elif MONGO_CONFIG_SSL_PROVIDER == MONGO_CONFIG_SSL_PROVIDER_OPENSSL std::string message(int value) const { diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp index f2ddee148c7..7651d286be1 100644 --- a/src/mongo/util/net/ssl_manager_openssl.cpp +++ b/src/mongo/util/net/ssl_manager_openssl.cpp @@ -3561,10 +3561,11 @@ void SSLManagerOpenSSL::_handleSSLError(SSLConnectionOpenSSL* conn, int ret) { } else if (ret == 0) { LOGV2_ERROR(23261, "Unexpected EOF encountered during SSL communication"); } else { + auto ec = lastSystemError(); LOGV2_ERROR(23262, "The SSL BIO reported an I/O error {error}", "The SSL BIO reported an I/O error", - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); } break; case SSL_ERROR_SSL: { diff --git a/src/mongo/util/net/ssl_manager_windows.cpp b/src/mongo/util/net/ssl_manager_windows.cpp index adf86ae847f..fbaa983b0fb 100644 --- a/src/mongo/util/net/ssl_manager_windows.cpp +++ b/src/mongo/util/net/ssl_manager_windows.cpp @@ -488,12 +488,11 @@ StatusWith<UniqueCertChainEngine> initChainEngine(CERT_CHAIN_ENGINE_CONFIG* chai chainEngineConfig->dwFlags = flags; HCERTCHAINENGINE chainEngine; - BOOL ret = CertCreateCertificateChainEngine(chainEngineConfig, &chainEngine); - if (!ret) { - DWORD gle = GetLastError(); + if (!CertCreateCertificateChainEngine(chainEngineConfig, &chainEngine)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertCreateCertificateChainEngine failed: " - << errnoWithDescription(gle)); + str::stream() + << "CertCreateCertificateChainEngine failed: " << errorMessage(ec)); } return {chainEngine}; @@ -633,32 +632,30 @@ StatusWith<std::string> readFile(StringData fileName) { StatusWith<std::vector<BYTE>> decodePEMBlob(StringData blob) { DWORD decodeLen{0}; - BOOL ret = CryptStringToBinaryA( - blob.rawData(), blob.size(), CRYPT_STRING_BASE64HEADER, NULL, &decodeLen, NULL, NULL); - if (!ret) { - DWORD gle = GetLastError(); - if (gle != ERROR_MORE_DATA) { + if (!CryptStringToBinaryA( + blob.rawData(), blob.size(), CRYPT_STRING_BASE64HEADER, NULL, &decodeLen, NULL, NULL)) { + auto ec = lastSystemError(); + if (ec != systemError(ERROR_MORE_DATA)) { return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "CryptStringToBinary failed to get size of key: " - << errnoWithDescription(gle)); + << errorMessage(ec)); } } std::vector<BYTE> binaryBlobBuf; binaryBlobBuf.resize(decodeLen); - ret = CryptStringToBinaryA(blob.rawData(), - blob.size(), - CRYPT_STRING_BASE64HEADER, - binaryBlobBuf.data(), - &decodeLen, - NULL, - NULL); - if (!ret) { - DWORD gle = GetLastError(); + if (!CryptStringToBinaryA(blob.rawData(), + blob.size(), + CRYPT_STRING_BASE64HEADER, + binaryBlobBuf.data(), + &decodeLen, + NULL, + NULL)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CryptStringToBinary failed to read key: " - << errnoWithDescription(gle)); + str::stream() + << "CryptStringToBinary failed to read key: " << errorMessage(ec)); } return std::move(binaryBlobBuf); @@ -669,27 +666,31 @@ StatusWith<std::vector<BYTE>> decodeObject(const char* structType, size_t length) { DWORD decodeLen{0}; - BOOL ret = - CryptDecodeObjectEx(X509_ASN_ENCODING, structType, data, length, 0, NULL, NULL, &decodeLen); - if (!ret) { - DWORD gle = GetLastError(); - if (gle != ERROR_MORE_DATA) { + if (!CryptDecodeObjectEx( + X509_ASN_ENCODING, structType, data, length, 0, NULL, NULL, &decodeLen)) { + auto ec = lastSystemError(); + if (ec != systemError(ERROR_MORE_DATA)) { return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "CryptDecodeObjectEx failed to get size of object: " - << errnoWithDescription(gle)); + << errorMessage(ec)); } } std::vector<BYTE> binaryBlobBuf; binaryBlobBuf.resize(decodeLen); - ret = CryptDecodeObjectEx( - X509_ASN_ENCODING, structType, data, length, 0, NULL, binaryBlobBuf.data(), &decodeLen); - if (!ret) { - DWORD gle = GetLastError(); + if (!CryptDecodeObjectEx(X509_ASN_ENCODING, + structType, + data, + length, + 0, + NULL, + binaryBlobBuf.data(), + &decodeLen)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CryptDecodeObjectEx failed to read object: " - << errnoWithDescription(gle)); + str::stream() + << "CryptDecodeObjectEx failed to read object: " << errorMessage(ec)); } return std::move(binaryBlobBuf); @@ -733,11 +734,11 @@ StatusWith<std::vector<UniqueCertificate>> readCAPEMBuffer(StringData buffer) { PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING, certBuf.data(), certBuf.size()); - if (cert == NULL) { - DWORD gle = GetLastError(); + if (!cert) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "CertCreateCertificateContext failed to decode cert: " - << errnoWithDescription(gle)); + << errorMessage(ec)); } certs.emplace_back(cert); @@ -748,14 +749,11 @@ StatusWith<std::vector<UniqueCertificate>> readCAPEMBuffer(StringData buffer) { Status addCertificatesToStore(HCERTSTORE certStore, std::vector<UniqueCertificate>& certificates) { for (auto& cert : certificates) { - BOOL ret = - CertAddCertificateContextToStore(certStore, cert.get(), CERT_STORE_ADD_NEW, NULL); - - if (!ret) { - DWORD gle = GetLastError(); + if (!CertAddCertificateContextToStore(certStore, cert.get(), CERT_STORE_ADD_NEW, NULL)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertAddCertificateContextToStore Failed " - << errnoWithDescription(gle)); + str::stream() + << "CertAddCertificateContextToStore Failed " << errorMessage(ec)); } } @@ -816,34 +814,32 @@ StatusWith<UniqueCertificateWithPrivateKey> readCertPEMFile(StringData fileName, PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING, certBuf.data(), certBuf.size()); - if (cert == NULL) { - DWORD gle = GetLastError(); + if (!cert) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "CertCreateCertificateContext failed to decode cert: " - << errnoWithDescription(gle)); + << errorMessage(ec)); } UniqueCertificate tempCertHolder(cert); HCERTSTORE store = CertOpenStore( CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL); - if (store == NULL) { - DWORD gle = GetLastError(); + if (!store) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertOpenStore failed to create memory store: " - << errnoWithDescription(gle)); + str::stream() + << "CertOpenStore failed to create memory store: " << errorMessage(ec)); } UniqueCertStore storeHolder(store); // Add the newly created certificate to the memory store, this makes a copy - BOOL ret = CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_NEW, NULL); - - if (!ret) { - DWORD gle = GetLastError(); + if (!CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_NEW, NULL)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "CertAddCertificateContextToStore Memory Failed " - << errnoWithDescription(gle)); + << errorMessage(ec)); } // Get the certificate from the store so we attach the private key to the cert in the store @@ -938,47 +934,45 @@ StatusWith<UniqueCertificateWithPrivateKey> readCertPEMFile(StringData fileName, // default // container is shared across processes owned by the same user. // Note: Server side Schannel requires CRYPT_VERIFYCONTEXT off - ret = CryptAcquireContextW( - &hProv, wstr.c_str(), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_SILENT); - if (!ret) { - DWORD gle = GetLastError(); - - if (gle == NTE_EXISTS) { - - ret = CryptAcquireContextW( - &hProv, wstr.c_str(), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_SILENT); - if (!ret) { - DWORD gle = GetLastError(); + if (!CryptAcquireContextW(&hProv, + wstr.c_str(), + MS_ENHANCED_PROV, + PROV_RSA_FULL, + CRYPT_NEWKEYSET | CRYPT_SILENT)) { + auto ec = lastSystemError(); + if (ec == systemError(NTE_EXISTS)) { + if (!CryptAcquireContextW( + &hProv, wstr.c_str(), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_SILENT)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CryptAcquireContextW failed " - << errnoWithDescription(gle)); + str::stream() + << "CryptAcquireContextW failed " << errorMessage(ec)); } } else { return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() - << "CryptAcquireContextW failed " << errnoWithDescription(gle)); + str::stream() << "CryptAcquireContextW failed " << errorMessage(ec)); } } } else { // Use a transient key container for the key - ret = CryptAcquireContextW( - &hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT); - if (!ret) { - DWORD gle = GetLastError(); + if (!CryptAcquireContextW(&hProv, + NULL, + MS_ENHANCED_PROV, + PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() - << "CryptAcquireContextW failed " << errnoWithDescription(gle)); + str::stream() << "CryptAcquireContextW failed " << errorMessage(ec)); } } UniqueCryptProvider cryptProvider(hProv); HCRYPTKEY hkey; - ret = CryptImportKey(hProv, privateKey.data(), privateKey.size(), 0, 0, &hkey); - if (!ret) { - DWORD gle = GetLastError(); + if (!CryptImportKey(hProv, privateKey.data(), privateKey.size(), 0, 0, &hkey)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CryptImportKey failed " << errnoWithDescription(gle)); + str::stream() << "CryptImportKey failed " << errorMessage(ec)); } UniqueCryptKey keyHolder(hkey); @@ -995,21 +989,20 @@ StatusWith<UniqueCertificateWithPrivateKey> readCertPEMFile(StringData fileName, if (!CertSetCertificateContextProperty( certHolder.get(), CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo)) { - DWORD gle = GetLastError(); + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertSetCertificateContextProperty Failed " - << errnoWithDescription(gle)); + str::stream() + << "CertSetCertificateContextProperty Failed " << errorMessage(ec)); } } // NOTE: This is used to set the certificate for client side SChannel - ret = CertSetCertificateContextProperty( - cert, CERT_KEY_PROV_HANDLE_PROP_ID, 0, (const void*)hProv); - if (!ret) { - DWORD gle = GetLastError(); + if (!CertSetCertificateContextProperty( + cert, CERT_KEY_PROV_HANDLE_PROP_ID, 0, (const void*)hProv)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertSetCertificateContextProperty failed " - << errnoWithDescription(gle)); + str::stream() + << "CertSetCertificateContextProperty failed " << errorMessage(ec)); } // Add the extra certificates into the same certificate store as the certificate @@ -1081,22 +1074,19 @@ Status readCRLPEMFile(HCERTSTORE certStore, StringData fileName) { auto certBuf = swCert.getValue(); PCCRL_CONTEXT crl = CertCreateCRLContext(X509_ASN_ENCODING, certBuf.data(), certBuf.size()); - if (crl == NULL) { - DWORD gle = GetLastError(); + if (!crl) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertCreateCRLContext failed to decode crl: " - << errnoWithDescription(gle)); + str::stream() + << "CertCreateCRLContext failed to decode crl: " << errorMessage(ec)); } UniqueCRL crlHolder(crl); - BOOL ret = CertAddCRLContextToStore(certStore, crl, CERT_STORE_ADD_NEW, NULL); - - if (!ret) { - DWORD gle = GetLastError(); + if (!CertAddCRLContextToStore(certStore, crl, CERT_STORE_ADD_NEW, NULL)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() - << "CertAddCRLContextToStore Failed " << errnoWithDescription(gle)); + str::stream() << "CertAddCRLContextToStore Failed " << errorMessage(ec)); } } @@ -1105,10 +1095,10 @@ Status readCRLPEMFile(HCERTSTORE certStore, StringData fileName) { StatusWith<UniqueCertStore> readCertChains(StringData caFile, StringData crlFile) { UniqueCertStore certStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); - if (certStore == nullptr) { - DWORD gle = GetLastError(); + if (!certStore) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertOpenStore Failed " << errnoWithDescription(gle)); + str::stream() << "CertOpenStore Failed " << errorMessage(ec)); } auto status = readCAPEMFile(certStore, caFile); @@ -1139,11 +1129,11 @@ StatusWith<UniqueCertificate> loadCertificateSelectorFromStore( storeType | CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG | CERT_STORE_READONLY_FLAG, L"My"); - if (store == NULL) { - DWORD gle = GetLastError(); + if (!store) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "CertOpenStore failed to open store 'My' from '" << storeName - << "': " << errnoWithDescription(gle)); + << "': " << errorMessage(ec)); } UniqueCertStore storeHolder(store); @@ -1157,14 +1147,14 @@ StatusWith<UniqueCertificate> loadCertificateSelectorFromStore( CERT_FIND_SUBJECT_STR, wstr.c_str(), NULL); - if (cert == NULL) { - DWORD gle = GetLastError(); + if (!cert) { + auto ec = lastSystemError(); return Status( ErrorCodes::InvalidSSLConfiguration, str::stream() << "CertFindCertificateInStore failed to find cert with subject name '" << selector.subject.c_str() << "' in 'My' store in '" << storeName - << "': " << errnoWithDescription(gle)); + << "': " << errorMessage(ec)); } return UniqueCertificate(cert); @@ -1178,15 +1168,14 @@ StatusWith<UniqueCertificate> loadCertificateSelectorFromStore( CERT_FIND_HASH, &hashBlob, NULL); - if (cert == NULL) { - DWORD gle = GetLastError(); + if (!cert) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "CertFindCertificateInStore failed to find cert with thumbprint '" << hexblob::encode(selector.thumbprint.data(), selector.thumbprint.size()) - << "' in 'My' store in '" << storeName - << "': " << errnoWithDescription(gle)); + << "' in 'My' store in '" << storeName << "': " << errorMessage(ec)); } return UniqueCertificate(cert); @@ -1220,27 +1209,26 @@ StatusWith<UniqueCertificate> loadAndValidateCertificateSelector( DWORD dwKeySpec; BOOL freeProvider; HCRYPTPROV hCryptProv; - BOOL ret = CryptAcquireCertificatePrivateKey(swCert.getValue().get(), - CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, - NULL, - &hCryptProv, - &dwKeySpec, - &freeProvider); - if (!ret) { - DWORD gle = GetLastError(); - if (gle == CRYPT_E_NO_KEY_PROPERTY) { + if (!CryptAcquireCertificatePrivateKey(swCert.getValue().get(), + CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, + NULL, + &hCryptProv, + &dwKeySpec, + &freeProvider)) { + auto ec = lastSystemError(); + if (ec == systemError(CRYPT_E_NO_KEY_PROPERTY)) { return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "Could not find private key attached to the selected certificate"); - } else if (gle == NTE_BAD_KEYSET) { + } else if (ec == systemError(NTE_BAD_KEYSET)) { return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "Could not read private key attached to the selected " "certificate, ensure it exists and check the private " "key permissions"); } else { return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CryptAcquireCertificatePrivateKey failed " - << errnoWithDescription(gle)); + str::stream() + << "CryptAcquireCertificatePrivateKey failed " << errorMessage(ec)); } } @@ -1751,19 +1739,17 @@ Status validatePeerCertificate(const std::string& remoteHost, auto before = Date_t::now(); PCCERT_CHAIN_CONTEXT chainContext; - BOOL ret = CertGetCertificateChain(certChainEngine, - cert, - NULL, - cert->hCertStore, - &certChainPara, - CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, - NULL, - &chainContext); - if (!ret) { - DWORD gle = GetLastError(); + if (!CertGetCertificateChain(certChainEngine, + cert, + NULL, + cert->hCertStore, + &certChainPara, + CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, + NULL, + &chainContext)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() - << "CertGetCertificateChain failed: " << errnoWithDescription(gle)); + str::stream() << "CertGetCertificateChain failed: " << errorMessage(ec)); } auto after = Date_t::now(); @@ -1803,15 +1789,16 @@ Status validatePeerCertificate(const std::string& remoteHost, memset(&certChainPolicyStatus, 0, sizeof(certChainPolicyStatus)); certChainPolicyStatus.cbSize = sizeof(certChainPolicyStatus); - ret = CertVerifyCertificateChainPolicy( - CERT_CHAIN_POLICY_SSL, certChainHolder.get(), &chain_policy_para, &certChainPolicyStatus); // This means something really went wrong, this should not happen. - if (!ret) { - DWORD gle = GetLastError(); + if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, + certChainHolder.get(), + &chain_policy_para, + &certChainPolicyStatus)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertVerifyCertificateChainPolicy failed: " - << errnoWithDescription(gle)); + str::stream() + << "CertVerifyCertificateChainPolicy failed: " << errorMessage(ec)); } auto swSubjectName = getCertificateSubjectName(cert); @@ -1849,17 +1836,16 @@ Status validatePeerCertificate(const std::string& remoteHost, // We know the CNs do not match, are there any other issues? sslCertChainPolicy.fdwChecks = SECURITY_FLAG_IGNORE_CERT_CN_INVALID; - ret = CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, - certChainHolder.get(), - &chain_policy_para, - &certChainPolicyStatus); // This means something really went wrong, this should not happen. - if (!ret) { - DWORD gle = GetLastError(); + if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, + certChainHolder.get(), + &chain_policy_para, + &certChainPolicyStatus)) { + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "CertVerifyCertificateChainPolicy2 failed: " - << errnoWithDescription(gle)); + << errorMessage(ec)); } if (certChainPolicyStatus.dwError == S_OK || @@ -1913,7 +1899,8 @@ Status validatePeerCertificate(const std::string& remoteHost, "SSL peer certificate validation failed ({errorCode}): {error}", "SSL peer certificate validation failed", "errorCode"_attr = unsignedHex(certChainPolicyStatus.dwError), - "error"_attr = errnoWithDescription(certChainPolicyStatus.dwError)); + "error"_attr = + errorMessage(systemError(certChainPolicyStatus.dwError))); if (certChainPolicyStatus.dwError == CERT_E_CN_NO_MATCH) { LOGV2_WARNING(23275, @@ -1941,14 +1928,14 @@ Status validatePeerCertificate(const std::string& remoteHost, str::stream msg; msg << "SSL peer certificate validation failed: (" << unsignedHex(certChainPolicyStatus.dwError) << ")" - << errnoWithDescription(certChainPolicyStatus.dwError); + << errorMessage(systemError(certChainPolicyStatus.dwError)); LOGV2_ERROR(23279, "SSL peer certificate validation failed: ({errorCode}){error}", "SSL peer certificate validation failed", "errorCode"_attr = unsignedHex(certChainPolicyStatus.dwError), - "error"_attr = errnoWithDescription(certChainPolicyStatus.dwError)); + "error"_attr = errorMessage(systemError(certChainPolicyStatus.dwError))); return Status(ErrorCodes::SSLHandshakeFailed, msg); } } @@ -2104,10 +2091,10 @@ Status getCertInfo(CertInformationToLog* info, PCCERT_CONTEXT cert) { if (!CertGetCertificateContextProperty( cert, CERT_SHA1_HASH_PROP_ID, info->thumbprint.data(), &bufSize)) { - DWORD gle = GetLastError(); + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, str::stream() << "getCertInfo failed to get certificate thumbprint: " - << errnoWithDescription(gle)); + << errorMessage(ec)); } info->hexEncodedThumbprint = hexblob::encode(info->thumbprint.data(), info->thumbprint.size()); @@ -2125,10 +2112,10 @@ Status getCRLInfo(CRLInformationToLog* info, PCCRL_CONTEXT crl) { if (!CertGetCRLContextProperty( crl, CERT_SHA1_HASH_PROP_ID, info->thumbprint.data(), &bufSize)) { - DWORD gle = GetLastError(); + auto ec = lastSystemError(); return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "getCRLInfo failed to get CRL thumbprint: " - << errnoWithDescription(gle)); + str::stream() + << "getCRLInfo failed to get CRL thumbprint: " << errorMessage(ec)); } info->validityNotBefore = diff --git a/src/mongo/util/ntservice.cpp b/src/mongo/util/ntservice.cpp index e59533a6b44..1abef2bdb2b 100644 --- a/src/mongo/util/ntservice.cpp +++ b/src/mongo/util/ntservice.cpp @@ -455,10 +455,10 @@ void installServiceOrDie(const wstring& serviceName, BOOL ret = ::ChangeServiceConfig2( schService, SERVICE_CONFIG_PRESHUTDOWN_INFO, &servicePreshutdownInfo); if (!ret) { - DWORD gle = ::GetLastError(); + auto ec = lastSystemError(); LOGV2_ERROR(23317, "Failed to set timeout for pre-shutdown notification", - "__error__"_attr = errnoWithDescription(gle)); + "__error__"_attr = errorMessage(ec)); serviceInstalled = false; } diff --git a/src/mongo/util/options_parser/options_parser.cpp b/src/mongo/util/options_parser/options_parser.cpp index ad51118032b..4146d5b63a0 100644 --- a/src/mongo/util/options_parser/options_parser.cpp +++ b/src/mongo/util/options_parser/options_parser.cpp @@ -1364,8 +1364,9 @@ Status checkFileOwnershipAndMode(int fd, mode_t prohibit, StringData modeDesc) { struct stat stats; if (::fstat(fd, &stats) == -1) { - const auto& ewd = errnoWithDescription(); - return {ErrorCodes::InvalidPath, str::stream() << "Error reading file metadata: " << ewd}; + auto ec = lastSystemError(); + return {ErrorCodes::InvalidPath, + str::stream() << "Error reading file metadata: " << errorMessage(ec)}; } if (stats.st_uid != ::getuid()) { @@ -1437,8 +1438,9 @@ Status OptionsParser::readConfigFile(const std::string& filename, #endif if (fd < 0) { - const auto& ewd = errnoWithDescription(); - return {ErrorCodes::InternalError, str::stream() << "Error opening config file: " << ewd}; + auto ec = lastPosixError(); + return {ErrorCodes::InternalError, + str::stream() << "Error opening config file: " << errorMessage(ec)}; } #ifdef _WIN32 diff --git a/src/mongo/util/password.cpp b/src/mongo/util/password.cpp index 49a4a54db02..447cbd2ca13 100644 --- a/src/mongo/util/password.cpp +++ b/src/mongo/util/password.cpp @@ -59,14 +59,16 @@ std::string askPassword() { if (isatty(stdinfd)) { int i = tcgetattr(stdinfd, &termio); if (i == -1) { - std::cerr << "Cannot get terminal attributes " << errnoWithDescription() << std::endl; + auto ec = lastSystemError(); + std::cerr << "Cannot get terminal attributes " << errorMessage(ec) << std::endl; return std::string(); } old = termio.c_lflag; termio.c_lflag &= ~ECHO; i = tcsetattr(stdinfd, TCSANOW, &termio); if (i == -1) { - std::cerr << "Cannot set terminal attributes " << errnoWithDescription() << std::endl; + auto ec = lastSystemError(); + std::cerr << "Cannot set terminal attributes " << errorMessage(ec) << std::endl; return std::string(); } } @@ -77,33 +79,38 @@ std::string askPassword() { termio.c_lflag = old; int i = tcsetattr(stdinfd, TCSANOW, &termio); if (i == -1) { - std::cerr << "Cannot set terminal attributes " << errnoWithDescription() << std::endl; + auto ec = lastSystemError(); + std::cerr << "Cannot set terminal attributes " << errorMessage(ec) << std::endl; return std::string(); } } #else HANDLE stdinh = GetStdHandle(STD_INPUT_HANDLE); if (stdinh == INVALID_HANDLE_VALUE) { - std::cerr << "Cannot get stdin handle " << GetLastError() << "\n"; + auto ec = lastSystemError(); + std::cerr << "Cannot get stdin handle " << errorMessage(ec) << "\n"; return std::string(); } DWORD old; if (!GetConsoleMode(stdinh, &old)) { - std::cerr << "Cannot get console mode " << GetLastError() << "\n"; + auto ec = lastSystemError(); + std::cerr << "Cannot get console mode " << errorMessage(ec) << "\n"; return std::string(); } DWORD noecho = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; if (!SetConsoleMode(stdinh, noecho)) { - std::cerr << "Cannot set console mode " << GetLastError() << "\n"; + auto ec = lastSystemError(); + std::cerr << "Cannot set console mode " << errorMessage(ec) << "\n"; return std::string(); } getline(std::cin, password); if (!SetConsoleMode(stdinh, old)) { - std::cerr << "Cannot set console mode " << GetLastError() << "\n"; + auto ec = lastSystemError(); + std::cerr << "Cannot set console mode " << errorMessage(ec) << "\n"; return std::string(); } #endif diff --git a/src/mongo/util/perfctr_collect.cpp b/src/mongo/util/perfctr_collect.cpp index 7b9c6413608..0fe8926f7b1 100644 --- a/src/mongo/util/perfctr_collect.cpp +++ b/src/mongo/util/perfctr_collect.cpp @@ -54,10 +54,9 @@ MONGO_INITIALIZER(PdhInit)(InitializerContext* context) { hPdhLibrary = LoadLibraryW(L"pdh.dll"); if (nullptr == hPdhLibrary) { - DWORD gle = GetLastError(); + auto ec = lastSystemError(); uasserted(ErrorCodes::WindowsPdhError, - str::stream() << "LoadLibrary of pdh.dll failed with " - << errnoWithDescription(gle)); + str::stream() << "LoadLibrary of pdh.dll failed with " << errorMessage(ec)); } } diff --git a/src/mongo/util/processinfo_linux.cpp b/src/mongo/util/processinfo_linux.cpp index 37e3d2ea3fc..49b95e5093e 100644 --- a/src/mongo/util/processinfo_linux.cpp +++ b/src/mongo/util/processinfo_linux.cpp @@ -75,8 +75,8 @@ public: auto name = "/proc/{}/stat"_format(pid.asUInt32()); FILE* f = fopen(name.c_str(), "r"); if (!f) { - auto e = errno; - msgasserted(13538, "couldn't open [{}] {}"_format(name, errnoWithDescription(e))); + auto ec = lastSystemError(); + msgasserted(13538, "couldn't open [{}] {}"_format(name, errorMessage(ec))); } int found = fscanf(f, "%d %127s %c " @@ -664,10 +664,10 @@ void ProcessInfo::SystemInfo::collectSystemInfo() { LinuxSysHelper::getLinuxDistro(distroName, distroVersion); if (uname(&unameData) == -1) { - auto e = errno; + auto ec = lastSystemError(); LOGV2(23339, "Unable to collect detailed system information", - "error"_attr = errnoWithDescription(e)); + "error"_attr = errorMessage(ec)); } osType = "Linux"; diff --git a/src/mongo/util/processinfo_solaris.cpp b/src/mongo/util/processinfo_solaris.cpp index 95598132526..5fbb815985c 100644 --- a/src/mongo/util/processinfo_solaris.cpp +++ b/src/mongo/util/processinfo_solaris.cpp @@ -68,15 +68,17 @@ static std::string readLineFromFile(const char* fname) { struct ProcPsinfo { ProcPsinfo() { FILE* f = fopen("/proc/self/psinfo", "r"); - massert(16846, - str::stream() << "couldn't open \"/proc/self/psinfo\": " << errnoWithDescription(), - f); + if (!f) { + auto ec = lastSystemError(); + msgasserted(16846, + str::stream() + << "couldn't open \"/proc/self/psinfo\": " << errorMessage(ec)); + } size_t num = fread(&psinfo, sizeof(psinfo), 1, f); - int err = errno; + auto ec = lastSystemError(); fclose(f); massert(16847, - str::stream() << "couldn't read from \"/proc/self/psinfo\": " - << errnoWithDescription(err), + str::stream() << "couldn't read from \"/proc/self/psinfo\": " << errorMessage(ec), num == 1); } psinfo_t psinfo; @@ -85,15 +87,16 @@ struct ProcPsinfo { struct ProcUsage { ProcUsage() { FILE* f = fopen("/proc/self/usage", "r"); - massert(16848, - str::stream() << "couldn't open \"/proc/self/usage\": " << errnoWithDescription(), - f); + if (!f) { + auto ec = lastSystemError(); + msgasserted( + 16848, str::stream() << "couldn't open \"/proc/self/usage\": " << errorMessage(ec)); + } size_t num = fread(&prusage, sizeof(prusage), 1, f); - int err = errno; + auto ec = lastSystemError(); fclose(f); massert(16849, - str::stream() << "couldn't read from \"/proc/self/usage\": " - << errnoWithDescription(err), + str::stream() << "couldn't read from \"/proc/self/usage\": " << errorMessage(ec), num == 1); } prusage_t prusage; @@ -202,9 +205,10 @@ bool ProcessInfo::checkNumaEnabled() { lgrp_cookie_t cookie = lgrp_init(LGRP_VIEW_OS); if (cookie == LGRP_COOKIE_NONE) { + auto ec = lastSystemError(); LOGV2_WARNING(23362, "lgrp_init failed: {errnoWithDescription}", - "errnoWithDescription"_attr = errnoWithDescription()); + "errnoWithDescription"_attr = errorMessage(ec)); return false; } @@ -213,9 +217,10 @@ bool ProcessInfo::checkNumaEnabled() { int groups = lgrp_nlgrps(cookie); if (groups == -1) { + auto ec = lastSystemError(); LOGV2_WARNING(23363, "lgrp_nlgrps failed: {errnoWithDescription}", - "errnoWithDescription"_attr = errnoWithDescription()); + "errnoWithDescription"_attr = errorMessage(ec)); return false; } diff --git a/src/mongo/util/processinfo_windows.cpp b/src/mongo/util/processinfo_windows.cpp index 5cf7edbdee2..214ef5643cd 100644 --- a/src/mongo/util/processinfo_windows.cpp +++ b/src/mongo/util/processinfo_windows.cpp @@ -77,10 +77,10 @@ LpiRecords getLogicalProcessorInformationRecords() { lpiRecords.slpiRecords = std::unique_ptr<SlpiBuf[]>( new SlpiBuf[((returnLength - 1) / sizeof(Slpi)) + 1]); } else { - DWORD gle = GetLastError(); + auto ec = lastSystemError(); LOGV2_WARNING(23811, "GetLogicalProcessorInformation failed", - "error"_attr = errnoWithDescription(gle)); + "error"_attr = errorMessage(ec)); return LpiRecords{}; } } @@ -147,8 +147,8 @@ int ProcessInfo::getVirtualMemorySize() { mse.dwLength = sizeof(mse); BOOL status = GlobalMemoryStatusEx(&mse); if (!status) { - DWORD gle = GetLastError(); - LOGV2_ERROR(23812, "GlobalMemoryStatusEx failed", "error"_attr = errnoWithDescription(gle)); + auto ec = lastSystemError(); + LOGV2_ERROR(23812, "GlobalMemoryStatusEx failed", "error"_attr = errorMessage(ec)); fassert(28621, status); } @@ -161,8 +161,8 @@ int ProcessInfo::getResidentSize() { PROCESS_MEMORY_COUNTERS pmc; BOOL status = GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); if (!status) { - DWORD gle = GetLastError(); - LOGV2_ERROR(23813, "GetProcessMemoryInfo failed", "error"_attr = errnoWithDescription(gle)); + auto ec = lastSystemError(); + LOGV2_ERROR(23813, "GetProcessMemoryInfo failed", "error"_attr = errorMessage(ec)); fassert(28622, status); } @@ -193,32 +193,32 @@ void ProcessInfo::getExtraInfo(BSONObjBuilder& info) { bool getFileVersion(const char* filePath, DWORD& fileVersionMS, DWORD& fileVersionLS) { DWORD verSize = GetFileVersionInfoSizeA(filePath, NULL); if (verSize == 0) { - DWORD gle = GetLastError(); + auto ec = lastSystemError(); LOGV2_WARNING(23807, "GetFileVersionInfoSizeA failed", "path"_attr = filePath, - "error"_attr = errnoWithDescription(gle)); + "error"_attr = errorMessage(ec)); return false; } std::unique_ptr<char[]> verData(new char[verSize]); if (GetFileVersionInfoA(filePath, NULL, verSize, verData.get()) == 0) { - DWORD gle = GetLastError(); + auto ec = lastSystemError(); LOGV2_WARNING(23808, "GetFileVersionInfoSizeA failed", "path"_attr = filePath, - "error"_attr = errnoWithDescription(gle)); + "error"_attr = errorMessage(ec)); return false; } UINT size; VS_FIXEDFILEINFO* verInfo; if (VerQueryValueA(verData.get(), "\\", (LPVOID*)&verInfo, &size) == 0) { - DWORD gle = GetLastError(); + auto ec = lastSystemError(); LOGV2_WARNING(23809, "VerQueryValueA failed", "path"_attr = filePath, - "error"_attr = errnoWithDescription(gle)); + "error"_attr = errorMessage(ec)); return false; } diff --git a/src/mongo/util/procparser.cpp b/src/mongo/util/procparser.cpp index 599608c9cc8..c1d85bbf71a 100644 --- a/src/mongo/util/procparser.cpp +++ b/src/mongo/util/procparser.cpp @@ -92,10 +92,10 @@ constexpr auto kSysBlockDeviceDirectoryName = "device"; StatusWith<std::string> readFileAsString(StringData filename) { int fd = open(filename.toString().c_str(), 0); if (fd == -1) { - int err = errno; + auto ec = lastSystemError(); return Status(ErrorCodes::FileOpenFailed, str::stream() << "Failed to open file " << filename - << " with error: " << errnoWithDescription(err)); + << " with error: " << errorMessage(ec)); } ScopeGuard scopedGuard([fd] { close(fd); }); @@ -114,17 +114,18 @@ StatusWith<std::string> readFileAsString(StringData filename) { size_read = read(fd, buf.data(), kFileBufferSize); if (size_read == -1) { - int err = errno; + auto ec = lastPosixError(); - // Retry if we hit EGAIN or EINTR a few times before giving up - if (retry < kFileReadRetryCount && (err == EAGAIN || err == EINTR)) { + // Retry if we hit EAGAIN or EINTR a few times before giving up + if (retry < kFileReadRetryCount && + (ec == posixError(EAGAIN) || ec == posixError(EINTR))) { ++retry; continue; } return Status(ErrorCodes::FileStreamFailed, str::stream() << "Failed to read file " << filename - << " with error: " << errnoWithDescription(err)); + << " with error: " << errorMessage(ec)); } break; diff --git a/src/mongo/util/shell_exec.cpp b/src/mongo/util/shell_exec.cpp index 1adc02dbd4f..cff6e13da75 100644 --- a/src/mongo/util/shell_exec.cpp +++ b/src/mongo/util/shell_exec.cpp @@ -67,41 +67,51 @@ public: // Close our end of stdin immediately to signal child we have no data. HANDLE dummy = nullptr; - uassert(ErrorCodes::OperationFailed, - str::stream() << "Unable to create stdin pipe for subprocess: " - << errnoWithDescription(), - CreatePipe(&dummy, &_startup.hStdInput, &sa, kExecBufferSizeBytes)); + if (!CreatePipe(&dummy, &_startup.hStdInput, &sa, kExecBufferSizeBytes)) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() + << "Unable to create stdin pipe for subprocess: " << errorMessage(ec)); + } CloseHandle(dummy); - uassert(ErrorCodes::OperationFailed, - str::stream() << "Unable to create stdout pipe for subprocess: " - << errnoWithDescription(), - CreatePipe(&_stdout, &_startup.hStdOutput, &sa, kExecBufferSizeBytes)); + if (!CreatePipe(&_stdout, &_startup.hStdOutput, &sa, kExecBufferSizeBytes)) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() + << "Unable to create stdout pipe for subprocess: " << errorMessage(ec)); + } - uassert(ErrorCodes::OperationFailed, - str::stream() << "Unable to create stderr pipe for subprocess: " - << errnoWithDescription(), - CreatePipe(&_stderr, &_startup.hStdError, &sa, kExecBufferSizeBytes)); + if (!CreatePipe(&_stderr, &_startup.hStdError, &sa, kExecBufferSizeBytes)) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() + << "Unable to create stderr pipe for subprocess: " << errorMessage(ec)); + } DWORD mode = PIPE_NOWAIT; - uassert(ErrorCodes::OperationFailed, - str::stream() << "Unable to set non-blocking for subprocess: " - << errnoWithDescription(), - SetNamedPipeHandleState(_stdout, &mode, nullptr, nullptr)); + if (!SetNamedPipeHandleState(_stdout, &mode, nullptr, nullptr)) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() + << "Unable to set non-blocking for subprocess: " << errorMessage(ec)); + } auto wideCmd = toWideString(cmd.c_str()); - uassert(ErrorCodes::OperationFailed, - str::stream() << "Unable to launch command: " << errnoWithDescription(), - CreateProcessW(nullptr, - const_cast<wchar_t*>(wideCmd.c_str()), - &sa, - &sa, - true, - CREATE_NO_WINDOW, - nullptr, - nullptr, - &_startup, - &_process)); + if (!CreateProcessW(nullptr, + const_cast<wchar_t*>(wideCmd.c_str()), + &sa, + &sa, + true, + CREATE_NO_WINDOW, + nullptr, + nullptr, + &_startup, + &_process)) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() << "Unable to launch command: " << errorMessage(ec)); + } } int close() { @@ -109,15 +119,19 @@ public: return _exitcode; } - uassert(ErrorCodes::OperationFailed, - str::stream() << "Failed retreiving exit code from subprocess: " - << errnoWithDescription(), - GetExitCodeProcess(_process.hProcess, &_exitcode)); + if (!GetExitCodeProcess(_process.hProcess, &_exitcode)) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() + << "Failed retreiving exit code from subprocess: " << errorMessage(ec)); + } if (_exitcode == STILL_ACTIVE) { - uassert(ErrorCodes::OperationFailed, - str::stream() << "Failed terminating subprocess: " << errnoWithDescription(), - TerminateProcess(_process.hProcess, 1)); + if (!TerminateProcess(_process.hProcess, 1)) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() << "Failed terminating subprocess: " << errorMessage(ec)); + } _exitcode = 1; } @@ -129,10 +143,12 @@ public: return true; } - uassert(ErrorCodes::OperationFailed, - str::stream() << "Failed retreiving status of subprocess: " - << errnoWithDescription(), - GetExitCodeProcess(_process.hProcess, &_exitcode)); + if (!GetExitCodeProcess(_process.hProcess, &_exitcode)) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() + << "Failed retreiving status of subprocess: " << errorMessage(ec)); + } return _exitcode != STILL_ACTIVE; } @@ -144,7 +160,7 @@ public: } else if (ret == WAIT_TIMEOUT) { return {ErrorCodes::OperationFailed, "Timeout expired"}; } else { - return {ErrorCodes::OperationFailed, errnoWithDescription()}; + return {ErrorCodes::OperationFailed, errorMessage(lastSystemError())}; } } @@ -156,9 +172,11 @@ public: char buf[kExecBufferSizeBytes]; DWORD read = 0; - uassert(ErrorCodes::OperationFailed, - str::stream() << "Failed reading from subprocess: " << errnoWithDescription(), - ReadFile(_stdout, buf, std::min<size_t>(sizeof(buf), len), &read, nullptr)); + if (!ReadFile(_stdout, buf, std::min<size_t>(sizeof(buf), len), &read, nullptr)) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() << "Failed reading from subprocess: " << errorMessage(ec)); + } if (read == 0) { CloseHandle(_stdout); @@ -207,9 +225,11 @@ class ProcessStream { public: ProcessStream(const std::string& cmd) { _fp = ::popen(cmd.c_str(), "r"); - uassert(ErrorCodes::OperationFailed, - str::stream() << "Unable to launch command: " << errnoWithDescription(), - _fp); + if (!_fp) { + auto ec = lastSystemError(); + uasserted(ErrorCodes::OperationFailed, + str::stream() << "Unable to launch command: " << errorMessage(ec)); + } _fd = fileno(_fp); } @@ -234,7 +254,7 @@ public: auto ret = poll(&fds, 1, durationCount<Milliseconds>(duration)); if (ret < 0) { - return {ErrorCodes::OperationFailed, errnoWithDescription()}; + return {ErrorCodes::OperationFailed, errorMessage(lastSystemError())}; } else if (ret == 0) { return {ErrorCodes::OperationFailed, "Timeout expired"}; } else { diff --git a/src/mongo/util/signal_handlers.cpp b/src/mongo/util/signal_handlers.cpp index 95a4bee2ccc..c063600f5c8 100644 --- a/src/mongo/util/signal_handlers.cpp +++ b/src/mongo/util/signal_handlers.cpp @@ -122,10 +122,11 @@ void eventProcessingThread() { HANDLE event = CreateEventA(nullptr, TRUE, FALSE, eventName.c_str()); if (event == nullptr) { + auto ec = lastSystemError(); LOGV2_WARNING(23382, "eventProcessingThread CreateEvent failed: {error}", "eventProcessingThread CreateEvent failed", - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); return; } @@ -134,16 +135,18 @@ void eventProcessingThread() { int returnCode = WaitForSingleObject(event, INFINITE); if (returnCode != WAIT_OBJECT_0) { if (returnCode == WAIT_FAILED) { + auto ec = lastSystemError(); LOGV2_WARNING(23383, "eventProcessingThread WaitForSingleObject failed: {error}", "eventProcessingThread WaitForSingleObject failed", - "error"_attr = errnoWithDescription()); + "error"_attr = errorMessage(ec)); return; } else { + auto ec = systemError(returnCode); LOGV2_WARNING(23384, "eventProcessingThread WaitForSingleObject failed: {error}", "eventProcessingThread WaitForSingleObject failed", - "error"_attr = errnoWithDescription(returnCode)); + "error"_attr = errorMessage(ec)); return; } } diff --git a/src/mongo/util/stacktrace_windows.cpp b/src/mongo/util/stacktrace_windows.cpp index 99ceea9e937..ad9dc61acc6 100644 --- a/src/mongo/util/stacktrace_windows.cpp +++ b/src/mongo/util/stacktrace_windows.cpp @@ -95,8 +95,9 @@ public: const auto symbolPath = symbolPathBuilder.str(); if (!SymInitializeW(handle, symbolPath.c_str(), TRUE)) { + auto ec = lastSystemError(); LOGV2_ERROR( - 31443, "Stack trace initialization failed", "error"_attr = errnoWithDescription()); + 31443, "Stack trace initialization failed", "error"_attr = errorMessage(ec)); return; } diff --git a/src/mongo/util/time_support_test.cpp b/src/mongo/util/time_support_test.cpp index 9306e789137..c90c7c64de1 100644 --- a/src/mongo/util/time_support_test.cpp +++ b/src/mongo/util/time_support_test.cpp @@ -100,7 +100,8 @@ MONGO_INITIALIZER(SetTimeZoneToEasternForTest)(InitializerContext*) { int ret = putenv(tzEnvString); #endif if (ret == -1) { - uasserted(ErrorCodes::BadValue, errnoWithDescription()); + auto ec = lastPosixError(); + uasserted(ErrorCodes::BadValue, errorMessage(ec)); } tzset(); } |