summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autoconf/configure.ac3
-rwxr-xr-xcmake/config-ix.cmake3
-rw-r--r--include/llvm/Config/config.h.cmake7
-rw-r--r--include/llvm/System/Errno.h34
-rw-r--r--lib/System/CMakeLists.txt1
-rw-r--r--lib/System/Errno.cpp71
-rw-r--r--lib/System/Unix/Unix.h28
-rw-r--r--tools/gold/gold-plugin.cpp5
8 files changed, 121 insertions, 31 deletions
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index f71e648d57..1db4dea848 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -914,7 +914,8 @@ AC_CHECK_FUNCS([backtrace ceilf floorf roundf rintf nearbyintf getcwd ])
AC_CHECK_FUNCS([powf fmodf strtof round ])
AC_CHECK_FUNCS([getpagesize getrusage getrlimit setrlimit gettimeofday ])
AC_CHECK_FUNCS([isatty mkdtemp mkstemp ])
-AC_CHECK_FUNCS([mktemp realpath sbrk setrlimit strdup strerror strerror_r ])
+AC_CHECK_FUNCS([mktemp realpath sbrk setrlimit strdup ])
+AC_CHECK_FUNCS([strerror strerror_r strerror_s ])
AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ])
AC_CHECK_FUNCS([setjmp longjmp sigsetjmp siglongjmp])
AC_C_PRINTF_A
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index a613ddd8e3..731071ef85 100755
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -67,6 +67,9 @@ check_symbol_exists(malloc_zone_statistics malloc/malloc.h
HAVE_MALLOC_ZONE_STATISTICS)
check_symbol_exists(pthread_mutex_lock pthread.h HAVE_PTHREAD_MUTEX_LOCK)
check_symbol_exists(strtoll stdlib.h HAVE_STRTOLL)
+check_symbol_exists(strerror string.h HAVE_STRERROR)
+check_symbol_exists(strerror_r string.h HAVE_STRERROR_R)
+check_symbol_exists(strerror_s string.h HAVE_STRERROR_S)
check_symbol_exists(__GLIBC__ stdio.h LLVM_USING_GLIBC)
if( LLVM_USING_GLIBC )
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index 27ef440223..180e8c5238 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -364,10 +364,13 @@
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
-#undef HAVE_STRERROR
+#cmakedefine HAVE_STRERROR
/* Define to 1 if you have the `strerror_r' function. */
-#undef HAVE_STRERROR_R
+#cmakedefine HAVE_STRERROR_R
+
+/* Define to 1 if you have the `strerror_s' function. */
+#cmakedefine HAVE_STRERROR_S
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
diff --git a/include/llvm/System/Errno.h b/include/llvm/System/Errno.h
new file mode 100644
index 0000000000..6e292ba626
--- /dev/null
+++ b/include/llvm/System/Errno.h
@@ -0,0 +1,34 @@
+//===- llvm/System/Errno.h - Portable+convenient errno handling -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares some portable and convenient functions to deal with errno.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_ERRNO_H
+#define LLVM_SYSTEM_ERRNO_H
+
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+/// Returns a string representation of the errno value, using whatever
+/// thread-safe variant of strerror() is available. Be sure to call this
+/// immediately after the function that set errno, or errno may have been
+/// overwritten by an intervening call.
+std::string StrError();
+
+/// Like the no-argument version above, but uses \p errnum instead of errno.
+std::string StrError(int errnum);
+
+} // namespace sys
+} // namespace llvm
+
+#endif // LLVM_SYSTEM_ERRNO_H
diff --git a/lib/System/CMakeLists.txt b/lib/System/CMakeLists.txt
index 431629a14d..bf7a0c601e 100644
--- a/lib/System/CMakeLists.txt
+++ b/lib/System/CMakeLists.txt
@@ -3,6 +3,7 @@ add_llvm_library(LLVMSystem
Atomic.cpp
Disassembler.cpp
DynamicLibrary.cpp
+ Errno.cpp
Host.cpp
IncludeFile.cpp
Memory.cpp
diff --git a/lib/System/Errno.cpp b/lib/System/Errno.cpp
new file mode 100644
index 0000000000..f4e3a88d05
--- /dev/null
+++ b/lib/System/Errno.cpp
@@ -0,0 +1,71 @@
+//===- Errno.cpp - errno support --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the errno wrappers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/Errno.h"
+#include "llvm/Config/config.h" // Get autoconf configuration settings
+
+#if HAVE_STRING_H
+#include <string.h>
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+namespace sys {
+
+#if HAVE_ERRNO_H
+#include <errno.h>
+std::string StrError() {
+ return StrError(errno);
+}
+#endif // HAVE_ERRNO_H
+
+std::string StrError(int errnum) {
+ const int MaxErrStrLen = 2000;
+ char buffer[MaxErrStrLen];
+ buffer[0] = '\0';
+ char* str = buffer;
+#ifdef HAVE_STRERROR_R
+ // strerror_r is thread-safe.
+ if (errnum)
+# if defined(__GLIBC__) && defined(_GNU_SOURCE)
+ // glibc defines its own incompatible version of strerror_r
+ // which may not use the buffer supplied.
+ str = strerror_r(errnum,buffer,MaxErrStrLen-1);
+# else
+ strerror_r(errnum,buffer,MaxErrStrLen-1);
+# endif
+#elif HAVE_STRERROR_S // Windows.
+ if (errnum)
+ strerror_s(buffer, errnum);
+#elif HAVE_STRERROR
+ // Copy the thread un-safe result of strerror into
+ // the buffer as fast as possible to minimize impact
+ // of collision of strerror in multiple threads.
+ if (errnum)
+ strncpy(buffer,strerror(errnum),MaxErrStrLen-1);
+ buffer[MaxErrStrLen-1] = '\0';
+#else
+ // Strange that this system doesn't even have strerror
+ // but, oh well, just use a generic message
+ sprintf(buffer, "Error #%d", errnum);
+#endif
+ return str;
+}
+
+} // namespace sys
+} // namespace llvm
+
+#endif // HAVE_STRING_H
diff --git a/lib/System/Unix/Unix.h b/lib/System/Unix/Unix.h
index c2c06dd114..c15866f3d9 100644
--- a/lib/System/Unix/Unix.h
+++ b/lib/System/Unix/Unix.h
@@ -20,6 +20,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Config/config.h" // Get autoconf configuration settings
+#include "llvm/System/Errno.h"
#include <cstdlib>
#include <cstdio>
#include <cstring>
@@ -77,34 +78,9 @@ static inline bool MakeErrMsg(
std::string* ErrMsg, const std::string& prefix, int errnum = -1) {
if (!ErrMsg)
return true;
- char buffer[MAXPATHLEN];
- buffer[0] = 0;
- char* str = buffer;
if (errnum == -1)
errnum = errno;
-#ifdef HAVE_STRERROR_R
- // strerror_r is thread-safe.
- if (errnum)
-# if defined(__GLIBC__) && defined(_GNU_SOURCE)
- // glibc defines its own incompatible version of strerror_r
- // which may not use the buffer supplied.
- str = strerror_r(errnum,buffer,MAXPATHLEN-1);
-# else
- strerror_r(errnum,buffer,MAXPATHLEN-1);
-# endif
-#elif HAVE_STRERROR
- // Copy the thread un-safe result of strerror into
- // the buffer as fast as possible to minimize impact
- // of collision of strerror in multiple threads.
- if (errnum)
- strncpy(buffer,strerror(errnum),MAXPATHLEN-1);
- buffer[MAXPATHLEN-1] = 0;
-#else
- // Strange that this system doesn't even have strerror
- // but, oh well, just use a generic message
- sprintf(buffer, "Error #%d", errnum);
-#endif
- *ErrMsg = prefix + ": " + str;
+ *ErrMsg = prefix + ": " + llvm::sys::StrError(errnum);
return true;
}
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp
index 8d8fcd2f44..146c53fbb7 100644
--- a/tools/gold/gold-plugin.cpp
+++ b/tools/gold/gold-plugin.cpp
@@ -17,6 +17,7 @@
#include "llvm-c/lto.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Errno.h"
#include "llvm/System/Path.h"
#include "llvm/System/Program.h"
@@ -183,7 +184,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
(*message)(LDPL_ERROR,
"Failed to seek to archive member of %s at offset %d: %s\n",
file->name,
- file->offset, strerror(errno));
+ file->offset, sys::StrError(errno).c_str());
return LDPS_ERR;
}
buf = malloc(file->filesize);
@@ -198,7 +199,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
"Failed to read archive member of %s at offset %d: %s\n",
file->name,
file->offset,
- strerror(errno));
+ sys::StrError(errno).c_str());
free(buf);
return LDPS_ERR;
}