1
0
mirror of https://github.com/systemd/systemd synced 2025-10-01 01:34:47 +02:00

Compare commits

..

13 Commits

Author SHA1 Message Date
Pierre Dubouilh
1edebb0b89 rlimit-util: log when falling back setting limit 2021-02-15 15:30:35 +01:00
Lennart Poettering
458ab40f35
Merge pull request #18580 from keszybz/signal-list
Add systemctl --signal=list
2021-02-15 14:37:03 +01:00
Luca Boccassi
7eba0c50f5 test: install binaries from local d/control file
The source package in the apt cache might be older than the
packaging from salsa.debian.org/systemd-team/systemd so it might not
list all the current binary packages.
This is currently the case for systemd-timesyncd, so TEST-30 fails.

Simply grep the control file rather than using apt-cache when iterating
over the packages contents.
2021-02-15 10:17:39 +01:00
Florian Hülsmann
92ef9e568b hwdb: add resolution for Waltop/MEDION batteryless graphics tablet (v:172f p:0505) 2021-02-15 10:16:57 +01:00
Yu Watanabe
0f1f933b6e tree-wide: fix typo 2021-02-15 10:15:04 +01:00
Zbigniew Jędrzejewski-Szmek
1751efdf6f test-parse-argument: add a test for the three parse_*_argument() functions
This mostly tests the return values and that the xsprintf
buffers are big enough.
2021-02-15 08:50:45 +01:00
Zbigniew Jędrzejewski-Szmek
b1e8f46c31 Move and rename parse_json_argument() function
json.[ch] is a very generic implementation, and cmdline argument parsing
doesn't fit there.
2021-02-15 08:50:45 +01:00
Zbigniew Jędrzejewski-Szmek
614b022c76 Move and rename parse_path_argument() function
This fits better in shared/, and the new parse-argument.c file is a good home
for it.
2021-02-15 08:50:45 +01:00
Zbigniew Jędrzejewski-Szmek
923e2122d0 basic/signal-util: drop unneeded extra byte from buffer
DECIMAL_STR_MAX() already returns +1 for NULL, so no need to do it
a second time.
2021-02-15 08:50:45 +01:00
Zbigniew Jędrzejewski-Szmek
97ab9dfc0d systemctl,loginctl,machinectl: add --signal=list
This lists numerical signal values:
$ systemctl --signal list
SIGNAL NAME
1      SIGHUP
2      SIGINT
3      SIGQUIT
...
62     SIGRTMIN+28
63     SIGRTMIN+29
64     SIGRTMIN+30

This is useful when trying to kill e.g. systemd with a specific signal number
using kill. kill doesn't accept our fancy signal names like RTMIN+4, so one
would have to calculate that value somehow. Doing
  systemctl --signal list | grep -F RTMIN+4
is a nice way of doing that.
2021-02-15 08:50:40 +01:00
Zbigniew Jędrzejewski-Szmek
86beb21302 systemctl,loginctl,machinectl: use a shared helper for arg_signal
I seems frivolous to yet another two -util.[ch] files, but the helper
should be in shared/ and it doesn't seem to fit anywhere else.
2021-02-14 15:59:09 +01:00
Zbigniew Jędrzejewski-Szmek
76e5e267fc systemctl: inline iterator declarations 2021-02-14 11:55:56 +01:00
Zbigniew Jędrzejewski-Szmek
e602abba15 basic/string-table: inline the iterator declaration 2021-02-14 11:24:45 +01:00
39 changed files with 286 additions and 177 deletions

View File

@ -687,3 +687,8 @@ evdev:input:b0003v172Fp0031*
evdev:input:b0003v172Fp0047* evdev:input:b0003v172Fp0047*
EVDEV_ABS_00=0:20000:80 EVDEV_ABS_00=0:20000:80
EVDEV_ABS_01=0:12500:80 EVDEV_ABS_01=0:12500:80
# WALTOP International Corp. Batteryless Tablet
evdev:input:b0003v172Fp0505*
EVDEV_ABS_00=::160
EVDEV_ABS_01=::160

View File

