getloadavg: Don't clobber LIBS. Regression from previous commit.
[pspp] / lib / strerror.c
index f0e03df95dfca4f004d30b9256993723cd78246c..d0dd1af98431674050072e6c725a6909408dc5c6 100644 (file)
 /* Specification.  */
 #include <string.h>
 
-#if REPLACE_STRERROR
-
-# include <errno.h>
-# include <stdio.h>
-# include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
-# include "intprops.h"
-# include "verify.h"
+#include "intprops.h"
+#include "strerror-override.h"
+#include "verify.h"
 
 /* Use the system functions, not the gnulib overrides in this file.  */
-# undef sprintf
+#undef sprintf
+
+char *
+strerror (int n)
+#undef strerror
+{
+  static char buf[STACKBUF_LEN];
+  size_t len;
+
+  /* Cast away const, due to the historical signature of strerror;
+     callers should not be modifying the string.  */
+  const char *msg = strerror_override (n);
+  if (msg)
+    return (char *) msg;
+
+  /* FreeBSD rejects 0; see http://austingroupbugs.net/view.php?id=382.
+     MacOS X 10.5 does not distinguish 0 from -1.  */
+  if (n)
+    msg = strerror (n);
+  else
+    {
+      int saved_errno = errno;
+      errno = 0;
+      msg = strerror (n);
+      if (errno || (msg &&
+                    (strstr (msg, "nknown") || strstr (msg, "ndefined"))))
+        msg = "Success";
+      errno = saved_errno;
+    }
+
+  /* Our strerror_r implementation might use the system's strerror
+     buffer, so all other clients of strerror have to see the error
+     copied into a buffer that we manage.  This is not thread-safe,
+     even if the system strerror is, but portable programs shouldn't
+     be using strerror if they care about thread-safety.  */
+  if (!msg || !*msg)
+    {
+      static char const fmt[] = "Unknown error %d";
+      verify (sizeof buf >= sizeof (fmt) + INT_STRLEN_BOUND (n));
+      sprintf (buf, fmt, n);
+      errno = EINVAL;
+      return buf;
+    }
 
-# include "strerror-impl.h"
+  /* Fix STACKBUF_LEN if this ever aborts.  */
+  len = strlen (msg);
+  if (sizeof buf <= len)
+    abort ();
 
-#endif
+  return memcpy (buf, msg, len + 1);
+}