Despite 03a5456 ("libmultipath: always use glibc basename()"), we still call the system library's basename() from libmultipath. musl libc until 1.24 provided a prototype for basename() in string.h, which was not correct and was resolved to the destructive POSIX basename(). musl libc 1.25 removed this prototype. While the remaining code path doesn't strictly depend on the non-destructive behavior of glibc's basename(), it's cleaner and safer to use the same implementation everywhere. Fixes: 03a5456 ("libmultipath: always use glibc basename()") Fixes: https://github.com/opensvc/multipath-tools/pull/84 Signed-off-by: Martin Wilck <mwilck@xxxxxxxx> Reviewed-by: Khem Raj <raj.khem@xxxxxxxxx> Reviewed-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx> --- mwilck: Already reviewed and queued, posting to dm-devel for information. --- libmpathutil/libmpathutil.version | 4 ++++ libmpathutil/util.c | 5 +---- libmpathutil/util.h | 5 +++++ tests/util.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version index 80d64a3..fee74a3 100644 --- a/libmpathutil/libmpathutil.version +++ b/libmpathutil/libmpathutil.version @@ -129,3 +129,7 @@ LIBMPATHUTIL_2.0 { vector_move_up; vector_sort; }; + +LIBMPATHUTIL_2.1 { + libmp_basename; +}; diff --git a/libmpathutil/util.c b/libmpathutil/util.c index 9d147fc..23d303f 100644 --- a/libmpathutil/util.c +++ b/libmpathutil/util.c @@ -32,18 +32,15 @@ strchop(char *str) return i; } -#ifndef __GLIBC__ /* * glibc's non-destructive version of basename() * License: LGPL-2.1-or-later */ -static const char *__basename(const char *filename) +const char *libmp_basename(const char *filename) { char *p = strrchr(filename, '/'); return p ? p + 1 : filename; } -#define basename(x) __basename(x) -#endif int basenamecpy (const char *src, char *dst, size_t size) diff --git a/libmpathutil/util.h b/libmpathutil/util.h index de9fcfd..4997fed 100644 --- a/libmpathutil/util.h +++ b/libmpathutil/util.h @@ -12,6 +12,11 @@ #include <stdio.h> size_t strchop(char *); + +const char *libmp_basename(const char *filename); +#ifndef __GLIBC__ +#define basename(x) libmp_basename(x) +#endif int basenamecpy (const char *src, char *dst, size_t size); int filepresent (const char *run); char *get_next_string(char **temp, const char *split_char); diff --git a/tests/util.c b/tests/util.c index d6083dc..4850ddc 100644 --- a/tests/util.c +++ b/tests/util.c @@ -16,6 +16,7 @@ * */ +#define _GNU_SOURCE #include <stdbool.h> #include <stdarg.h> #include <stddef.h> @@ -23,6 +24,7 @@ #include <stdlib.h> #include <cmocka.h> #include <endian.h> +#include <string.h> #include "util.h" #include "globals.c" @@ -163,6 +165,34 @@ static int test_basenamecpy(void) return cmocka_run_group_tests(tests, NULL, NULL); } +static void test_basename_01(void **state) +{ + const char *path = "/foo/bar"; + const char *base; + + base = basename(path); + assert_string_equal(base, "bar"); + assert_string_equal(path, "/foo/bar"); +} + +static void test_basename_02(void **state) +{ + const char *path = "/foo/bar/"; + const char *base; + + base = basename(path); + assert_string_equal(base, ""); + assert_string_equal(path, "/foo/bar/"); +} + +static int test_basename(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_basename_01), + cmocka_unit_test(test_basename_02), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} + /* * On big endian systems, if bitfield_t is 32bit, we need * to swap the two 32 bit parts of a 64bit value to make @@ -946,6 +976,7 @@ int main(void) init_test_verbosity(-1); ret += test_basenamecpy(); + ret += test_basename(); ret += test_bitmasks(); ret += test_strlcpy(); ret += test_strlcat(); -- 2.44.0