1218885Sdim//===- Errno.cpp - errno support --------------------------------*- C++ -*-===//
2218885Sdim//
3218885Sdim//                     The LLVM Compiler Infrastructure
4218885Sdim//
5218885Sdim// This file is distributed under the University of Illinois Open Source
6218885Sdim// License. See LICENSE.TXT for details.
7218885Sdim//
8218885Sdim//===----------------------------------------------------------------------===//
9218885Sdim//
10218885Sdim// This file implements the errno wrappers.
11218885Sdim//
12218885Sdim//===----------------------------------------------------------------------===//
13218885Sdim
14218885Sdim#include "llvm/Support/Errno.h"
15218885Sdim#include "llvm/Config/config.h"     // Get autoconf configuration settings
16243830Sdim#include "llvm/Support/raw_ostream.h"
17218885Sdim#include <string.h>
18218885Sdim
19218885Sdim#if HAVE_ERRNO_H
20218885Sdim#include <errno.h>
21218885Sdim#endif
22218885Sdim
23218885Sdim//===----------------------------------------------------------------------===//
24218885Sdim//=== WARNING: Implementation here must contain only TRULY operating system
25218885Sdim//===          independent code.
26218885Sdim//===----------------------------------------------------------------------===//
27218885Sdim
28218885Sdimnamespace llvm {
29218885Sdimnamespace sys {
30218885Sdim
31218885Sdim#if HAVE_ERRNO_H
32218885Sdimstd::string StrError() {
33218885Sdim  return StrError(errno);
34218885Sdim}
35218885Sdim#endif  // HAVE_ERRNO_H
36218885Sdim
37218885Sdimstd::string StrError(int errnum) {
38218885Sdim  const int MaxErrStrLen = 2000;
39218885Sdim  char buffer[MaxErrStrLen];
40218885Sdim  buffer[0] = '\0';
41243830Sdim  std::string str;
42263508Sdim  if (errnum == 0)
43263508Sdim    return str;
44263508Sdim
45218885Sdim#ifdef HAVE_STRERROR_R
46218885Sdim  // strerror_r is thread-safe.
47263508Sdim#if defined(__GLIBC__) && defined(_GNU_SOURCE)
48263508Sdim  // glibc defines its own incompatible version of strerror_r
49263508Sdim  // which may not use the buffer supplied.
50263508Sdim  str = strerror_r(errnum, buffer, MaxErrStrLen - 1);
51263508Sdim#else
52263508Sdim  strerror_r(errnum, buffer, MaxErrStrLen - 1);
53263508Sdim  str = buffer;
54263508Sdim#endif
55218885Sdim#elif HAVE_DECL_STRERROR_S // "Windows Secure API"
56263508Sdim  strerror_s(buffer, MaxErrStrLen - 1, errnum);
57263508Sdim  str = buffer;
58218885Sdim#elif defined(HAVE_STRERROR)
59218885Sdim  // Copy the thread un-safe result of strerror into
60218885Sdim  // the buffer as fast as possible to minimize impact
61218885Sdim  // of collision of strerror in multiple threads.
62263508Sdim  str = strerror(errnum);
63218885Sdim#else
64218885Sdim  // Strange that this system doesn't even have strerror
65218885Sdim  // but, oh well, just use a generic message
66243830Sdim  raw_string_ostream stream(str);
67243830Sdim  stream << "Error #" << errnum;
68243830Sdim  stream.flush();
69218885Sdim#endif
70218885Sdim  return str;
71218885Sdim}
72218885Sdim
73218885Sdim}  // namespace sys
74218885Sdim}  // namespace llvm
75