A user reports that ndctl fails to compile on MUSL systems:

daxctl/device.c: In function 'parse_device_options':
daxctl/device.c:377:26: error: implicit declaration of function 'basename' 
[-Wimplicit-function-declaration]
  377 |                 device = basename(argv[0]);
      |                          ^~~~~~~~

There are two versions of basename() with different behaviors:
        GNU basename() from <string.h>: doesn't modify its argument
        POSIX basename() from <libgen.h>: may modify its argument
glibc provides both versions, while MUSL libc only provides the POSIX
version.

In daxctl/device.c, basename() is called without any header, relying
on the GNU extension being implicitly available. And in daxctl/lib/
libdaxctl.c, libgen.h is included and the POSIX basename() used,
which works but is needlessly complex as POSIX basename() can modify
its argument.

Rather than conditionally including headers or dealing with platform
differences, replace both basename() usages with a new implementation
using strrchar to find the last '/' in the path and return everything
after it, or the whole string if no '/' is found.

Closes: https://github.com/pmem/ndctl/issues/283
Signed-off-by: Alison Schofield <[email protected]>
---
 daxctl/device.c        | 8 +++++---
 daxctl/lib/libdaxctl.c | 4 ++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/daxctl/device.c b/daxctl/device.c
index e3993b17c260..44a0a0ddb1d4 100644
--- a/daxctl/device.c
+++ b/daxctl/device.c
@@ -362,11 +362,13 @@ static const char *parse_device_options(int argc, const 
char **argv,
        };
        unsigned long long units = 1;
        int i, rc = 0;
-       char *device = NULL;
+       const char *device = NULL;
 
        argc = parse_options(argc, argv, options, u, 0);
-       if (argc > 0)
-               device = basename(argv[0]);
+       if (argc > 0) {
+               device = strrchr(argv[0], '/');
+               device = device ? device + 1 : argv[0];
+       }
 
        /* Handle action-agnostic non-option arguments */
        if (argc == 0 &&
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index b7fa0de0b73d..eee1d02c3714 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -3,7 +3,6 @@
 #include <stdio.h>
 #include <errno.h>
 #include <limits.h>
-#include <libgen.h>
 #include <stdlib.h>
 #include <dirent.h>
 #include <unistd.h>
@@ -408,7 +407,8 @@ DAXCTL_EXPORT int daxctl_dev_is_system_ram_capable(struct 
daxctl_dev *dev)
        if (!mod_path)
                return false;
 
-       mod_base = basename(mod_path);
+       mod_base = strrchr(mod_path, '/');
+       mod_base = mod_base ? mod_base + 1 : mod_path;
        if (strcmp(mod_base, dax_modules[DAXCTL_DEV_MODE_RAM]) == 0) {
                free(mod_path);
                return true;
-- 
2.37.3


Reply via email to