|
@@ -3105,14 +3105,22 @@ void perror(register const char *s)
|
|
|
#ifdef __STDIO_PRINTF_M_SPEC
|
|
|
fprintf(_stderr, "%s%s%m\n", s, sep);
|
|
|
#else
|
|
|
-
|
|
|
- fprintf(_stderr, "%s%s%s\n", s, sep, strerror(errno));
|
|
|
+ {
|
|
|
+ char buf[64];
|
|
|
+ fprintf(_stderr, "%s%s%s\n", s, sep,
|
|
|
+ _stdio_strerror_r(errno, buf, sizeof(buf)));
|
|
|
+ }
|
|
|
#endif
|
|
|
#else
|
|
|
|
|
|
- __STDIO_THREADLOCK(stderr);
|
|
|
- _stdio_fdout(STDERR_FILENO, s, sep, strerror(errno));
|
|
|
- __STDIO_THREADUNLOCK(stderr);
|
|
|
+ {
|
|
|
+ char buf[64];
|
|
|
+
|
|
|
+ __STDIO_THREADLOCK(stderr);
|
|
|
+ _stdio_fdout(STDERR_FILENO, s, sep,
|
|
|
+ _stdio_strerror_r(errno, buf, sizeof(buf)));
|
|
|
+ __STDIO_THREADUNLOCK(stderr);
|
|
|
+ }
|
|
|
#endif
|
|
|
}
|
|
|
|
|
@@ -3209,3 +3217,38 @@ char *_uintmaxtostr(char * __restrict bufend, uintmax_t uval,
|
|
|
#undef INTERNAL_DIV_MOD
|
|
|
|
|
|
#endif
|
|
|
+
|
|
|
+#ifdef L__stdio_strerror_r
|
|
|
+
|
|
|
+
|
|
|
+ * appropriately.
|
|
|
+ *
|
|
|
+ * WARNING!!! While it is similar to the glibc strerror_r function,
|
|
|
+ * it is not the same. It is expected that "unknown" error strings
|
|
|
+ * will fit in the buffer passed. Also, the return value may not
|
|
|
+ * be == buf, as unknown strings are "right-justified" in the buf
|
|
|
+ * due to the way _int10stostr works. */
|
|
|
+
|
|
|
+static const char unknown[] = "Unknown error";
|
|
|
+
|
|
|
+char *_stdio_strerror_r(int err, char *buf, size_t buflen)
|
|
|
+{
|
|
|
+ int errsave;
|
|
|
+
|
|
|
+ assert(buflen >= __UIM_BUFLEN_INT + sizeof(unknown));
|
|
|
+
|
|
|
+ errsave = errno;
|
|
|
+
|
|
|
+ if (strerror_r(err, buf, buflen)) {
|
|
|
+ __set_errno(errsave);
|
|
|
+
|
|
|
+ buf = _int10tostr(buf+buflen-1, err) - sizeof(unknown);
|
|
|
+ strcpy(buf, unknown);
|
|
|
+ buf[sizeof(unknown)-1] = ' ';
|
|
|
+ }
|
|
|
+
|
|
|
+ return buf;
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|