Skip to content

Commit 1a93330

Browse files
committed
Add a portable strerror*() wrapper, llvm::sys::StrError(). This includes the
Windows variant, strerror_s, but I couldn't test that. I'll update configure and config.h.in in a subsequent patch. llvm-svn: 74621
1 parent 702e817 commit 1a93330

File tree

8 files changed

+121
-31
lines changed

8 files changed

+121
-31
lines changed

llvm/autoconf/configure.ac

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,8 @@ AC_CHECK_FUNCS([backtrace ceilf floorf roundf rintf nearbyintf getcwd ])
914914
AC_CHECK_FUNCS([powf fmodf strtof round ])
915915
AC_CHECK_FUNCS([getpagesize getrusage getrlimit setrlimit gettimeofday ])
916916
AC_CHECK_FUNCS([isatty mkdtemp mkstemp ])
917-
AC_CHECK_FUNCS([mktemp realpath sbrk setrlimit strdup strerror strerror_r ])
917+
AC_CHECK_FUNCS([mktemp realpath sbrk setrlimit strdup ])
918+
AC_CHECK_FUNCS([strerror strerror_r strerror_s ])
918919
AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ])
919920
AC_CHECK_FUNCS([setjmp longjmp sigsetjmp siglongjmp])
920921
AC_C_PRINTF_A

llvm/cmake/config-ix.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ check_symbol_exists(malloc_zone_statistics malloc/malloc.h
6767
HAVE_MALLOC_ZONE_STATISTICS)
6868
check_symbol_exists(pthread_mutex_lock pthread.h HAVE_PTHREAD_MUTEX_LOCK)
6969
check_symbol_exists(strtoll stdlib.h HAVE_STRTOLL)
70+
check_symbol_exists(strerror string.h HAVE_STRERROR)
71+
check_symbol_exists(strerror_r string.h HAVE_STRERROR_R)
72+
check_symbol_exists(strerror_s string.h HAVE_STRERROR_S)
7073

7174
check_symbol_exists(__GLIBC__ stdio.h LLVM_USING_GLIBC)
7275
if( LLVM_USING_GLIBC )

llvm/include/llvm/Config/config.h.cmake

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,10 +364,13 @@
364364
#undef HAVE_STRDUP
365365

366366
/* Define to 1 if you have the `strerror' function. */
367-
#undef HAVE_STRERROR
367+
#cmakedefine HAVE_STRERROR
368368

369369
/* Define to 1 if you have the `strerror_r' function. */
370-
#undef HAVE_STRERROR_R
370+
#cmakedefine HAVE_STRERROR_R
371+
372+
/* Define to 1 if you have the `strerror_s' function. */
373+
#cmakedefine HAVE_STRERROR_S
371374

372375
/* Define to 1 if you have the <strings.h> header file. */
373376
#undef HAVE_STRINGS_H

llvm/include/llvm/System/Errno.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===- llvm/System/Errno.h - Portable+convenient errno handling -*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file declares some portable and convenient functions to deal with errno.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_SYSTEM_ERRNO_H
15+
#define LLVM_SYSTEM_ERRNO_H
16+
17+
#include <string>
18+
19+
namespace llvm {
20+
namespace sys {
21+
22+
/// Returns a string representation of the errno value, using whatever
23+
/// thread-safe variant of strerror() is available. Be sure to call this
24+
/// immediately after the function that set errno, or errno may have been
25+
/// overwritten by an intervening call.
26+
std::string StrError();
27+
28+
/// Like the no-argument version above, but uses \p errnum instead of errno.
29+
std::string StrError(int errnum);
30+
31+
} // namespace sys
32+
} // namespace llvm
33+
34+
#endif // LLVM_SYSTEM_ERRNO_H

