From cdaf715a84f4978683cad6b18c32c21cc691bc69 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 21 Sep 2022 16:26:32 +0200 Subject: [PATCH 1/4] sys/string_utils: add strscpy() --- sys/Kconfig | 1 + sys/include/string_utils.h | 24 ++++++++++++++++++++++- sys/libc/Kconfig | 11 +++++++++++ sys/libc/Makefile | 1 + sys/libc/string.c | 40 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 sys/libc/Kconfig create mode 100644 sys/libc/Makefile create mode 100644 sys/libc/string.c diff --git a/sys/Kconfig b/sys/Kconfig index 4a6c84c21e..73354e3f5a 100644 --- a/sys/Kconfig +++ b/sys/Kconfig @@ -37,6 +37,7 @@ rsource "fs/Kconfig" rsource "hashes/Kconfig" rsource "iolist/Kconfig" rsource "isrpipe/Kconfig" +rsource "libc/Kconfig" menu "Libc" diff --git a/sys/include/string_utils.h b/sys/include/string_utils.h index eb0ec8641a..50f3db8a47 100644 --- a/sys/include/string_utils.h +++ b/sys/include/string_utils.h @@ -22,11 +22,13 @@ * @author Marian Buschsieweke */ +#include +#include /* if explicit_bzero() is provided by standard C lib, it may be defined in * either `string.h` or `strings.h`, so just include both here */ -#include #include #include +#include #include "kernel_defines.h" @@ -70,6 +72,26 @@ static inline void explicit_bzero(void *dest, size_t n_bytes) } #endif +/** + * @brief Copy the string, or as much of it as fits, into the dest buffer. + * + * Preferred to `strncpy` since it always returns a valid string, and doesn't + * unnecessarily force the tail of the destination buffer to be zeroed. + * If the zeroing is desired, it's likely cleaner to use `strscpy` with an + * overflow test, then just memset the tail of the dest buffer. + * + * @param[out] dest Where to copy the string to + * @param[in] src Where to copy the string from + * @param[in] count Size of destination buffer + * + * @pre The destination buffer is at least one byte large, as + * otherwise the terminating zero byte won't fit + * + * @return the number of characters copied (not including the trailing zero) + * @retval -E2BIG the destination buffer wasn't big enough + */ +ssize_t strscpy(char *dest, const char *src, size_t count); + #ifdef __cplusplus } #endif diff --git a/sys/libc/Kconfig b/sys/libc/Kconfig new file mode 100644 index 0000000000..eaa4895518 --- /dev/null +++ b/sys/libc/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2021 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. +# + +config MODULE_LIBC + bool "C Library helper functions" + default y + depends on TEST_KCONFIG diff --git a/sys/libc/Makefile b/sys/libc/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/sys/libc/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/sys/libc/string.c b/sys/libc/string.c new file mode 100644 index 0000000000..c3c1cc661a --- /dev/null +++ b/sys/libc/string.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 ML!PA Consulting GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + * + * @author Benjamin Valentin + */ + +#include +#include "string_utils.h" + +ssize_t strscpy(char *dest, const char *src, size_t count) +{ + const char *start = dest; + + if (!count) { + return -E2BIG; + } + + while (--count && *src) { + *dest++ = *src++; + } + + *dest = 0; + + if (*src == 0) { + return dest - start; + } else { + return -E2BIG; + } +} +/** @} */ From 887015860962820c0ffd18d3fbd7195cd9cee7e4 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 21 Sep 2022 16:27:02 +0200 Subject: [PATCH 2/4] libc: add to default modules --- makefiles/defaultmodules_regular.inc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefiles/defaultmodules_regular.inc.mk b/makefiles/defaultmodules_regular.inc.mk index 5dc2fa6e9c..6f5f46584c 100644 --- a/makefiles/defaultmodules_regular.inc.mk +++ b/makefiles/defaultmodules_regular.inc.mk @@ -6,7 +6,7 @@ DEFAULT_MODULE += board board_common_init \ cpu \ core core_init core_lib core_msg core_panic core_thread \ - sys + sys libc # Include potentially added default modules by the board -include $(BOARDDIR)/Makefile.default From 3fc4d9d98c236744c5fb7155c0c1da1ef3a76a3d Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 21 Sep 2022 16:27:31 +0200 Subject: [PATCH 3/4] tests/unittests: add tests for libc module --- tests/unittests/tests-libc/Makefile | 1 + tests/unittests/tests-libc/tests-libc.c | 46 +++++++++++++++++++++++++ tests/unittests/tests-libc/tests-libc.h | 44 +++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 tests/unittests/tests-libc/Makefile create mode 100644 tests/unittests/tests-libc/tests-libc.c create mode 100644 tests/unittests/tests-libc/tests-libc.h diff --git a/tests/unittests/tests-libc/Makefile b/tests/unittests/tests-libc/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/tests/unittests/tests-libc/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-libc/tests-libc.c b/tests/unittests/tests-libc/tests-libc.c new file mode 100644 index 0000000000..3d4a714ed3 --- /dev/null +++ b/tests/unittests/tests-libc/tests-libc.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2019 ML!PA Consulting GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include +#include +#include "string_utils.h" + +#include "tests-libc.h" + +static void test_libc_strscpy(void) +{ + char buffer[8]; + + TEST_ASSERT_EQUAL_INT(strscpy(buffer, "Hello", sizeof(buffer)), 5); + TEST_ASSERT_EQUAL_INT(strcmp(buffer, "Hello"), 0); + TEST_ASSERT_EQUAL_INT(strscpy(buffer, "012345678", sizeof(buffer)), -E2BIG); + TEST_ASSERT_EQUAL_INT(strcmp(buffer, "0123456"), 0); + memset(buffer, 0, sizeof(buffer)); + TEST_ASSERT_EQUAL_INT(strscpy(buffer, "01234567", sizeof(buffer)), -E2BIG); + TEST_ASSERT_EQUAL_INT(strcmp(buffer, "0123456"), 0); + memset(buffer, 0, sizeof(buffer)); + TEST_ASSERT_EQUAL_INT(strscpy(buffer, "0123456", sizeof(buffer)), 7); + TEST_ASSERT_EQUAL_INT(strcmp(buffer, "0123456"), 0); + TEST_ASSERT_EQUAL_INT(strscpy(buffer, "empty", 0), -E2BIG); +} + +Test *tests_libc_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_libc_strscpy), + }; + + EMB_UNIT_TESTCALLER(libc_tests, NULL, NULL, fixtures); + + return (Test *)&libc_tests; +} + +void tests_libc(void) +{ + TESTS_RUN(tests_libc_tests()); +} diff --git a/tests/unittests/tests-libc/tests-libc.h b/tests/unittests/tests-libc/tests-libc.h new file mode 100644 index 0000000000..619d92dccf --- /dev/null +++ b/tests/unittests/tests-libc/tests-libc.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2022 ML!PA Consulting GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file + * @brief Unittests for the ``libc`` module + * + * @author Benjamin Valentin + */ +#ifndef TESTS_LIBC_H +#define TESTS_LIBC_H + +#include "embUnit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The entry point of this test suite. + */ +void tests_libc(void); + +/** + * @brief Generates tests for libc + * + * @return embUnit tests if successful, NULL if not. + */ +Test *tests_libc_tests(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TESTS_LIBC_H */ +/** @} */ From 16491eaca724a689a673caaca0d2b0f25ab0997f Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 28 Sep 2022 09:57:39 +0200 Subject: [PATCH 4/4] sys/string_utils: fix check for native --- sys/include/string_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/include/string_utils.h b/sys/include/string_utils.h index 50f3db8a47..46bfb3def4 100644 --- a/sys/include/string_utils.h +++ b/sys/include/string_utils.h @@ -47,7 +47,7 @@ extern "C" { * * for all other cases, we provide it here */ -#if !defined(BOARD_NATIVE) \ +#if !defined(CPU_NATIVE) \ && !(IS_USED(MODULE_PICOLIBC) && __BSD_VISIBLE) \ && !(IS_USED(MODULE_NEWLIB) && __BSD_VISIBLE && !defined(MCU_ESP8266))