From 46d80a79c97c7a8de493fb5134ff25044017e189 Mon Sep 17 00:00:00 2001 From: Aleksander Kaminski Date: Thu, 10 Aug 2023 14:25:25 +0200 Subject: [PATCH] string: strerror_r() implementation DONE: RTOS-554 --- include/string.h | 4 ++++ string/strerror.c | 58 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/include/string.h b/include/string.h index 30b90dd0..3b337df5 100644 --- a/include/string.h +++ b/include/string.h @@ -115,6 +115,10 @@ extern size_t strcspn(const char *str1, const char *str2); extern char *strerror(int errnum); +/* Thread-safe strerror. */ +extern int strerror_r(int errnum, char *buf, size_t buflen); + + /* Computes the length of the string str up to but not including the terminating null character. */ extern size_t strlen(const char *str); diff --git a/string/strerror.c b/string/strerror.c index d7c484ac..be719142 100644 --- a/string/strerror.c +++ b/string/strerror.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -44,7 +45,6 @@ static const errinfo_t gaitab[] = { // static assert: 16-bit offset static const char assert_errnames_size[-(sizeof(errnames) > 0xFFFF)] __attribute__((unused)); static const char assert_gainames_size[-(sizeof(gainames) > 0xFFFF)] __attribute__((unused)); -static char err_unknownMsg[32]; /* FIXME: Make thread safe? IMHO overkill */ static int err_cmp(const void *key, const void *elem) @@ -56,7 +56,7 @@ static int err_cmp(const void *key, const void *elem) } -static inline const char *strerror_(const errinfo_t *tab, size_t tabsz, const char *names, int errnum) +static inline const char *strerror_(const errinfo_t *tab, size_t tabsz, const char *names, int errnum, char *buff, size_t bufflen, int *err) { const errinfo_t *e; @@ -65,25 +65,61 @@ static inline const char *strerror_(const errinfo_t *tab, size_t tabsz, const ch } e = bsearch((void *)(long)errnum, tab, tabsz / sizeof(*tab), sizeof(*tab), err_cmp); - if (e == NULL) { - (void)sprintf(err_unknownMsg, "Unknown error %d", errnum); - errno = EINVAL; - return err_unknownMsg; - } - else { - return names + e->offset; + (void)snprintf(buff, bufflen, "Unknown error %d", errnum); + *err = EINVAL; + return buff; } + + return names + e->offset; } char *strerror(int errnum) { - return (char *)strerror_(errtab, sizeof(errtab), errnames, errnum); + static char unknownMsg[32]; + const char *str; + int err = 0; + + str = strerror_(errtab, sizeof(errtab), errnames, errnum, unknownMsg, sizeof(unknownMsg), &err); + if (err != 0) { + errno = err; + } + + return (char *)str; +} + + +int strerror_r(int errnum, char *buf, size_t buflen) +{ + char unknownMsg[32]; + const char *str; + int ret = 0; + size_t len; + + str = strerror_(errtab, sizeof(errtab), errnames, errnum, unknownMsg, sizeof(unknownMsg), &ret); + len = strlen(str); + if (buflen > len) { + memcpy(buf, str, len + 1); + } + else { + ret = ERANGE; + } + + return ret; } const char *gai_strerror(int errnum) { - return strerror_(gaitab, sizeof(gaitab), gainames, errnum); + static char unknownMsg[32]; + const char *str; + int err = 0; + + str = strerror_(gaitab, sizeof(gaitab), gainames, errnum, unknownMsg, sizeof(unknownMsg), &err); + if (err != 0) { + errno = err; + } + + return (char *)str; }