diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-05-24 16:43:12 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-25 17:36:02 +0200 |
commit | c81b3e1ee3c005f1703f8a9e47b53b3ed836fc32 (patch) | |
tree | 1aa0cbd7edf718bfcf9dbf4c7eada0f67a0f48bc /Userland/Libraries/LibC | |
parent | 3526fbbc5f548935efc79bad3ce5d396a6d58e3b (diff) | |
download | serenity-c81b3e1ee3c005f1703f8a9e47b53b3ed836fc32.zip |
LibC: Implement strerror_r()
This implements the XSI-compliant version of strerror_r() - as opposed
to the GNU-specific variant.
The function explicitly saves errno so as to not accidentally change it
with one of the calls to other functions.
Diffstat (limited to 'Userland/Libraries/LibC')
-rw-r--r-- | Userland/Libraries/LibC/string.cpp | 20 | ||||
-rw-r--r-- | Userland/Libraries/LibC/string.h | 1 |
2 files changed, 21 insertions, 0 deletions
diff --git a/Userland/Libraries/LibC/string.cpp b/Userland/Libraries/LibC/string.cpp index db74946ae8..3847afb6dc 100644 --- a/Userland/Libraries/LibC/string.cpp +++ b/Userland/Libraries/LibC/string.cpp @@ -354,6 +354,26 @@ const char* const sys_errlist[] = { int sys_nerr = EMAXERRNO; +int strerror_r(int errnum, char* buf, size_t buflen) +{ + auto saved_errno = errno; + if (errnum >= EMAXERRNO) { + auto rc = strlcpy(buf, "unknown error", buflen); + if (rc >= buflen) + dbgln("strerror_r(): Invalid error number '{}' specified and the output buffer is too small.", errnum); + errno = saved_errno; + return EINVAL; + } + auto text = strerror(errnum); + auto rc = strlcpy(buf, text, buflen); + if (rc >= buflen) { + errno = saved_errno; + return ERANGE; + } + errno = saved_errno; + return 0; +} + char* strerror(int errnum) { if (errnum < 0 || errnum >= EMAXERRNO) { diff --git a/Userland/Libraries/LibC/string.h b/Userland/Libraries/LibC/string.h index beaf594a33..d7010ef6ac 100644 --- a/Userland/Libraries/LibC/string.h +++ b/Userland/Libraries/LibC/string.h @@ -43,6 +43,7 @@ char* strncat(char* dest, const char* src, size_t); size_t strspn(const char*, const char* accept); size_t strcspn(const char*, const char* reject); +int strerror_r(int, char*, size_t); char* strerror(int errnum); char* strsignal(int signum); char* strpbrk(const char*, const char* accept); |