diff options
-rw-r--r-- | autoconf/configure.ac | 3 | ||||
-rwxr-xr-x | cmake/config-ix.cmake | 3 | ||||
-rw-r--r-- | include/llvm/Config/config.h.cmake | 7 | ||||
-rw-r--r-- | include/llvm/System/Errno.h | 34 | ||||
-rw-r--r-- | lib/System/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/System/Errno.cpp | 71 | ||||
-rw-r--r-- | lib/System/Unix/Unix.h | 28 | ||||
-rw-r--r-- | tools/gold/gold-plugin.cpp | 5 |
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; } |