@ -334,13 +334,14 @@
<term><option>-s</option></term> <term><option>-s</option></term>
<term><option>--signal=</option></term> <term><option>--signal=</option></term>
<listitem><para>When used with <command>kill-session</command> <listitem><para>When used with <command>kill-session</command> or <command>kill-user</command>,
or <command>kill-user</command>, choose which signal to send choose which signal to send to selected processes. Must be one of the well known signal specifiers,
to selected processes. Must be one of the well known signal such as <constant>SIGTERM</constant>, <constant>SIGINT</constant> or <constant>SIGSTOP</constant>.
specifiers, such as <constant>SIGTERM</constant>, If omitted, defaults to <constant>SIGTERM</constant>.</para>
<constant>SIGINT</constant> or <constant>SIGSTOP</constant>.
If omitted, defaults to <para>The special value <literal>help</literal> will list the known values and the program will exit
<constant>SIGTERM</constant>.</para></listitem> immediately, and the special value <literal>list</literal> will list known values along with the
numerical signal numbers and the program will exit immediately.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -699,17 +699,7 @@
<option>all</option>.</para></listitem> <option>all</option>.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <xi:include href="standard-options.xml" xpointer="signal" />
<term><option>-s</option></term>
<term><option>--signal=</option></term>
<listitem><para>When used with <command>kill</command>, choose
which signal to send to selected processes. Must be one of the
well-known signal specifiers, such as
<constant>SIGTERM</constant>, <constant>SIGINT</constant> or
<constant>SIGSTOP</constant>. If omitted, defaults to
<constant>SIGTERM</constant>.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--uid=</option></term> <term><option>--uid=</option></term>

View File

@ -61,4 +61,20 @@
(for a pretty version of the same, with indentation and line breaks) or <literal>off</literal> (to turn (for a pretty version of the same, with indentation and line breaks) or <literal>off</literal> (to turn
off JSON output, the default).</para></listitem> off JSON output, the default).</para></listitem>
</varlistentry> </varlistentry>
<varlistentry id='signal'>
<term><option>-s</option></term>
<term><option>--signal=</option></term>
<listitem>
<para>When used with <command>kill</command>, choose which signal to send to selected processes. Must
be one of the well-known signal specifiers such as <constant>SIGTERM</constant>,
<constant>SIGINT</constant> or <constant>SIGSTOP</constant>. If omitted, defaults to
<option>SIGTERM</option>.</para>
<para>The special value <literal>help</literal> will list the known values and the program will exit
immediately, and the special value <literal>list</literal> will list known values along with the
numerical signal numbers and the program will exit immediately.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>

View File

@ -2067,21 +2067,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
is defined. If omitted, defaults to is defined. If omitted, defaults to
<option>all</option>.</para> <option>all</option>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <xi:include href="standard-options.xml" xpointer="signal" />
<term><option>-s</option></term>
<term><option>--signal=</option></term>
<listitem>
<para>When used with <command>kill</command>, choose which
signal to send to selected processes. Must be one of the
well-known signal specifiers such as <constant>SIGTERM</constant>, <constant>SIGINT</constant> or
<constant>SIGSTOP</constant>. If omitted, defaults to
<option>SIGTERM</option>.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--what=</option></term> <term><option>--what=</option></term>

View File

@ -752,38 +752,6 @@ int fsck_exists(const char *fstype) {
return executable_is_good(checker); return executable_is_good(checker);
} }
int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg) {
char *p;
int r;
/*
* This function is intended to be used in command line
* parsers, to handle paths that are passed in. It makes the
* path absolute, and reduces it to NULL if omitted or
* root (the latter optionally).
*
* NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON
* SUCCESS! Hence, do not pass in uninitialized pointers.
*/
if (isempty(path)) {
*arg = mfree(*arg);
return 0;
}
r = path_make_absolute_cwd(path, &p);
if (r < 0)
return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path);
path_simplify(p, false);
if (suppress_root && empty_or_root(p))
p = mfree(p);
free_and_replace(*arg, p);
return 0;
}
char* dirname_malloc(const char *path) { char* dirname_malloc(const char *path) {
char *d, *dir, *dir2; char *d, *dir, *dir2;

View File

@ -144,8 +144,6 @@ int fsck_exists(const char *fstype);
_ret; \ _ret; \
}) })
int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg);
char* dirname_malloc(const char *path); char* dirname_malloc(const char *path);
const char *last_path_component(const char *path); const char *last_path_component(const char *path);
int path_extract_filename(const char *p, char **ret); int path_extract_filename(const char *p, char **ret);

View File

