From: VMware, Inc <> Date: Wed, 20 Jan 2010 21:37:07 +0000 (-0800) Subject: Add Str_Strerror, a thread safe version of strerror X-Git-Tag: 2010.01.19-226760~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3afb0ca24131be7a800cef35dc51f25070883f5;p=thirdparty%2Fopen-vm-tools.git Add Str_Strerror, a thread safe version of strerror strerror is not thread safe, it reuses the memory for the error string on every call. strerror_r is thread safe, but requires callers to manage their buffers. Add a new Str_Strerror function that uses thread local storage to keep the error string. This function is only present on GLIBC_VERSION_23 and later. The change to vmm-link-vmm-to-static.make undefines GLIB_VERSION_23, which was erroneously set. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/include/str.h b/open-vm-tools/lib/include/str.h index 81be1566d..6b2722959 100644 --- a/open-vm-tools/lib/include/str.h +++ b/open-vm-tools/lib/include/str.h @@ -98,6 +98,9 @@ EXTERN char *Str_Strnstr(const char *src, const char *sub, size_t n); EXTERN char *Str_Strcpy(char *dst, const char *src, size_t maxLen); EXTERN char *Str_Strcat(char *dst, const char *src, size_t maxLen); EXTERN char *Str_Strncat(char *buf, size_t bufSize, const char *src, size_t n); +#if defined(GLIBC_VERSION_23) +EXTERN const char *Str_Strerror(int errnum); +#endif EXTERN char *Str_Asprintf(size_t *length, const char *format, ...) PRINTF_DECL(2, 3); diff --git a/open-vm-tools/lib/string/str.c b/open-vm-tools/lib/string/str.c index 801d1dadd..9e547d972 100644 --- a/open-vm-tools/lib/string/str.c +++ b/open-vm-tools/lib/string/str.c @@ -48,6 +48,9 @@ #include "bsd_output.h" #endif #include "codeset.h" +#if defined(GLIBC_VERSION_23) +#define MAX_ERRSTR_SIZE 128 +#endif #if defined _WIN32 && !defined HAS_BSD_PRINTF #define vsnprintf _vsnprintf @@ -101,7 +104,6 @@ Str_Sprintf(char *buf, // OUT const char *fmt, // IN ...) // IN { - uint32 *stack = (uint32*) &buf; va_list args; int i; @@ -109,7 +111,8 @@ Str_Sprintf(char *buf, // OUT i = Str_Vsnprintf(buf, maxSize, fmt, args); va_end(args); if (i < 0) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); + Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, + GetReturnAddress()); } return i; } @@ -241,7 +244,6 @@ Str_Strcpy(char *buf, // OUT const char *src, // IN size_t maxSize) // IN { - uint32 *stack = (uint32 *)&buf; size_t len; ASSERT(buf != NULL); @@ -249,8 +251,9 @@ Str_Strcpy(char *buf, // OUT len = strlen(src); if (len >= maxSize) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); - ASSERT_BUG(5686, FALSE); + Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, + GetReturnAddress()); + ASSERT_BUG(5686, FALSE); // Presumably in case Panic is stubbed } return memcpy(buf, src, len + 1); } @@ -359,7 +362,6 @@ Str_Strcat(char *buf, // IN-OUT const char *src, // IN size_t maxSize) // IN { - uint32 *stack = (uint32 *)&buf; size_t bufLen; size_t srcLen; @@ -371,7 +373,8 @@ Str_Strcat(char *buf, // IN-OUT /* The first comparison checks for numeric overflow */ if (bufLen + srcLen < srcLen || bufLen + srcLen >= maxSize) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); + Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, + GetReturnAddress()); } memcpy(buf + bufLen, src, srcLen + 1); @@ -405,13 +408,11 @@ Str_Strncat(char *buf, // IN-OUT const char *src, // IN: String to append size_t n) // IN: Max chars of src to append { - uint32 *stack; size_t bufLen; ASSERT(buf != NULL); ASSERT(src != NULL); - stack = (uint32 *)&buf; bufLen = strlen(buf); /* @@ -428,7 +429,8 @@ Str_Strncat(char *buf, // IN-OUT if (bufLen + n >= bufSize && bufLen + strlen(src) >= bufSize) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__,__LINE__, stack[-1]); + Panic("%s:%d Buffer too small %p\n", __FILE__,__LINE__, + GetReturnAddress()); } /* @@ -440,6 +442,41 @@ Str_Strncat(char *buf, // IN-OUT } +#if defined(GLIBC_VERSION_23) +/* + *---------------------------------------------------------------------- + * + * Str_Strerror -- + * + * User level wrapper for strerror that is thread safe. + * + * Results: + * Same as strerror. + * + * Side effects: + * Allocates per-thread strerror string. + * + *---------------------------------------------------------------------- + */ + +const char * +Str_Strerror(int errnum) // IN: errno value +{ + static __thread char strerrorString[MAX_ERRSTR_SIZE]; + char *ret; + + ret = strerror_r(errnum, strerrorString, MAX_ERRSTR_SIZE); + + if (!ret) { + Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, + GetReturnAddress()); + } + + return ret; +} +#endif + + /* *----------------------------------------------------------------------------- * @@ -669,7 +706,6 @@ Str_Swprintf(wchar_t *buf, // OUT const wchar_t *fmt, // IN ...) // IN { - uint32 *stack = (uint32*) &buf; va_list args; int i; @@ -677,7 +713,8 @@ Str_Swprintf(wchar_t *buf, // OUT i = Str_Vsnwprintf(buf, maxSize, fmt, args); va_end(args); if (i < 0) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); + Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, + GetReturnAddress()); } return i; } @@ -804,13 +841,13 @@ Str_Wcscpy(wchar_t *buf, // OUT const wchar_t *src, // IN size_t maxSize) // IN: Size of buf, in wide-characters. { - uint32 *stack = (uint32 *)&buf; size_t len; len = wcslen(src); if (len >= maxSize) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); - ASSERT_BUG(5686, FALSE); + Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, + GetReturnAddress()); + ASSERT_BUG(5686, FALSE); // Presumably in case Panic is stubbed } return memcpy(buf, src, (len + 1)*sizeof(wchar_t)); } @@ -837,7 +874,6 @@ Str_Wcscat(wchar_t *buf, // IN-OUT const wchar_t *src, // IN size_t maxSize) // IN: Size of buf, in wide-characters. { - uint32 *stack = (uint32 *)&buf; size_t bufLen; size_t srcLen; @@ -846,7 +882,8 @@ Str_Wcscat(wchar_t *buf, // IN-OUT /* The first comparison checks for numeric overflow */ if (bufLen + srcLen < srcLen || bufLen + srcLen >= maxSize) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); + Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, + GetReturnAddress()); } memcpy(buf + bufLen, src, (srcLen + 1)*sizeof(wchar_t)); @@ -880,7 +917,6 @@ Str_Wcsncat(wchar_t *buf, // IN-OUT const wchar_t *src, // IN: String to append size_t n) // IN: Max chars of src to append { - uint32 *stack = (uint32 *)&buf; size_t bufLen = wcslen(buf); /* @@ -897,7 +933,8 @@ Str_Wcsncat(wchar_t *buf, // IN-OUT if (bufLen + n >= bufSize && bufLen + wcslen(src) >= bufSize) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__,__LINE__, stack[-1]); + Panic("%s:%d Buffer too small %p\n", __FILE__,__LINE__, + GetReturnAddress()); } /* @@ -930,12 +967,12 @@ Str_Mbscpy(char *buf, // OUT const char *src, // IN size_t maxSize) // IN { - uint32 *stack = (uint32 *)&buf; size_t len; len = strlen((const char *) src); if (len >= maxSize) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); + Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, + GetReturnAddress()); } return memcpy(buf, src, len + 1); } @@ -965,7 +1002,6 @@ Str_Mbscat(char *buf, // IN-OUT const char *src, // IN size_t maxSize) // IN { - uint32 *stack = (uint32 *)&buf; size_t bufLen; size_t srcLen; @@ -974,7 +1010,8 @@ Str_Mbscat(char *buf, // IN-OUT /* The first comparison checks for numeric overflow */ if (bufLen + srcLen < srcLen || bufLen + srcLen >= maxSize) { - Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]); + Panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, + GetReturnAddress()); } memcpy(buf + bufLen, src, srcLen + 1);