mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
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.
This commit is contained in:
parent
3526fbbc5f
commit
c81b3e1ee3
Notes:
sideshowbarker
2024-07-18 17:25:18 +09:00
Author: https://github.com/gunnarbeutner Commit: https://github.com/SerenityOS/serenity/commit/c81b3e1ee3c Pull-request: https://github.com/SerenityOS/serenity/pull/7448 Reviewed-by: https://github.com/ADKaster
4 changed files with 40 additions and 0 deletions
|
@ -6,6 +6,7 @@ set(TEST_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/TestLibCExec.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/TestLibCExec.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/TestLibCDirEnt.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/TestLibCDirEnt.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/TestLibCInodeWatcher.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/TestLibCInodeWatcher.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/TestLibCString.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp")
|
file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp")
|
||||||
|
|
18
Tests/LibC/TestLibCString.cpp
Normal file
18
Tests/LibC/TestLibCString.cpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibTest/TestCase.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
TEST_CASE(strerror_r_basic)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(strerror_r(1000, nullptr, 0), EINVAL);
|
||||||
|
EXPECT_EQ(strerror_r(EFAULT, nullptr, 0), ERANGE);
|
||||||
|
char buf[64];
|
||||||
|
EXPECT_EQ(strerror_r(EFAULT, buf, sizeof(buf)), 0);
|
||||||
|
EXPECT_EQ(strcmp(buf, "Bad address"), 0);
|
||||||
|
}
|
|
@ -354,6 +354,26 @@ const char* const sys_errlist[] = {
|
||||||
|
|
||||||
int sys_nerr = EMAXERRNO;
|
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)
|
char* strerror(int errnum)
|
||||||
{
|
{
|
||||||
if (errnum < 0 || errnum >= EMAXERRNO) {
|
if (errnum < 0 || errnum >= EMAXERRNO) {
|
||||||
|
|
|
@ -43,6 +43,7 @@ char* strncat(char* dest, const char* src, size_t);
|
||||||
|
|
||||||
size_t strspn(const char*, const char* accept);
|
size_t strspn(const char*, const char* accept);
|
||||||
size_t strcspn(const char*, const char* reject);
|
size_t strcspn(const char*, const char* reject);
|
||||||
|
int strerror_r(int, char*, size_t);
|
||||||
char* strerror(int errnum);
|
char* strerror(int errnum);
|
||||||
char* strsignal(int signum);
|
char* strsignal(int signum);
|
||||||
char* strpbrk(const char*, const char* accept);
|
char* strpbrk(const char*, const char* accept);
|
||||||
|
|
Loading…
Reference in a new issue