@ -43,6 +43,8 @@ int setrlimit_closest(int resource, const struct rlimit *rlim) {
fixed.rlim_max == highest.rlim_max) fixed.rlim_max == highest.rlim_max)
return 0; return 0;
log_debug("Failed at setting rlimit " RLIM_FMT " for resource RLIMIT_%s. Will attempt setting value " RLIM_FMT " instead.", rlim->rlim_max, rlimit_to_string(resource), fixed.rlim_max);
if (setrlimit(resource, &fixed) < 0) if (setrlimit(resource, &fixed) < 0)
return -errno; return -errno;

View File

@ -198,7 +198,7 @@ static const char *const __signal_table[] = {
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int); DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
const char *signal_to_string(int signo) { const char *signal_to_string(int signo) {
static thread_local char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1]; static thread_local char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int)];
const char *name; const char *name;
name = __signal_to_string(signo); name = __signal_to_string(signo);

View File

@ -103,9 +103,8 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
#define DUMP_STRING_TABLE(name,type,max) \ #define DUMP_STRING_TABLE(name,type,max) \
do { \ do { \
type _k; \
flockfile(stdout); \ flockfile(stdout); \
for (_k = 0; _k < (max); _k++) { \ for (type _k = 0; _k < (max); _k++) { \
const char *_t; \ const char *_t; \
_t = name##_to_string(_k); \ _t = name##_to_string(_k); \
if (!_t) \ if (!_t) \

View File

@ -21,6 +21,7 @@
#include "log.h" #include "log.h"
#include "main-func.h" #include "main-func.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -2523,7 +2524,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_JSON: case ARG_JSON:
r = json_parse_cmdline_parameter_and_warn(optarg, &arg_json_format_flags); r = parse_json_argument(optarg, &arg_json_format_flags);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -58,6 +58,7 @@
#include "mount-setup.h" #include "mount-setup.h"
#include "os-util.h" #include "os-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -358,7 +359,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
return 0; return 0;
if (path_is_absolute(value)) if (path_is_absolute(value))
(void) parse_path_argument_and_warn(value, false, &arg_early_core_pattern); (void) parse_path_argument(value, false, &arg_early_core_pattern);
else else
log_warning("Specified core pattern '%s' is not an absolute path, ignoring.", value); log_warning("Specified core pattern '%s' is not an absolute path, ignoring.", value);
@ -498,7 +499,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
if (proc_cmdline_value_missing(key, value)) if (proc_cmdline_value_missing(key, value))
return 0; return 0;
(void) parse_path_argument_and_warn(value, false, &arg_watchdog_device); (void) parse_path_argument(value, false, &arg_watchdog_device);
} else if (proc_cmdline_key_streq(key, "systemd.clock_usec")) { } else if (proc_cmdline_key_streq(key, "systemd.clock_usec")) {

View File

@ -25,6 +25,7 @@
#include "macro.h" #include "macro.h"
#include "main-func.h" #include "main-func.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -320,7 +321,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_JSON: case ARG_JSON:
r = json_parse_cmdline_parameter_and_warn(optarg, &arg_json_format_flags); r = parse_json_argument(optarg, &arg_json_format_flags);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -16,6 +16,7 @@
#include "libfido2-util.h" #include "libfido2-util.h"
#include "main-func.h" #include "main-func.h"
#include "memory-util.h" #include "memory-util.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pkcs11-util.h" #include "pkcs11-util.h"
@ -323,7 +324,7 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Too many arguments, refusing."); "Too many arguments, refusing.");
r = parse_path_argument_and_warn(argv[optind], false, &arg_node); r = parse_path_argument(argv[optind], false, &arg_node);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -22,6 +22,7 @@
#include "mkdir.h" #include "mkdir.h"
#include "mount-util.h" #include "mount-util.h"
#include "namespace-util.h" #include "namespace-util.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -245,7 +246,7 @@ static int parse_argv(int argc, char *argv[]) {
} }
case ARG_VERITY_DATA: case ARG_VERITY_DATA:
r = parse_path_argument_and_warn(optarg, false, &arg_verity_settings.data_path); r = parse_path_argument(optarg, false, &arg_verity_settings.data_path);
if (r < 0) if (r < 0)
return r; return r;
break; break;
@ -259,7 +260,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_JSON: case ARG_JSON:
r = json_parse_cmdline_parameter_and_warn(optarg, &arg_json_format_flags); r = parse_json_argument(optarg, &arg_json_format_flags);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -24,6 +24,7 @@
#include "mkdir.h" #include "mkdir.h"
#include "mount-util.h" #include "mount-util.h"
#include "os-util.h" #include "os-util.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -1046,13 +1047,13 @@ static int parse_argv(int argc, char *argv[]) {
return version(); return version();
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, true, &arg_root); r = parse_path_argument(optarg, true, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;
case ARG_IMAGE: case ARG_IMAGE:
r = parse_path_argument_and_warn(optarg, false, &arg_image); r = parse_path_argument(optarg, false, &arg_image);
if (r < 0) if (r < 0)
return r; return r;
break; break;

View File

@ -208,7 +208,7 @@ static int process_progress(int fd, FILE* console) {
p = percent(pass, cur, max); p = percent(pass, cur, max);
r = fprintf(console, "\r%s: fsck %3.1f%% complete...\r", device, p); r = fprintf(console, "\r%s: fsck %3.1f%% complete...\r", device, p);
if (r < 0) if (r < 0)
return -EIO; /* No point in continuing if something happend to our output stream */ return -EIO; /* No point in continuing if something happened to our output stream */
fflush(console); fflush(console);
clear = MAX(clear, r); clear = MAX(clear, r);

View File

@ -23,6 +23,7 @@
#include "main-func.h" #include "main-func.h"
#include "memory-util.h" #include "memory-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pkcs11-util.h" #include "pkcs11-util.h"
@ -2260,7 +2261,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
} }
r = parse_path_argument_and_warn(optarg, false, &hd); r = parse_path_argument(optarg, false, &hd);
if (r < 0) if (r < 0)
return r; return r;
@ -2481,7 +2482,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
} }
r = parse_path_argument_and_warn(optarg, false, &v); r = parse_path_argument(optarg, false, &v);
if (r < 0) if (r < 0)
return r; return r;
@ -3233,7 +3234,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_JSON: case ARG_JSON:
r = json_parse_cmdline_parameter_and_warn(optarg, &arg_json_format_flags); r = parse_json_argument(optarg, &arg_json_format_flags);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -55,6 +55,7 @@
#include "mountpoint-util.h" #include "mountpoint-util.h"
#include "nulstr-util.h" #include "nulstr-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pcre2-dlopen.h" #include "pcre2-dlopen.h"
@ -719,13 +720,13 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ true, &arg_root); r = parse_path_argument(optarg, /* suppress_root= */ true, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;
case ARG_IMAGE: case ARG_IMAGE:
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_image); r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_image);
if (r < 0) if (r < 0)
return r; return r;
break; break;

