xref: /freebsd-src/contrib/llvm-project/llvm/lib/Support/Errno.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===- Errno.cpp - errno support --------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the errno wrappers.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Support/Errno.h"
140b57cec5SDimitry Andric #include "llvm/Config/config.h"
1581ad6265SDimitry Andric #include <cstring>
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #if HAVE_ERRNO_H
180b57cec5SDimitry Andric #include <errno.h>
190b57cec5SDimitry Andric #endif
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
220b57cec5SDimitry Andric //=== WARNING: Implementation here must contain only TRULY operating system
230b57cec5SDimitry Andric //===          independent code.
240b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric namespace llvm {
270b57cec5SDimitry Andric namespace sys {
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric #if HAVE_ERRNO_H
StrError()300b57cec5SDimitry Andric std::string StrError() {
310b57cec5SDimitry Andric   return StrError(errno);
320b57cec5SDimitry Andric }
330b57cec5SDimitry Andric #endif  // HAVE_ERRNO_H
340b57cec5SDimitry Andric 
StrError(int errnum)350b57cec5SDimitry Andric std::string StrError(int errnum) {
360b57cec5SDimitry Andric   std::string str;
370b57cec5SDimitry Andric   if (errnum == 0)
380b57cec5SDimitry Andric     return str;
390b57cec5SDimitry Andric #if defined(HAVE_STRERROR_R) || HAVE_DECL_STRERROR_S
400b57cec5SDimitry Andric   const int MaxErrStrLen = 2000;
410b57cec5SDimitry Andric   char buffer[MaxErrStrLen];
420b57cec5SDimitry Andric   buffer[0] = '\0';
430b57cec5SDimitry Andric #endif
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric #ifdef HAVE_STRERROR_R
460b57cec5SDimitry Andric   // strerror_r is thread-safe.
470b57cec5SDimitry Andric #if defined(__GLIBC__) && defined(_GNU_SOURCE)
480b57cec5SDimitry Andric   // glibc defines its own incompatible version of strerror_r
490b57cec5SDimitry Andric   // which may not use the buffer supplied.
500b57cec5SDimitry Andric   str = strerror_r(errnum, buffer, MaxErrStrLen - 1);
510b57cec5SDimitry Andric #else
520b57cec5SDimitry Andric   strerror_r(errnum, buffer, MaxErrStrLen - 1);
530b57cec5SDimitry Andric   str = buffer;
540b57cec5SDimitry Andric #endif
550b57cec5SDimitry Andric #elif HAVE_DECL_STRERROR_S // "Windows Secure API"
560b57cec5SDimitry Andric   strerror_s(buffer, MaxErrStrLen - 1, errnum);
570b57cec5SDimitry Andric   str = buffer;
58*06c3fb27SDimitry Andric #else
590b57cec5SDimitry Andric   // Copy the thread un-safe result of strerror into
600b57cec5SDimitry Andric   // the buffer as fast as possible to minimize impact
610b57cec5SDimitry Andric   // of collision of strerror in multiple threads.
620b57cec5SDimitry Andric   str = strerror(errnum);
630b57cec5SDimitry Andric #endif
640b57cec5SDimitry Andric   return str;
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric }  // namespace sys
680b57cec5SDimitry Andric }  // namespace llvm
69