diff options
author | Philipp Janda <siffiejoe@gmx.net> | 2017-10-01 13:42:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-01 13:42:18 +0200 |
commit | db8446dfae8bc8d03fd4dc8a845bfba104b9b372 (patch) | |
tree | 7e5a8a5c2f9cffdf1b43b7ae3cd0edbb8d925ea2 | |
parent | 9cb6834fe07297ba79e7453978cf7e7d8d8c339a (diff) | |
parent | 447decaaf902ad9c461a6df2bbe702481f3d7786 (diff) | |
download | lua-compat-5.3-db8446dfae8bc8d03fd4dc8a845bfba104b9b372.tar.gz lua-compat-5.3-db8446dfae8bc8d03fd4dc8a845bfba104b9b372.tar.bz2 lua-compat-5.3-db8446dfae8bc8d03fd4dc8a845bfba104b9b372.zip |
Merge pull request #37 from keplerproject/strerror
Transparently handle GNU/XSI strerror_r.
-rw-r--r-- | c-api/compat-5.3.c | 71 |
1 files changed, 25 insertions, 46 deletions
diff --git a/c-api/compat-5.3.c b/c-api/compat-5.3.c index e87808c..09c60dd 100644 --- a/c-api/compat-5.3.c +++ b/c-api/compat-5.3.c | |||
@@ -24,38 +24,15 @@ | |||
24 | #endif /* No-lock fopen_s usage if possible */ | 24 | #endif /* No-lock fopen_s usage if possible */ |
25 | 25 | ||
26 | #if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK | 26 | #if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK |
27 | #include <share.h> | 27 | # include <share.h> |
28 | #endif /* VC++ _fsopen for share-allowed file read */ | 28 | #endif /* VC++ _fsopen for share-allowed file read */ |
29 | 29 | ||
30 | #ifndef COMPAT53_HAVE_STRERROR_R | 30 | #ifndef COMPAT53_HAVE_STRERROR_R |
31 | # if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || \ | 31 | # if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || \ |
32 | (!defined (__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6)) | 32 | (!defined (__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6)) |
33 | # define COMPAT53_HAVE_STRERROR_R 1 | 33 | # define COMPAT53_HAVE_STRERROR_R 1 |
34 | # if ((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \ | ||
35 | (defined(_XOPEN_SOURCE) || _XOPEN_SOURCE >= 600)) && \ | ||
36 | (!defined(_GNU_SOURCE) || !_GNU_SOURCE) | ||
37 | # ifndef COMPAT53_HAVE_STRERROR_R_XSI | ||
38 | # define COMPAT53_HAVE_STRERROR_R_XSI 1 | ||
39 | # endif /* XSI-Compliant strerror_r */ | ||
40 | # ifndef COMPAT53_HAVE_STRERROR_R_GNU | ||
41 | # define COMPAT53_HAVE_STRERROR_R_GNU 0 | ||
42 | # endif /* GNU strerror_r */ | ||
43 | # else /* XSI/Posix vs. GNU strerror_r */ | ||
44 | # ifndef COMPAT53_HAVE_STRERROR_R_GNU | ||
45 | # define COMPAT53_HAVE_STRERROR_R_GNU 1 | ||
46 | # endif /* GNU variant strerror_r */ | ||
47 | # ifndef COMPAT53_HAVE_STRERROR_R_XSI | ||
48 | # define COMPAT53_HAVE_STRERROR_R_XSI 0 | ||
49 | # endif /* XSI strerror_r */ | ||
50 | # endif /* XSI/Posix vs. GNU strerror_r */ | ||
51 | # else /* none of the defines matched: define to 0 */ | 34 | # else /* none of the defines matched: define to 0 */ |
52 | # define COMPAT53_HAVE_STRERROR_R 0 | 35 | # define COMPAT53_HAVE_STRERROR_R 0 |
53 | # ifndef COMPAT53_HAVE_STRERROR_R_XSI | ||
54 | # define COMPAT53_HAVE_STRERROR_R_XSI 0 | ||
55 | # endif /* XSI strerror_r */ | ||
56 | # ifndef COMPAT53_HAVE_STRERROR_R_GNU | ||
57 | # define COMPAT53_HAVE_STRERROR_R_GNU 0 | ||
58 | # endif /* GNU strerror_r */ | ||
59 | # endif /* have strerror_r of some form */ | 36 | # endif /* have strerror_r of some form */ |
60 | #endif /* strerror_r */ | 37 | #endif /* strerror_r */ |
61 | 38 | ||
@@ -69,34 +46,38 @@ | |||
69 | #endif /* strerror_s */ | 46 | #endif /* strerror_s */ |
70 | 47 | ||
71 | #ifndef COMPAT53_LUA_FILE_BUFFER_SIZE | 48 | #ifndef COMPAT53_LUA_FILE_BUFFER_SIZE |
72 | #define COMPAT53_LUA_FILE_BUFFER_SIZE 4096 | 49 | # define COMPAT53_LUA_FILE_BUFFER_SIZE 4096 |
73 | #endif /* Lua File Buffer Size */ | 50 | #endif /* Lua File Buffer Size */ |
74 | 51 | ||
75 | 52 | ||
76 | static char* compat53_strerror (int en, char* buff, size_t sz) { | 53 | static char* compat53_strerror (int en, char* buff, size_t sz) { |
77 | #if COMPAT53_HAVE_STRERROR_R | 54 | #if COMPAT53_HAVE_STRERROR_R |
78 | /* use strerror_r here, because it's available on these specific platforms */ | 55 | /* use strerror_r here, because it's available on these specific platforms */ |
79 | #if COMPAT53_HAVE_STRERROR_R_XSI | 56 | if (sz > 0) { |
80 | /* XSI Compliant */ | 57 | buff[0] = '\0'; |
81 | strerror_r(en, buff, sz); | 58 | /* we don't care whether the GNU version or the XSI version is used: */ |
82 | return buff; | 59 | if (strerror_r(en, buff, sz)) { |
83 | #else | 60 | /* Yes, we really DO want to ignore the return value! |
84 | /* GNU-specific which returns const char* */ | 61 | * GCC makes that extra hard, not even a (void) cast will do. */ |
85 | return strerror_r(en, buff, sz); | 62 | } |
86 | #endif | 63 | if (buff[0] == '\0') { |
64 | /* Buffer is unchanged, so we probably have called GNU strerror_r which | ||
65 | * returned a static constant string. Chances are that strerror will | ||
66 | * return the same static constant string and therefore be thread-safe. */ | ||
67 | return strerror(en); | ||
68 | } | ||
69 | } | ||
70 | return buff; /* sz is 0 *or* strerror_r wrote into the buffer */ | ||
87 | #elif COMPAT53_HAVE_STRERROR_S | 71 | #elif COMPAT53_HAVE_STRERROR_S |
88 | /* for MSVC and other C11 implementations, use strerror_s | 72 | /* for MSVC and other C11 implementations, use strerror_s since it's |
89 | * since it's provided by default by the libraries | 73 | * provided by default by the libraries */ |
90 | */ | ||
91 | strerror_s(buff, sz, en); | 74 | strerror_s(buff, sz, en); |
92 | return buff; | 75 | return buff; |
93 | #else | 76 | #else |
94 | /* fallback, but | 77 | /* fallback, but strerror is not guaranteed to be threadsafe due to modifying |
95 | * strerror is not guaranteed to be threadsafe due to modifying | 78 | * errno itself and some impls not locking a static buffer for it ... but most |
96 | * errno itself and some impls not locking a static buffer for it | 79 | * known systems have threadsafe errno: this might only change if the locale |
97 | * ... but most known systems have threadsafe errno: this might only change | 80 | * is changed out from under someone while this function is being called */ |
98 | * if the locale is changed out from under someone while this function is being called | ||
99 | */ | ||
100 | (void)buff; | 81 | (void)buff; |
101 | (void)sz; | 82 | (void)sz; |
102 | return strerror(en); | 83 | return strerror(en); |
@@ -579,12 +560,10 @@ COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char | |||
579 | * dictate this to the user. A quick check shows that fopen_s this | 560 | * dictate this to the user. A quick check shows that fopen_s this |
580 | * goes back to VS 2005, and _fsopen goes back to VS 2003 .NET, | 561 | * goes back to VS 2005, and _fsopen goes back to VS 2003 .NET, |
581 | * possibly even before that so we don't need to do any version | 562 | * possibly even before that so we don't need to do any version |
582 | * number checks, since this has been there since forever. | 563 | * number checks, since this has been there since forever. */ |
583 | */ | ||
584 | 564 | ||
585 | /* TO USER: if you want the behavior of typical fopen_s/fopen, | 565 | /* TO USER: if you want the behavior of typical fopen_s/fopen, |
586 | * which does lock the file on VC++, define the macro used below to 0 | 566 | * which does lock the file on VC++, define the macro used below to 0 */ |
587 | */ | ||
588 | #if COMPAT53_FOPEN_NO_LOCK | 567 | #if COMPAT53_FOPEN_NO_LOCK |
589 | lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */ | 568 | lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */ |
590 | if (lf.f == NULL) | 569 | if (lf.f == NULL) |