llvm/lib/System/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_llvm_library(LLVMSystem
33
Atomic.cpp
44
Disassembler.cpp
55
DynamicLibrary.cpp
6+
Errno.cpp
67
Host.cpp
78
IncludeFile.cpp
89
Memory.cpp

llvm/lib/System/Errno.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//===- Errno.cpp - errno support --------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file implements the errno wrappers.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "llvm/System/Errno.h"
15+
#include "llvm/Config/config.h" // Get autoconf configuration settings
16+
17+
#if HAVE_STRING_H
18+
#include <string.h>
19+
20+
//===----------------------------------------------------------------------===//
21+
//=== WARNING: Implementation here must contain only TRULY operating system
22+
//=== independent code.
23+
//===----------------------------------------------------------------------===//
24+
25+
namespace llvm {
26+
namespace sys {
27+
28+
#if HAVE_ERRNO_H
29+
#include <errno.h>
30+
std::string StrError() {
31+
return StrError(errno);
32+
}
33+
#endif // HAVE_ERRNO_H
34+
35+
std::string StrError(int errnum) {
36+
const int MaxErrStrLen = 2000;
37+
char buffer[MaxErrStrLen];
38+
buffer[0] = '\0';
39+
char* str = buffer;
40+
#ifdef HAVE_STRERROR_R
41+
// strerror_r is thread-safe.
42+
if (errnum)
43+
# if defined(__GLIBC__) && defined(_GNU_SOURCE)
44+
// glibc defines its own incompatible version of strerror_r
45+
// which may not use the buffer supplied.
46+
str = strerror_r(errnum,buffer,MaxErrStrLen-1);
47+
# else
48+
strerror_r(errnum,buffer,MaxErrStrLen-1);
49+
# endif
50+
#elif HAVE_STRERROR_S // Windows.
51+
if (errnum)
52+
strerror_s(buffer, errnum);
53+
#elif HAVE_STRERROR
54+
// Copy the thread un-safe result of strerror into
55+
// the buffer as fast as possible to minimize impact
56+
// of collision of strerror in multiple threads.
57+
if (errnum)
58+
strncpy(buffer,strerror(errnum),MaxErrStrLen-1);
59+
buffer[MaxErrStrLen-1] = '\0';
60+
#else
61+
// Strange that this system doesn't even have strerror
62+
// but, oh well, just use a generic message
63+
sprintf(buffer, "Error #%d", errnum);
64+
#endif
65+
return str;
66+
}
67+
68+
} // namespace sys
69+
} // namespace llvm
70+
71+
#endif // HAVE_STRING_H

llvm/lib/System/Unix/Unix.h

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
//===----------------------------------------------------------------------===//
2121

2222
#include "llvm/Config/config.h" // Get autoconf configuration settings
23+
#include "llvm/System/Errno.h"
2324
#include <cstdlib>
2425
#include <cstdio>
2526
#include <cstring>
@@ -77,34 +78,9 @@ static inline bool MakeErrMsg(
7778
std::string* ErrMsg, const std::string& prefix, int errnum = -1) {
7879
if (!ErrMsg)
7980
return true;
80-
char buffer[MAXPATHLEN];
81-
buffer[0] = 0;
82-
char* str = buffer;
8381
if (errnum == -1)
8482
errnum = errno;
85-
#ifdef HAVE_STRERROR_R
86-
// strerror_r is thread-safe.
87-
if (errnum)
88-
# if defined(__GLIBC__) && defined(_GNU_SOURCE)
89-
// glibc defines its own incompatible version of strerror_r
90-
// which may not use the buffer supplied.
91-
str = strerror_r(errnum,buffer,MAXPATHLEN-1);
92-
# else
93-
strerror_r(errnum,buffer,MAXPATHLEN-1);
94-
# endif
95-
#elif HAVE_STRERROR
96-
// Copy the thread un-safe result of strerror into
97-
// the buffer as fast as possible to minimize impact
98-
// of collision of strerror in multiple threads.
99-
if (errnum)
100-
strncpy(buffer,strerror(errnum),MAXPATHLEN-1);
101-
buffer[MAXPATHLEN-1] = 0;
102-
#else
103-
// Strange that this system doesn't even have strerror
104-
// but, oh well, just use a generic message
105-
sprintf(buffer, "Error #%d", errnum);
106-
#endif
107-
*ErrMsg = prefix + ": " + str;
83+
*ErrMsg = prefix + ": " + llvm::sys::StrError(errnum);
10884
return true;
10985
}
11086

llvm/tools/gold/gold-plugin.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm-c/lto.h"
1818

1919
#include "llvm/Support/raw_ostream.h"
20+
#include "llvm/System/Errno.h"
2021
#include "llvm/System/Path.h"
2122
#include "llvm/System/Program.h"
2223

@@ -183,7 +184,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
183184
(*message)(LDPL_ERROR,
184185
"Failed to seek to archive member of %s at offset %d: %s\n",
185186
file->name,
186-
file->offset, strerror(errno));
187+
file->offset, sys::StrError(errno).c_str());
187188
return LDPS_ERR;
188189
}
189190
buf = malloc(file->filesize);
@@ -198,7 +199,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
198199
"Failed to read archive member of %s at offset %d: %s\n",
199200
file->name,
200201
file->offset,
201-
strerror(errno));
202+
sys::StrError(errno).c_str());
202203
free(buf);
203204
return LDPS_ERR;
204205
}

0 commit comments

Comments
 (0)