fts: add/use new struct member, fts_dirp
[gnulib.git] / lib / strerror_r.c
index 93e33fa..2b3f1f2 100644 (file)
@@ -175,18 +175,11 @@ strerror_r (int errnum, char *buf, size_t buflen)
         ret = strerror_r (errnum, buf, buflen);
     }
 # else
-    /* Solaris 10 does not populate buf on ERANGE.  */
     ret = strerror_r (errnum, buf, buflen);
-    if (ret == ERANGE && !*buf)
-      {
-        char stackbuf[STACKBUF_LEN];
 
-        /* strerror-impl.h is also affected if our choice of stackbuf
-           size is not large enough.  */
-        if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE)
-          abort ();
-        safe_copy (buf, buflen, stackbuf);
-      }
+    /* Some old implementations may return (-1, EINVAL) instead of EINVAL.  */
+    if (ret < 0)
+      ret = errno;
 # endif
 
 # ifdef _AIX
@@ -198,21 +191,29 @@ strerror_r (int errnum, char *buf, size_t buflen)
         size_t len;
         strerror_r (errnum, stackbuf, sizeof stackbuf);
         len = strlen (stackbuf);
-        /* stackbuf should have been large enough.  */
+        /* STACKBUF_LEN should have been large enough.  */
         if (len + 1 == sizeof stackbuf)
           abort ();
         if (buflen <= len)
           ret = ERANGE;
       }
-# endif
-
-    /* Some old implementations may return (-1, EINVAL) instead of EINVAL.  */
-    if (ret < 0)
-      ret = errno;
+# else
+    /* Solaris 10 does not populate buf on ERANGE.  OpenBSD 4.7
+       truncates early on ERANGE rather than return a partial integer.
+       We prefer the maximal string.  We set buf[0] earlier, and we
+       know of no implementation that modifies buf to be an
+       unterminated string, so this strlen should be portable in
+       practice (rather than pulling in a safer strnlen).  */
+    if (ret == ERANGE && strlen (buf) < buflen - 1)
+      {
+        char stackbuf[STACKBUF_LEN];
 
-    /* FreeBSD rejects 0; see http://austingroupbugs.net/view.php?id=382.  */
-    if (errnum == 0 && ret == EINVAL)
-      ret = safe_copy (buf, buflen, "Success");
+        /* STACKBUF_LEN should have been large enough.  */
+        if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE)
+          abort ();
+        safe_copy (buf, buflen, stackbuf);
+      }
+# endif
 
 #else /* USE_SYSTEM_STRERROR */