[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/2] libc: Implementiere strerror_r()
+ Eigentlich ist das relativ einfach, weil strerror() schon snprintf()
benutzt. Leider gibt es aber grundsätzlich zwei Versionen von
strerror_r(), und die Manpage sagt im Prinzip, dass per default die
XSI-Variante benutzt wird, aber bei _GNU_SOURCE dann die GNU-Variante.
Das klingt, als sollten wir am besten beide anbieten, und das macht
das ganze dann leider komplizierter, als es nötig sein sollte.
Signed-off-by: Hanna Reitz <hanna.reitz@xxxxxxxxxxx>
---
src/include/string.h | 6 +++++
src/modules/lib/posix/strerror.c | 40 ++++++++++++++++++++++++++++----
2 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/src/include/string.h b/src/include/string.h
index c7a69831..db244ac3 100644
--- a/src/include/string.h
+++ b/src/include/string.h
@@ -83,6 +83,12 @@ char* strndup(const char* str, size_t n);
char *strpbrk(const char *s1, const char *s2);
char* strerror(int error_code);
+#if (_POSIX_C_SOURCE >= 200112l) && !defined(_GNU_SOURCE)
+int _xsi_strerror_r(int error_code, char* buf, size_t buflen);
+#define strerror_r _xsi_strerror_r
+#else
+char* strerror_r(int error_code, char* buf, size_t buflen);
+#endif
int strcasecmp(const char* s1, const char* s2);
int strncasecmp(const char* s1, const char* s2, size_t n);
diff --git a/src/modules/lib/posix/strerror.c b/src/modules/lib/posix/strerror.c
index d73b3a7d..28a0a8a4 100644
--- a/src/modules/lib/posix/strerror.c
+++ b/src/modules/lib/posix/strerror.c
@@ -31,6 +31,12 @@
#include <stdio.h>
#include <errno.h>
+// string.h koennte dieses Macro definiert haben, aber hier koennen wir
+// das nicht brauchen.
+#ifdef strerror_r
+#undef strerror_r
+#endif
+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
static char* error_messages[] = {
@@ -61,22 +67,46 @@ static char* error_messages[] = {
* TODO: ATM nur stub
*
* @param error_code Fehlernummer
+ * @param buf Puffer, in dem die Fehlermeldung gespeichert wird
+ * @param buflen Laenge des Puffers
*
- * @return Pointer auf internen Buffer mit Fehlermeldung
+ * @return 0 bei Erfolg, sonst errno (errno wird ebenfalls gesetzt)
*/
-char* strerror(int error_code)
+int _xsi_strerror_r(int error_code, char* buf, size_t buflen)
{
- static char error_message[64];
+ int old_errno = errno;
+ int printf_len;
+ int ret = 0;
if (error_code >= 0 && error_code < ARRAY_SIZE(error_messages) &&
error_messages[error_code] != NULL)
{
- snprintf(error_message, sizeof(error_message),
+ printf_len = snprintf(buf, buflen,
"%s (%d)", error_messages[error_code], error_code);
+ errno = old_errno; // errno nicht veraendern
} else {
- snprintf(error_message, sizeof(error_message),
+ printf_len = snprintf(buf, buflen,
"Unbekannter Fehler %d", error_code);
+ ret = errno = EINVAL;
}
+
+ if (printf_len >= buflen) {
+ ret = errno = ERANGE;
+ }
+
+ return ret;
+}
+
+char* strerror(int error_code)
+{
+ static char error_message[64];
+ _xsi_strerror_r(error_code, error_message, sizeof(error_message));
return error_message;
}
+char* strerror_r(int error_code, char* buf, size_t buflen)
+{
+ _xsi_strerror_r(error_code, buf, buflen);
+ return buf;
+}
+
--
2.31.0