blob: 485378dfdc983748fcc5866b84d9ad504078f336 [file] [log] [blame]
Jeffrey Yasskin1a933302009-07-01 18:11:20 +00001//===- Errno.cpp - errno support --------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Jeffrey Yasskin1a933302009-07-01 18:11:20 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the errno wrappers.
10//
11//===----------------------------------------------------------------------===//
12
Michael J. Spencer447762d2010-11-29 18:16:10 +000013#include "llvm/Support/Errno.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000014#include "llvm/Config/config.h" // Get autoconf configuration settings
Dmitri Gribenko91c06da2012-09-28 14:15:28 +000015#include "llvm/Support/raw_ostream.h"
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000016#include <string.h>
17
18#if HAVE_ERRNO_H
19#include <errno.h>
20#endif
Jeffrey Yasskin5a2e5212009-07-06 16:50:27 +000021
Jeffrey Yasskin1a933302009-07-01 18:11:20 +000022//===----------------------------------------------------------------------===//
23//=== WARNING: Implementation here must contain only TRULY operating system
24//=== independent code.
25//===----------------------------------------------------------------------===//
26
27namespace llvm {
28namespace sys {
29
30#if HAVE_ERRNO_H
Jeffrey Yasskin1a933302009-07-01 18:11:20 +000031std::string StrError() {
32 return StrError(errno);
33}
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000034#endif // HAVE_ERRNO_H
Jeffrey Yasskin1a933302009-07-01 18:11:20 +000035
36std::string StrError(int errnum) {
Dmitri Gribenko91c06da2012-09-28 14:15:28 +000037 std::string str;
Chandler Carruth14aae042013-09-02 05:55:10 +000038 if (errnum == 0)
39 return str;
Yaron Kerend9089412014-12-04 21:36:38 +000040#if defined(HAVE_STRERROR_R) || HAVE_DECL_STRERROR_S
41 const int MaxErrStrLen = 2000;
42 char buffer[MaxErrStrLen];
43 buffer[0] = '\0';
Fangrui Songf78650a2018-07-30 19:41:25 +000044#endif
Chandler Carruth14aae042013-09-02 05:55:10 +000045
Jeffrey Yasskin1a933302009-07-01 18:11:20 +000046#ifdef HAVE_STRERROR_R
47 // strerror_r is thread-safe.
Chandler Carruth14aae042013-09-02 05:55:10 +000048#if defined(__GLIBC__) && defined(_GNU_SOURCE)
49 // glibc defines its own incompatible version of strerror_r
50 // which may not use the buffer supplied.
51 str = strerror_r(errnum, buffer, MaxErrStrLen - 1);
52#else
53 strerror_r(errnum, buffer, MaxErrStrLen - 1);
54 str = buffer;
55#endif
NAKAMURA Takumi189111802011-02-09 04:18:48 +000056#elif HAVE_DECL_STRERROR_S // "Windows Secure API"
Chandler Carruth14aae042013-09-02 05:55:10 +000057 strerror_s(buffer, MaxErrStrLen - 1, errnum);
58 str = buffer;
Duncan Sandsf9cf4ff2009-07-02 12:09:50 +000059#elif defined(HAVE_STRERROR)
Jeffrey Yasskin1a933302009-07-01 18:11:20 +000060 // Copy the thread un-safe result of strerror into
61 // the buffer as fast as possible to minimize impact
62 // of collision of strerror in multiple threads.
Chandler Carruth14aae042013-09-02 05:55:10 +000063 str = strerror(errnum);
Jeffrey Yasskin1a933302009-07-01 18:11:20 +000064#else
65 // Strange that this system doesn't even have strerror
66 // but, oh well, just use a generic message
Dmitri Gribenko91c06da2012-09-28 14:15:28 +000067 raw_string_ostream stream(str);
68 stream << "Error #" << errnum;
69 stream.flush();
Jeffrey Yasskin1a933302009-07-01 18:11:20 +000070#endif
71 return str;
72}
73
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000074} // namespace sys
75} // namespace llvm