diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index 53f4a1a60c8..a55e91ff203 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -35,11 +35,15 @@ All tools: no-ops. If that's what's explicitly desired, you might consider setting `$SYSTEMD_OFFLINE=1`. +* `$SYSTEMD_IN_INITRD` — takes a boolean. If set, overrides initrd detection. + This is useful for debugging and testing initrd-only programs in the main + system. + * `$SYSTEMD_FIRST_BOOT=0|1` — if set, assume "first boot" condition to be false or true, instead of checking the flag file created by PID 1. -* `$SD_EVENT_PROFILE_DELAYS=1` — if set, the sd-event event loop implementation - will print latency information at runtime. +* `$SYSTEMD_INVOKED_AS=name` — override argv[0] for detection of a multicall + binary. E.g. `SYSTEMD_INVOKED_AS=systemd-udevd build/udevadm`. * `$SYSTEMD_PROC_CMDLINE` — if set, the contents are used as the kernel command line instead of the actual one in `/proc/cmdline`. This is useful for @@ -76,9 +80,8 @@ All tools: (relevant in particular for the system manager and `systemd-hostnamed`). Must be a valid hostname (either a single label or a FQDN). -* `$SYSTEMD_IN_INITRD` — takes a boolean. If set, overrides initrd detection. - This is useful for debugging and testing initrd-only programs in the main - system. +* `$SD_EVENT_PROFILE_DELAYS=1` — if set, the sd-event event loop implementation + will print latency information at runtime. * `$SYSTEMD_BUS_TIMEOUT=SECS` — specifies the maximum time to wait for method call completion. If no time unit is specified, assumes seconds. The usual other units diff --git a/src/basic/argv-util.c b/src/basic/argv-util.c index 10f8cd86f4a..cefe6900bed 100644 --- a/src/basic/argv-util.c +++ b/src/basic/argv-util.c @@ -29,13 +29,15 @@ void save_argc_argv(int argc, char **argv) { } bool invoked_as(char *argv[], const char *token) { - if (!argv || isempty(argv[0])) + const char *progname = secure_getenv("SYSTEMD_INVOKED_AS"); + + if (!progname && argv) + progname = argv[0]; + + if (isempty(progname) || isempty(token)) return false; - if (isempty(token)) - return false; - - return strstr(last_path_component(argv[0]), token); + return strstr(last_path_component(progname), token); } bool invoked_by_systemd(void) { diff --git a/src/shared/help-util.c b/src/shared/help-util.c index 7b67bb58f1a..8968ba13771 100644 --- a/src/shared/help-util.c +++ b/src/shared/help-util.c @@ -1,8 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include + #include "alloc-util.h" #include "ansi-color.h" #include "help-util.h" +#include "path-util.h" #include "pretty-print.h" /* These are helpers for putting together --help texts in a uniform way with a common output style. Each @@ -25,12 +28,16 @@ * options.[ch] APIs. */ void help_cmdline(const char *arguments) { + const char *progname = + last_path_component(secure_getenv("SYSTEMD_INVOKED_AS")) + ?: program_invocation_short_name; + assert(arguments); printf("%s>%s %s %s\n", ansi_grey(), ansi_normal(), - program_invocation_short_name, + progname, arguments); } diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c index 4c803fbbd9c..63458117cb9 100644 --- a/src/test/test-process-util.c +++ b/src/test/test-process-util.c @@ -1125,6 +1125,21 @@ TEST(getenv_for_pid) { } } +TEST(invoked_as) { + ASSERT_FALSE(invoked_as(NULL, "foobar")); + ASSERT_FALSE(invoked_as(NULL, "barbar")); + + ASSERT_EQ(setenv("SYSTEMD_INVOKED_AS", "/usr/bin/foobar", 1), 0); + + ASSERT_TRUE(invoked_as(NULL, "foobar")); + ASSERT_FALSE(invoked_as(NULL, "barbar")); + ASSERT_TRUE(invoked_as(NULL, "foo")); + ASSERT_TRUE(invoked_as(STRV_MAKE("barbar", "barbar", "y"), "foobar")); + ASSERT_FALSE(invoked_as(STRV_MAKE("barbar", "barbar", "y"), "barbar")); + + ASSERT_EQ(unsetenv("SYSTEMD_INVOKED_AS"), 0); +} + static int intro(void) { log_show_color(true); return EXIT_SUCCESS;