mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
musl: introduce two wrappers (#39700)
This commit is contained in:
7
src/include/musl/stdlib.h
Normal file
7
src/include/musl/stdlib.h
Normal file
@@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include_next <stdlib.h>
|
||||
|
||||
long long strtoll_fallback(const char *nptr, char **endptr, int base);
|
||||
#define strtoll strtoll_fallback
|
||||
7
src/include/musl/string.h
Normal file
7
src/include/musl/string.h
Normal file
@@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include_next <string.h>
|
||||
|
||||
char* strerror_r_gnu(int errnum, char *buf, size_t buflen);
|
||||
#define strerror_r strerror_r_gnu
|
||||
@@ -6,4 +6,6 @@ endif
|
||||
|
||||
libc_wrapper_sources += files(
|
||||
'stdio.c',
|
||||
'stdlib.c',
|
||||
'string.c',
|
||||
)
|
||||
|
||||
19
src/libc/musl/stdlib.c
Normal file
19
src/libc/musl/stdlib.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* The header stdlib.h overrides strtoll with strtoll_fallback, hence we need to undef it here. */
|
||||
#undef strtoll
|
||||
|
||||
long long strtoll_fallback(const char *nptr, char **endptr, int base) {
|
||||
/* glibc returns 0 if the first character is '.' without error, but musl returns as an error.
|
||||
* As our code assumes the glibc behavior, let's accept strings start with '.'. */
|
||||
if (nptr && *nptr == '.') {
|
||||
if (endptr)
|
||||
*endptr = (char*) nptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, use the native strtoll(). */
|
||||
return strtoll(nptr, endptr, base);
|
||||
}
|
||||
44
src/libc/musl/string.c
Normal file
44
src/libc/musl/string.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* MAX_ERRNO is defined as 4095 in linux/err.h. We use the same value here. */
|
||||
#define ERRNO_MAX 4095
|
||||
|
||||
/* strerror(3) says that glibc uses a maximum length of 1024 bytes. */
|
||||
#define ERRNO_BUF_LEN 1024
|
||||
|
||||
/* The header string.h overrides strerror_r with strerror_r_gnu, hence we need to undef it here. */
|
||||
#undef strerror_r
|
||||
|
||||
char* strerror_r_gnu(int errnum, char *buf, size_t buflen) {
|
||||
/* musl provides spurious catchall error message "No error information" for unknown errno
|
||||
* (including errno == 0). Let's patch it to glibc style. */
|
||||
|
||||
if (errnum == 0)
|
||||
return (char*) "Success";
|
||||
|
||||
if (buflen == 0)
|
||||
return (char*) "Unknown error";
|
||||
|
||||
if (errnum < 0 || errnum > ERRNO_MAX)
|
||||
goto fallback;
|
||||
|
||||
if (strerror_r(errnum, buf, buflen) != 0)
|
||||
goto fallback;
|
||||
|
||||
char buf_0[ERRNO_BUF_LEN];
|
||||
if (strerror_r(0, buf_0, sizeof buf_0) != 0) /* Wut?? */
|
||||
goto fallback;
|
||||
|
||||
/* strerror_r() may truncate the result. In that case, let's not compare the trailing NUL. */
|
||||
size_t n = (buflen < ERRNO_BUF_LEN ? buflen : ERRNO_BUF_LEN) - 1;
|
||||
if (strncmp(buf, buf_0, n) != 0)
|
||||
return buf;
|
||||
|
||||
fallback:
|
||||
snprintf(buf, buflen, "Unknown error %i", errnum);
|
||||
return buf;
|
||||
}
|
||||
@@ -230,7 +230,6 @@ TEST(sd_bus_error_set_errnof) {
|
||||
assert_se(sd_bus_error_set_errnof(&error, EACCES, NULL) == -EACCES);
|
||||
assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_ACCESS_DENIED));
|
||||
ASSERT_STREQ(error.message, STRERROR(EACCES));
|
||||
assert_se(error._need_free == 0);
|
||||
|
||||
str = mfree(str);
|
||||
sd_bus_error_free(&error);
|
||||
@@ -238,7 +237,6 @@ TEST(sd_bus_error_set_errnof) {
|
||||
assert_se(sd_bus_error_set_errnof(&error, ENOANO, NULL) == -ENOANO);
|
||||
assert_se(sd_bus_error_has_name(&error, "System.Error.ENOANO"));
|
||||
ASSERT_STREQ(error.message, STRERROR(ENOANO));
|
||||
assert_se(error._need_free == 1);
|
||||
|
||||
str = mfree(str);
|
||||
sd_bus_error_free(&error);
|
||||
@@ -246,7 +244,6 @@ TEST(sd_bus_error_set_errnof) {
|
||||
assert_se(sd_bus_error_set_errnof(&error, 100000, NULL) == -100000);
|
||||
assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_FAILED));
|
||||
ASSERT_STREQ(error.message, STRERROR(100000));
|
||||
assert_se(error._need_free == 1);
|
||||
|
||||
str = mfree(str);
|
||||
sd_bus_error_free(&error);
|
||||
@@ -262,7 +259,6 @@ TEST(sd_bus_error_set_errnof) {
|
||||
errno = EACCES;
|
||||
assert_se(asprintf(&str, "hoge %s: %m", "foo") >= 0);
|
||||
assert_se(streq(error.message, str));
|
||||
assert_se(error._need_free == 1);
|
||||
|
||||
str = mfree(str);
|
||||
sd_bus_error_free(&error);
|
||||
@@ -272,7 +268,6 @@ TEST(sd_bus_error_set_errnof) {
|
||||
errno = ENOANO;
|
||||
assert_se(asprintf(&str, "hoge %s: %m", "foo") >= 0);
|
||||
assert_se(streq(error.message, str));
|
||||
assert_se(error._need_free == 1);
|
||||
|
||||
str = mfree(str);
|
||||
sd_bus_error_free(&error);
|
||||
@@ -282,7 +277,6 @@ TEST(sd_bus_error_set_errnof) {
|
||||
errno = 100000;
|
||||
assert_se(asprintf(&str, "hoge %s: %m", "foo") >= 0);
|
||||
assert_se(streq(error.message, str));
|
||||
assert_se(error._need_free == 1);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, dump_mapping_table);
|
||||
|
||||
Reference in New Issue
Block a user