View File

@ -22,6 +22,7 @@
#include "main-func.h" #include "main-func.h"
#include "memory-util.h" #include "memory-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "process-util.h" #include "process-util.h"
@ -1395,14 +1396,9 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case 's': case 's':
if (streq(optarg, "help")) { r = parse_signal_argument(optarg, &arg_signal);
DUMP_STRING_TABLE(signal, int, _NSIG); if (r <= 0)
return 0; return r;
}
arg_signal = signal_from_string(optarg);
if (arg_signal < 0)
return log_error_errno(arg_signal, "Failed to parse signal string %s.", optarg);
break; break;
case 'H': case 'H':

View File

@ -10,6 +10,7 @@
#include "log.h" #include "log.h"
#include "machine-id-setup.h" #include "machine-id-setup.h"
#include "main-func.h" #include "main-func.h"
#include "parse-argument.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "util.h" #include "util.h"
@ -76,7 +77,7 @@ static int parse_argv(int argc, char *argv[]) {
return version(); return version();
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, true, &arg_root); r = parse_path_argument(optarg, true, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;

View File

@ -39,6 +39,7 @@
#include "mkdir.h" #include "mkdir.h"
#include "nulstr-util.h" #include "nulstr-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -2715,15 +2716,9 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case 's': case 's':
if (streq(optarg, "help")) { r = parse_signal_argument(optarg, &arg_signal);
DUMP_STRING_TABLE(signal, int, _NSIG); if (r <= 0)
return 0; return r;
}
r = signal_from_string(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse signal string %s.", optarg);
arg_signal = r;
break; break;
case ARG_NO_ASK_PASSWORD: case ARG_NO_ASK_PASSWORD:

View File

@ -839,15 +839,15 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li
routes = foreign ? manager->routes_foreign : manager->routes; routes = foreign ? manager->routes_foreign : manager->routes;
SET_FOREACH(route, routes) { SET_FOREACH(route, routes) {
/* Do not touch routes managed by the kernel */ /* Do not touch routes managed by the kernel. */
if (route->protocol == RTPROT_KERNEL) if (route->protocol == RTPROT_KERNEL)
continue; continue;
/* The route will be configured later, or already configured by a link */ /* The route will be configured later, or already configured by a link. */
if (links_have_route(manager, route, except)) if (links_have_route(manager, route, except))
continue; continue;
/* The existing links do not have the route. Let's drop this now. It may by /* The existing links do not have the route. Let's drop this now. It may be
* re-configured later. */ * re-configured later. */
k = route_remove(route, manager, NULL, NULL); k = route_remove(route, manager, NULL, NULL);
if (k < 0 && r >= 0) if (k < 0 && r >= 0)

View File

@ -78,6 +78,7 @@
#include "nulstr-util.h" #include "nulstr-util.h"
#include "os-util.h" #include "os-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -791,7 +792,7 @@ static int parse_argv(int argc, char *argv[]) {
return version(); return version();
case 'D': case 'D':
r = parse_path_argument_and_warn(optarg, false, &arg_directory); r = parse_path_argument(optarg, false, &arg_directory);
if (r < 0) if (r < 0)
return r; return r;
@ -799,7 +800,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_TEMPLATE: case ARG_TEMPLATE:
r = parse_path_argument_and_warn(optarg, false, &arg_template); r = parse_path_argument(optarg, false, &arg_template);
if (r < 0) if (r < 0)
return r; return r;
@ -807,7 +808,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case 'i': case 'i':
r = parse_path_argument_and_warn(optarg, false, &arg_image); r = parse_path_argument(optarg, false, &arg_image);
if (r < 0) if (r < 0)
return r; return r;
@ -815,7 +816,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_OCI_BUNDLE: case ARG_OCI_BUNDLE:
r = parse_path_argument_and_warn(optarg, false, &arg_oci_bundle); r = parse_path_argument(optarg, false, &arg_oci_bundle);
if (r < 0) if (r < 0)
return r; return r;
@ -934,7 +935,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_NETWORK_NAMESPACE_PATH: case ARG_NETWORK_NAMESPACE_PATH:
r = parse_path_argument_and_warn(optarg, false, &arg_network_namespace_path); r = parse_path_argument(optarg, false, &arg_network_namespace_path);
if (r < 0) if (r < 0)
return r; return r;
@ -1386,7 +1387,7 @@ static int parse_argv(int argc, char *argv[]) {
} }
case ARG_VERITY_DATA: case ARG_VERITY_DATA:
r = parse_path_argument_and_warn(optarg, false, &arg_verity_settings.data_path); r = parse_path_argument(optarg, false, &arg_verity_settings.data_path);
if (r < 0) if (r < 0)
return r; return r;
break; break;

View File

@ -45,6 +45,7 @@
#include "mkfs-util.h" #include "mkfs-util.h"
#include "mount-util.h" #include "mount-util.h"
#include "parse-util.h" #include "parse-util.h"
#include "parse-argument.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "proc-cmdline.h" #include "proc-cmdline.h"
@ -3623,7 +3624,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, false, &arg_root); r = parse_path_argument(optarg, false, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;
@ -3653,7 +3654,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_DEFINITIONS: case ARG_DEFINITIONS:
r = parse_path_argument_and_warn(optarg, false, &arg_definitions); r = parse_path_argument(optarg, false, &arg_definitions);
if (r < 0) if (r < 0)
return r; return r;
break; break;
@ -3687,7 +3688,7 @@ static int parse_argv(int argc, char *argv[]) {
} }
case ARG_JSON: case ARG_JSON:
r = json_parse_cmdline_parameter_and_warn(optarg, &arg_json_format_flags); r = parse_json_argument(optarg, &arg_json_format_flags);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -2459,7 +2459,7 @@ static int patch_rr(DnsPacket *p, usec_t age) {
INIT_REWINDER(rewinder, p); INIT_REWINDER(rewinder, p);
/* Patches the RR at the current rindex, substracts the specified time from the TTL */ /* Patches the RR at the current rindex, subtracts the specified time from the TTL */
r = dns_packet_read_name(p, NULL, true, NULL); r = dns_packet_read_name(p, NULL, true, NULL);
if (r < 0) if (r < 0)

View File

@ -21,6 +21,7 @@
#include "fd-util.h" #include "fd-util.h"
#include "format-util.h" #include "format-util.h"
#include "main-func.h" #include "main-func.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -470,7 +471,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_WORKING_DIRECTORY: case ARG_WORKING_DIRECTORY:
r = parse_path_argument_and_warn(optarg, true, &arg_working_directory); r = parse_path_argument(optarg, true, &arg_working_directory);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -4459,27 +4459,6 @@ int json_variant_unhex(JsonVariant *v, void **ret, size_t *ret_size) {
return unhexmem(json_variant_string(v), (size_t) -1, ret, ret_size); return unhexmem(json_variant_string(v), (size_t) -1, ret, ret_size);
} }
int json_parse_cmdline_parameter_and_warn(const char *s, JsonFormatFlags *ret) {
assert(s);
assert(ret);
if (streq(s, "pretty"))
*ret = JSON_FORMAT_PRETTY|JSON_FORMAT_COLOR_AUTO;
else if (streq(s, "short"))
*ret = JSON_FORMAT_NEWLINE;
else if (streq(s, "off"))
*ret = JSON_FORMAT_OFF;
else if (streq(s, "help")) {
puts("pretty\n"
"short\n"
"off");
return 0; /* 0 means → we showed a brief help, exit now */
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown argument to --json= switch: %s", s);
return 1; /* 1 means → properly parsed */
}
static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = { static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = {
[JSON_VARIANT_STRING] = "string", [JSON_VARIANT_STRING] = "string",
[JSON_VARIANT_INTEGER] = "integer", [JSON_VARIANT_INTEGER] = "integer",

View File

@ -357,7 +357,5 @@ int json_log_internal(JsonVariant *variant, int level, int error, const char *fi
int json_variant_unbase64(JsonVariant *v, void **ret, size_t *ret_size); int json_variant_unbase64(JsonVariant *v, void **ret, size_t *ret_size);
int json_variant_unhex(JsonVariant *v, void **ret, size_t *ret_size); int json_variant_unhex(JsonVariant *v, void **ret, size_t *ret_size);
int json_parse_cmdline_parameter_and_warn(const char *s, JsonFormatFlags *ret);
const char *json_variant_type_to_string(JsonVariantType t); const char *json_variant_type_to_string(JsonVariantType t);
JsonVariantType json_variant_type_from_string(const char *s); JsonVariantType json_variant_type_from_string(const char *s);

View File

@ -202,6 +202,8 @@ shared_sources = files('''
output-mode.h output-mode.h
pager.c pager.c
pager.h pager.h
parse-argument.c
parse-argument.h
pe-header.h pe-header.h
pkcs11-util.c pkcs11-util.c
pkcs11-util.h pkcs11-util.h

102
src/shared/parse-argument.c Normal file
View File

@ -0,0 +1,102 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "format-table.h"
#include "parse-argument.h"
#include "path-util.h"
#include "signal-util.h"
#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
/* All functions in this file emit warnigs. */
int parse_json_argument(const char *s, JsonFormatFlags *ret) {
assert(s);
assert(ret);
if (streq(s, "pretty"))
*ret = JSON_FORMAT_PRETTY|JSON_FORMAT_COLOR_AUTO;
else if (streq(s, "short"))
*ret = JSON_FORMAT_NEWLINE;
else if (streq(s, "off"))
*ret = JSON_FORMAT_OFF;
else if (streq(s, "help")) {
puts("pretty\n"
"short\n"
"off");
return 0; /* 0 means → we showed a brief help, exit now */
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown argument to --json= switch: %s", s);
return 1; /* 1 means → properly parsed */
}
int parse_path_argument(const char *path, bool suppress_root, char **arg) {
char *p;
int r;
/*
* This function is intended to be used in command line parsers, to handle paths that are passed
* in. It makes the path absolute, and reduces it to NULL if omitted or root (the latter optionally).
*
* NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON SUCCESS!
* Hence, do not pass in uninitialized pointers.
*/
if (isempty(path)) {
*arg = mfree(*arg);
return 0;
}
r = path_make_absolute_cwd(path, &p);
if (r < 0)
return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path);
path_simplify(p, false);
if (suppress_root && empty_or_root(p))
p = mfree(p);
return free_and_replace(*arg, p);
}
int parse_signal_argument(const char *s, int *ret) {
int r;
assert(s);
assert(ret);
if (streq(s, "help")) {
DUMP_STRING_TABLE(signal, int, _NSIG);
return 0;
}
if (streq(s, "list")) {
_cleanup_(table_unrefp) Table *table = NULL;
table = table_new("signal", "name");
if (!table)
return log_oom();
for (int i = 1; i < _NSIG; i++) {
r = table_add_many(
table,
TABLE_INT, i,
TABLE_SIGNAL, i);
if (r < 0)
return table_log_add_error(r);
}
r = table_print(table, NULL);
if (r < 0)
return table_log_print_error(r);
return 0;
}
r = signal_from_string(s);
if (r < 0)
return log_error_errno(r, "Failed to parse signal string \"%s\".", s);
*ret = r;
return 1; /* work to do */
}

View File

@ -0,0 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "json.h"
int parse_json_argument(const char *s, JsonFormatFlags *ret);
int parse_path_argument(const char *path, bool suppress_root, char **arg);
int parse_signal_argument(const char *s, int *ret);

View File

@ -22,6 +22,7 @@
#include "mountpoint-util.h" #include "mountpoint-util.h"
#include "os-util.h" #include "os-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "process-util.h" #include "process-util.h"
@ -943,13 +944,13 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, false, &arg_root); r = parse_path_argument(optarg, false, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;
case ARG_JSON: case ARG_JSON:
r = json_parse_cmdline_parameter_and_warn(optarg, &arg_json_format_flags); r = parse_json_argument(optarg, &arg_json_format_flags);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -11,6 +11,7 @@
#include "main-func.h" #include "main-func.h"
#include "output-mode.h" #include "output-mode.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "rlimit-util.h" #include "rlimit-util.h"
@ -492,14 +493,12 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
case ARG_VERSION: case ARG_VERSION:
return version(); return version();
case 't': { case 't':
const char *p;
if (isempty(optarg)) if (isempty(optarg))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--type= requires arguments."); "--type= requires arguments.");
for (p = optarg;;) { for (const char *p = optarg;;) {
_cleanup_free_ char *type = NULL; _cleanup_free_ char *type = NULL;
r = extract_first_word(&p, &type, ",", 0); r = extract_first_word(&p, &type, ",", 0);
@ -533,7 +532,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
} }
break; break;
}
case 'P': case 'P':
arg_value = true; arg_value = true;
@ -546,10 +544,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
arg_properties = new0(char*, 1); arg_properties = new0(char*, 1);
if (!arg_properties) if (!arg_properties)
return log_oom(); return log_oom();
} else { } else
const char *p; for (const char *p = optarg;;) {
for (p = optarg;;) {
_cleanup_free_ char *prop = NULL; _cleanup_free_ char *prop = NULL;
r = extract_first_word(&p, &prop, ",", 0); r = extract_first_word(&p, &prop, ",", 0);
@ -561,7 +557,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
if (strv_consume(&arg_properties, TAKE_PTR(prop)) < 0) if (strv_consume(&arg_properties, TAKE_PTR(prop)) < 0)
return log_oom(); return log_oom();
} }
}
/* If the user asked for a particular property, show it, even if it is empty. */ /* If the user asked for a particular property, show it, even if it is empty. */
arg_all = true; arg_all = true;
@ -643,7 +638,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break; break;
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, false, &arg_root); r = parse_path_argument(optarg, false, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;
@ -679,16 +674,9 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break; break;
case 's': case 's':
if (streq(optarg, "help")) { r = parse_signal_argument(optarg, &arg_signal);
DUMP_STRING_TABLE(signal, int, _NSIG); if (r <= 0)
return 0; return r;
}
arg_signal = signal_from_string(optarg);
if (arg_signal < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to parse signal string %s.",
optarg);
break; break;
case ARG_NO_ASK_PASSWORD: case ARG_NO_ASK_PASSWORD:
@ -778,14 +766,12 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
arg_boot_loader_entry = empty_to_null(optarg); arg_boot_loader_entry = empty_to_null(optarg);
break; break;
case ARG_STATE: { case ARG_STATE:
const char *p;
if (isempty(optarg)) if (isempty(optarg))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--state= requires arguments."); "--state= requires arguments.");
for (p = optarg;;) { for (const char *p = optarg;;) {
_cleanup_free_ char *s = NULL; _cleanup_free_ char *s = NULL;
r = extract_first_word(&p, &s, ",", 0); r = extract_first_word(&p, &s, ",", 0);
@ -803,7 +789,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
return log_oom(); return log_oom();
} }
break; break;
}
case 'r': case 'r':
if (geteuid() != 0) if (geteuid() != 0)
@ -843,13 +828,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
arg_with_dependencies = true; arg_with_dependencies = true;
break; break;
case ARG_WHAT: { case ARG_WHAT:
const char *p;
if (isempty(optarg)) if (isempty(optarg))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--what= requires arguments."); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--what= requires arguments.");
for (p = optarg;;) { for (const char *p = optarg;;) {
_cleanup_free_ char *k = NULL; _cleanup_free_ char *k = NULL;
r = extract_first_word(&p, &k, ",", 0); r = extract_first_word(&p, &k, ",", 0);
@ -873,7 +856,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
} }
break; break;
}
case ARG_REBOOT_ARG: case ARG_REBOOT_ARG:
arg_reboot_argument = optarg; arg_reboot_argument = optarg;

View File

@ -17,6 +17,7 @@
#include "mount-util.h" #include "mount-util.h"
#include "nscd-flush.h" #include "nscd-flush.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "selinux-util.h" #include "selinux-util.h"
@ -1813,7 +1814,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_root); r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;
@ -1823,7 +1824,7 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"This systemd-sysusers version is compiled without support for --image=."); "This systemd-sysusers version is compiled without support for --image=.");
#else #else
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_image); r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_image);
if (r < 0) if (r < 0)
return r; return r;
break; break;

View File

@ -222,6 +222,8 @@ tests += [
[['src/test/test-extract-word.c']], [['src/test/test-extract-word.c']],
[['src/test/test-parse-argument.c']],
[['src/test/test-parse-util.c'], [['src/test/test-parse-util.c'],
[], [],
[libseccomp]], [libseccomp]],

View File

@ -0,0 +1,63 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "parse-argument.h"
#include "stdio-util.h"
#include "tests.h"
static void test_parse_json_argument(void) {
log_info("/* %s */", __func__);
JsonFormatFlags flags = JSON_FORMAT_PRETTY;
assert_se(parse_json_argument("help", &flags) == 0);
assert_se(flags == JSON_FORMAT_PRETTY);
assert_se(parse_json_argument("off", &flags) == 1);
assert_se(flags == JSON_FORMAT_OFF);
}
static void test_parse_path_argument(void) {
log_info("/* %s */", __func__);
_cleanup_free_ char *path = NULL;
assert_se(parse_path_argument("help", false, &path) == 0);
assert_se(streq(basename(path), "help"));
assert_se(parse_path_argument("/", false, &path) == 0);
assert_se(streq(path, "/"));
assert_se(parse_path_argument("/", true, &path) == 0);
assert_se(path == NULL);
}
static void test_parse_signal_argument(void) {
log_info("/* %s */", __func__);
int signal = -1;
assert_se(parse_signal_argument("help", &signal) == 0);
assert_se(signal == -1);
assert_se(parse_signal_argument("list", &signal) == 0);
assert_se(signal == -1);
assert_se(parse_signal_argument("SIGABRT", &signal) == 1);
assert_se(signal == SIGABRT);
assert_se(parse_signal_argument("ABRT", &signal) == 1);
assert_se(signal == SIGABRT);
char buf[DECIMAL_STR_MAX(int)];
xsprintf(buf, "%d", SIGABRT);
assert_se(parse_signal_argument(buf, &signal) == 1);
assert_se(signal == SIGABRT);
}
int main(int argc, char *argv[]) {
test_setup_logging(LOG_INFO);
test_parse_json_argument();
test_parse_path_argument();
test_parse_signal_argument();
}

View File

@ -46,6 +46,7 @@
#include "mountpoint-util.h" #include "mountpoint-util.h"
#include "offline-passwd.h" #include "offline-passwd.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-lookup.h" #include "path-lookup.h"
#include "path-util.h" #include "path-util.h"
@ -3114,7 +3115,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_root); r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;
@ -3124,7 +3125,7 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"This systemd-tmpfiles version is compiled without support for --image=."); "This systemd-tmpfiles version is compiled without support for --image=.");
#else #else
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_image); r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_image);
if (r < 0) if (r < 0)
return r; return r;
#endif #endif

View File

@ -750,7 +750,7 @@ install_compiled_systemd() {
install_debian_systemd() { install_debian_systemd() {
ddebug "Install debian systemd" ddebug "Install debian systemd"
local _systemd_pkgs=$(apt-cache showsrc systemd | grep -m 1 -E '^Binary:' | cut -d ':' -f 2 | tr -d ,) local _systemd_pkgs=$(grep -E '^Package:' ${SOURCE_DIR}/debian/control | cut -d ':' -f 2)
local _files="" local _files=""
for deb in $_systemd_pkgs; do for deb in $_systemd_pkgs; do
_files=$(dpkg-query -L $deb 2>/dev/null) || continue _files=$(dpkg-query -L $deb 2>/dev/null) || continue