src/corelib/global/qglobal.cpp
changeset 23 89e065397ea6
parent 18 2f34d5167611
child 30 5dc02b23752f
--- a/src/corelib/global/qglobal.cpp	Fri May 14 16:40:13 2010 +0300
+++ b/src/corelib/global/qglobal.cpp	Thu May 27 13:40:48 2010 +0300
@@ -2075,7 +2075,28 @@
 }
 #endif // Q_CC_MWERKS && Q_OS_MACX
 
-
+#if !defined(Q_OS_WIN) && !defined(QT_NO_THREAD) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \
+    defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L
+namespace {
+    // There are two incompatible versions of strerror_r:
+    // a) the XSI/POSIX.1 version, which returns an int,
+    //    indicating success or not
+    // b) the GNU version, which returns a char*, which may or may not
+    //    be the beginning of the buffer we used
+    // The GNU libc manpage for strerror_r says you should use the the XSI
+    // version in portable code. However, it's impossible to do that if
+    // _GNU_SOURCE is defined so we use C++ overloading to decide what to do
+    // depending on the return type
+    static inline QString fromstrerror_helper(int, const QByteArray &buf)
+    {
+        return QString::fromLocal8Bit(buf);
+    }
+    static inline QString fromstrerror_helper(const char *str, const QByteArray &)
+    {
+        return QString::fromLocal8Bit(str);
+    }
+}
+#endif
 
 QString qt_error_string(int errorCode)
 {
@@ -2118,12 +2139,9 @@
 
         if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND)
             ret = QString::fromLatin1("The specified module could not be found.");
-
 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX)
-
         QByteArray buf(1024, '\0');
-        strerror_r(errorCode, buf.data(), buf.size());
-        ret = QString::fromLocal8Bit(buf.constData());
+        ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf);
 #else
         ret = QString::fromLocal8Bit(strerror(errorCode));
 #endif