]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Add Str_Strerror, a thread safe version of strerror
authorVMware, Inc <>
Wed, 20 Jan 2010 21:37:07 +0000 (13:37 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Wed, 20 Jan 2010 21:37:07 +0000 (13:37 -0800)
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 <mvanzin@vmware.com>
open-vm-tools/lib/include/str.h
open-vm-tools/lib/string/str.c

index 81be1566d999255a4d12170abb9dfd3969ddb38c..6b2722959674055f61e7d428d37c8ddd17a33b20 100644 (file)
@@ -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);
index 801d1dadd6e63c73a6d36c626ada00d802aa1c8c..9e547d9725395f6ea6566ad49fb63ca6f82e6e43 100644 (file)
@@ -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);