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