diff --git a/src/broker/broker.c b/src/broker/broker.c index b8601037edcf..19872f336b3a 100644 --- a/src/broker/broker.c +++ b/src/broker/broker.c @@ -53,6 +53,7 @@ #include "src/common/libutil/errno_safe.h" #include "src/common/libutil/errprintf.h" #include "src/common/libutil/intree.h" +#include "src/common/libutil/basename.h" #include "src/common/librouter/subhash.h" #include "src/common/libfluxutil/method.h" #include "ccan/array_size/array_size.h" @@ -689,8 +690,7 @@ static bool is_interactive_shell (const char *argz, size_t argz_len) char *shell; char *cmd = argz_next (argz, argz_len, NULL); while ((shell = getusershell ())) { - if (streq (cmd, shell) - || streq (cmd, basename (shell))) { + if (streq (cmd, shell) || streq (cmd, basename_simple (shell))) { result = true; break; } diff --git a/src/broker/module.c b/src/broker/module.c index e86b2b3efcde..4bca2a8b8614 100644 --- a/src/broker/module.c +++ b/src/broker/module.c @@ -37,6 +37,7 @@ #include "src/common/libutil/log.h" #include "src/common/libutil/errprintf.h" #include "src/common/libutil/errno_safe.h" +#include "src/common/libutil/basename.h" #include "src/common/librouter/subhash.h" #include "ccan/str/str.h" @@ -289,23 +290,16 @@ static void module_cb (flux_reactor_t *r, p->poller_cb (p, p->poller_arg); } -static char *module_name_from_path (const char *s) +static char *module_name_from_path (const char *path) { - char *path, *name, *cpy; + char *name; char *cp; - if (!(path = strdup (s)) - || !(name = basename (path))) - goto error; + name = basename_simple (path); + // if path ends in .so or .so.VERSION, strip it off if ((cp = strstr (name, ".so"))) - *cp = '\0'; - if (!(cpy = strdup (name))) - goto error; - free (path); - return cpy; -error: - ERRNO_SAFE_WRAP (free, path); - return NULL; + return strndup (name, cp - name); + return strdup (name); } module_t *module_create (flux_t *h, diff --git a/src/cmd/flux-exec.c b/src/cmd/flux-exec.c index 5135b11aaa7b..0507b1e1f5fb 100644 --- a/src/cmd/flux-exec.c +++ b/src/cmd/flux-exec.c @@ -31,6 +31,7 @@ #include "src/common/libidset/idset.h" #include "src/common/libeventlog/eventlog.h" #include "src/common/libutil/log.h" +#include "src/common/libutil/basename.h" #include "src/common/libsubprocess/fbuf.h" #include "src/common/libsubprocess/fbuf_watcher.h" #include "ccan/str/str.h" @@ -450,7 +451,7 @@ static bool check_for_imp_run (int argc, char *argv[], const char **ppath) /* If argv0 basename is flux-imp, then we'll likely have to use * flux-imp kill to signal the resulting subprocesses */ - if (streq (basename (argv[0]), "flux-imp")) { + if (streq (basename_simple (argv[0]), "flux-imp")) { *ppath = argv[0]; return true; } diff --git a/src/cmd/job/mpir.c b/src/cmd/job/mpir.c index e5d719fdc341..02f8ae88a534 100644 --- a/src/cmd/job/mpir.c +++ b/src/cmd/job/mpir.c @@ -25,6 +25,7 @@ #include #include "src/common/libutil/log.h" +#include "src/common/libutil/basename.h" #include "src/common/libjob/idf58.h" #include "src/common/libdebugged/debugged.h" #include "src/shell/mpir/proctable.h" @@ -143,7 +144,7 @@ static void completion_cb (flux_subprocess_t *p) int rank = flux_subprocess_rank (p); int exitcode = flux_subprocess_exit_code (p); int signum = flux_subprocess_signaled (p); - const char *prog = basename (MPIR_executable_path); + const char *prog = basename_simple (MPIR_executable_path); if (signum > 0) log_msg ("MPIR: rank %d: %s: %s", rank, prog, strsignal (signum)); @@ -187,7 +188,7 @@ static void output_cb (flux_subprocess_t *p, const char *stream) { const char *line; int len = 0; - const char *prog = basename (MPIR_executable_path); + const char *prog = basename_simple (MPIR_executable_path); int rank = flux_subprocess_rank (p); len = flux_subprocess_read_trimmed_line (p, stream, &line); @@ -200,7 +201,7 @@ static void output_cb (flux_subprocess_t *p, const char *stream) static void state_cb (flux_subprocess_t *p, flux_subprocess_state_t state) { if (state == FLUX_SUBPROCESS_FAILED) { - const char *prog = basename (MPIR_executable_path); + const char *prog = basename_simple (MPIR_executable_path); int rank = flux_subprocess_rank (p); const char *errmsg = flux_subprocess_fail_error (p); log_msg ("MPIR: rank %d: %s: %s", rank, prog, errmsg); diff --git a/src/common/libsdexec/unit.c b/src/common/libsdexec/unit.c index 58f741540b4b..9ee6b204b6c3 100644 --- a/src/common/libsdexec/unit.c +++ b/src/common/libsdexec/unit.c @@ -21,6 +21,7 @@ #include "src/common/libmissing/macros.h" #include "src/common/libutil/errprintf.h" #include "src/common/libutil/aux.h" +#include "src/common/libutil/basename.h" #include "ccan/str/str.h" #include "ccan/array_size/array_size.h" @@ -75,12 +76,8 @@ int sdexec_unit_aux_set (struct unit *unit, const char *sdexec_unit_name (struct unit *unit) { - if (unit) { - const char *cp; - if ((cp = strrchr (unit->path, '/'))) - return cp + 1; - return unit->path; - } + if (unit) + return basename_simple (unit->path); return "internal error: unit is null"; } diff --git a/src/common/libtomlc99/Makefile.am b/src/common/libtomlc99/Makefile.am index 8fe620c1f0e2..a589ad6cd0d3 100644 --- a/src/common/libtomlc99/Makefile.am +++ b/src/common/libtomlc99/Makefile.am @@ -38,7 +38,8 @@ test_cppflags = \ test_ldadd = \ $(top_builddir)/src/common/libtomlc99/libtomlc99.la \ - $(top_builddir)/src/common/libtap/libtap.la + $(top_builddir)/src/common/libtap/libtap.la \ + $(top_builddir)/src/common/libutil/libutil.la toml_cat_SOURCES = toml_cat.c toml_cat_LDADD = $(test_ldadd) diff --git a/src/common/libtomlc99/test/toml.c b/src/common/libtomlc99/test/toml.c index 0b6a9d6f7909..638138d4fc65 100644 --- a/src/common/libtomlc99/test/toml.c +++ b/src/common/libtomlc99/test/toml.c @@ -22,6 +22,7 @@ #include #include "src/common/libtap/tap.h" +#include "src/common/libutil/basename.h" #include "toml.h" #define EX1 "\ @@ -243,7 +244,7 @@ void parse_bad_input (void) for (i = 0; i < results.gl_pathc; i++) { char errbuf[255]; - char *name = basename (results.gl_pathv[i]); + char *name = basename_simple (results.gl_pathv[i]); const char *reason; bool blocklist = matchtab (name, bad_input_blocklist, &reason); @@ -299,7 +300,7 @@ void parse_good_input (void) for (i = 0; i < results.gl_pathc; i++) { char errbuf[255]; ok (parse_good_file (results.gl_pathv[i], errbuf, 255) == true, - "%s: %s", basename (results.gl_pathv[i]), errbuf); + "%s: %s", basename_simple (results.gl_pathv[i]), errbuf); } globfree (&results); } diff --git a/src/common/libutil/Makefile.am b/src/common/libutil/Makefile.am index c06b71112d7e..b9c993995258 100644 --- a/src/common/libutil/Makefile.am +++ b/src/common/libutil/Makefile.am @@ -105,6 +105,8 @@ libutil_la_SOURCES = \ sigutil.c \ parse_size.h \ parse_size.c \ + basename.h \ + basename.c \ ansi_color.h TESTS = test_sha1.t \ diff --git a/src/common/libutil/basename.c b/src/common/libutil/basename.c new file mode 100644 index 000000000000..bdd90654c206 --- /dev/null +++ b/src/common/libutil/basename.c @@ -0,0 +1,28 @@ +/************************************************************\ + * Copyright 2016 Lawrence Livermore National Security, LLC + * (c.f. AUTHORS, NOTICE.LLNS, COPYING) + * + * This file is part of the Flux resource manager framework. + * For details, see https://github.com/flux-framework. + * + * SPDX-License-Identifier: LGPL-3.0 +\************************************************************/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include + +#include "basename.h" + +/* This is what glibc basename(3) does more or less. + * https://github.com/lattera/glibc/blob/master/string/basename.c + */ + +char *basename_simple (const char *path) +{ + char *p = strrchr (path, '/'); + return p ? p + 1 : (char *)path; +} + +// vi:ts=4 sw=4 expandtab diff --git a/src/common/libutil/basename.h b/src/common/libutil/basename.h new file mode 100644 index 000000000000..315be034c85d --- /dev/null +++ b/src/common/libutil/basename.h @@ -0,0 +1,18 @@ +/************************************************************\ + * Copyright 2024 Lawrence Livermore National Security, LLC + * (c.f. AUTHORS, NOTICE.LLNS, COPYING) + * + * This file is part of the Flux resource manager framework. + * For details, see https://github.com/flux-framework. + * + * SPDX-License-Identifier: LGPL-3.0 +\************************************************************/ + +#ifndef _UTIL_BASENAME_H +#define _UTIL_BASENAME_H + +char *basename_simple (const char *path); + +#endif /* !_UTIL_BASENAME_H */ + +// vi:ts=4 sw=4 expandtab diff --git a/src/common/libutil/dirwalk.c b/src/common/libutil/dirwalk.c index 2b1b3dea158b..0a5b8a13c216 100644 --- a/src/common/libutil/dirwalk.c +++ b/src/common/libutil/dirwalk.c @@ -28,6 +28,7 @@ #include "src/common/libczmqcontainers/czmq_containers.h" #include "ccan/str/str.h" +#include "basename.h" #include "dirwalk.h" struct direntry { @@ -153,7 +154,7 @@ const char * dirwalk_name (dirwalk_t *d) if (!d->current) return NULL; if (!d->current->basename) - d->current->basename = basename (d->current->path); + d->current->basename = basename_simple (d->current->path); return d->current->basename; } diff --git a/src/common/libutil/log.c b/src/common/libutil/log.c index 103b56e0a729..d31415f96304 100644 --- a/src/common/libutil/log.c +++ b/src/common/libutil/log.c @@ -23,6 +23,7 @@ #include #include +#include "basename.h" #include "log.h" extern char *__progname; @@ -34,7 +35,7 @@ log_init (char *p) if (!p) prog = __progname; else - prog = basename (p); + prog = basename_simple (p); } void diff --git a/src/common/libutil/test/dirwalk.c b/src/common/libutil/test/dirwalk.c index afa25323066c..9e214e705a2a 100644 --- a/src/common/libutil/test/dirwalk.c +++ b/src/common/libutil/test/dirwalk.c @@ -29,7 +29,8 @@ #include "src/common/libtap/tap.h" #include "src/common/libczmqcontainers/czmq_containers.h" #include "ccan/str/str.h" -#include "src/common/libutil/dirwalk.h" +#include "basename.h" +#include "dirwalk.h" static int makepath (const char *fmt, ...) { @@ -268,7 +269,7 @@ int main(int argc, char** argv) l = dirwalk_find (tmp, 0, "foo", 1, NULL, 0); ok (l != NULL, "dirwalk_find"); ok (l && zlist_size (l) == 1, "dirwalk_find stopped at 1 result"); - ok (streq (basename (zlist_first (l)), "foo"), + ok (streq (basename_simple (zlist_first (l)), "foo"), "breadth-first search got expected match"); zlist_destroy (&l); diff --git a/src/modules/job-exec/exec.c b/src/modules/job-exec/exec.c index 149716027c72..d1a058754c8a 100644 --- a/src/modules/job-exec/exec.c +++ b/src/modules/job-exec/exec.c @@ -39,6 +39,7 @@ #include "src/common/libjob/idf58.h" #include "ccan/str/str.h" +#include "src/common/libutil/basename.h" #include "src/common/libutil/errprintf.h" #include "src/common/libutil/errno_safe.h" #include "src/common/libsubprocess/bulk-exec.h" @@ -266,7 +267,7 @@ static void output_cb (struct bulk_exec *exec, } jobinfo_log_output (job, flux_subprocess_rank (p), - basename (cmd), + basename_simple (cmd), stream, data, len); diff --git a/src/modules/job-ingest/worker.c b/src/modules/job-ingest/worker.c index 44c09403e82b..b394fa8287b9 100644 --- a/src/modules/job-ingest/worker.c +++ b/src/modules/job-ingest/worker.c @@ -46,6 +46,7 @@ #include #include "src/common/libczmqcontainers/czmq_containers.h" +#include "src/common/libutil/basename.h" #include "ccan/str/str.h" #include "worker.h" @@ -500,7 +501,7 @@ struct worker *worker_create (flux_t *h, double inactivity_timeout, goto error; if (!(w->trash = zlist_new())) goto error; - if (!(w->name = strdup (basename (name)))) + if (!(w->name = strdup (basename_simple (name)))) goto error; if (!(w->queue = zlist_new ())) goto error; diff --git a/src/modules/job-manager/jobtap.c b/src/modules/job-manager/jobtap.c index 7f9b45078b68..887b81e4b4cc 100644 --- a/src/modules/job-manager/jobtap.c +++ b/src/modules/job-manager/jobtap.c @@ -27,6 +27,7 @@ #include "src/common/libczmqcontainers/czmq_containers.h" #include "src/common/libutil/iterators.h" +#include "src/common/libutil/basename.h" #include "src/common/libutil/errno_safe.h" #include "src/common/libutil/errprintf.h" #include "src/common/libutil/aux.h" @@ -1377,7 +1378,7 @@ static int plugin_try_load (struct jobtap *jobtap, return errprintf (errp, "%s", flux_plugin_strerror (p)); - if (!(name = strdup (basename (fullpath))) + if (!(name = strdup (basename_simple (fullpath))) || flux_plugin_aux_set (p, "jobtap::basename", name, free) < 0) { ERRNO_SAFE_WRAP (free, name); return errprintf (errp, diff --git a/src/shell/batch.c b/src/shell/batch.c index 21e9b79bc1ad..7d496955b651 100644 --- a/src/shell/batch.c +++ b/src/shell/batch.c @@ -26,6 +26,7 @@ #include #include "src/common/libutil/read_all.h" +#include "src/common/libutil/basename.h" #include "ccan/str/str.h" #include "builtins.h" @@ -138,7 +139,7 @@ static bool is_batch_command (flux_cmd_t *cmd) const char *argv1 = flux_cmd_arg (cmd, 1); return (argv0 - && streq (basename (argv0), "flux") + && streq (basename_simple (argv0), "flux") && (streq (argv1, "broker") || streq (argv1, "start"))); } diff --git a/src/shell/doom.c b/src/shell/doom.c index 564e48943aa0..acec67abfbd1 100644 --- a/src/shell/doom.c +++ b/src/shell/doom.c @@ -39,6 +39,7 @@ #include "src/common/libeventlog/eventlog.h" #include "src/common/libutil/fsd.h" +#include "src/common/libutil/basename.h" #include "builtins.h" #include "internal.h" @@ -100,9 +101,7 @@ static const char *doom_exit_host (struct shell_doom *doom) static const char *get_jobspec_command_arg0 (struct shell_doom *doom) { json_t *s = json_array_get (doom->shell->info->jobspec->command, 0); - const char *path = json_string_value (s); - const char *p = strrchr (path, '/'); - return p ? p + 1 : path; + return basename_simple (json_string_value (s)); } static void doom_check (struct shell_doom *doom, diff --git a/src/shell/shell.c b/src/shell/shell.c index fcdf4ef8d864..887a732b2e0d 100644 --- a/src/shell/shell.c +++ b/src/shell/shell.c @@ -31,6 +31,7 @@ #include "src/common/libutil/log.h" #include "src/common/libutil/errno_safe.h" #include "src/common/libutil/fdutils.h" +#include "src/common/libutil/basename.h" #include "src/common/libtaskmap/taskmap_private.h" #include "ccan/str/str.h" @@ -1051,7 +1052,7 @@ static int mustache_render_name (flux_shell_t *shell, json_t *cmd = json_array_get (shell->info->jobspec->command, 0); if (!cmd || !(jobname = json_string_value (cmd)) - || !(jobname = basename (jobname))) + || !(jobname = basename_simple (jobname))) jobname = "unknown"; } if (fputs (jobname, fp) == EOF) {