1 //===- Errno.cpp - errno support --------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the errno wrappers. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Support/Errno.h" 14 #include "llvm/Config/config.h" 15 #include <cstring> 16 17 #if HAVE_ERRNO_H 18 #include <errno.h> 19 #endif 20 21 //===----------------------------------------------------------------------===// 22 //=== WARNING: Implementation here must contain only TRULY operating system 23 //=== independent code. 24 //===----------------------------------------------------------------------===// 25 26 namespace llvm { 27 namespace sys { 28 29 #if HAVE_ERRNO_H 30 std::string StrError() { 31 return StrError(errno); 32 } 33 #endif // HAVE_ERRNO_H 34 35 std::string StrError(int errnum) { 36 std::string str; 37 if (errnum == 0) 38 return str; 39 #if defined(HAVE_STRERROR_R) || HAVE_DECL_STRERROR_S 40 const int MaxErrStrLen = 2000; 41 char buffer[MaxErrStrLen]; 42 buffer[0] = '\0'; 43 #endif 44 45 #ifdef HAVE_STRERROR_R 46 // strerror_r is thread-safe. 47 #if defined(__GLIBC__) && defined(_GNU_SOURCE) 48 // glibc defines its own incompatible version of strerror_r 49 // which may not use the buffer supplied. 50 str = strerror_r(errnum, buffer, MaxErrStrLen - 1); 51 #else 52 strerror_r(errnum, buffer, MaxErrStrLen - 1); 53 str = buffer; 54 #endif 55 #elif HAVE_DECL_STRERROR_S // "Windows Secure API" 56 strerror_s(buffer, MaxErrStrLen - 1, errnum); 57 str = buffer; 58 #elif defined(HAVE_STRERROR) 59 // Copy the thread un-safe result of strerror into 60 // the buffer as fast as possible to minimize impact 61 // of collision of strerror in multiple threads. 62 str = strerror(errnum); 63 #else 64 // Strange that this system doesn't even have strerror 65 // but, oh well, just use a generic message 66 raw_string_ostream stream(str); 67 stream << "Error #" << errnum; 68 stream.flush(); 69 #endif 70 return str; 71 } 72 73 } // namespace sys 74 } // namespace llvm 75