mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
Merge pull request #20871 from mrc0mmand/udevadm-property-value
udev: teach udevadm --property=NAME and --value options
This commit is contained in:
commit
bfcc0fedd0
@ -98,6 +98,24 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--property=<replaceable>NAME</replaceable></option></term>
|
||||
<listitem>
|
||||
<para>When showing device properties using the <option>--query=property</option>
|
||||
option, limit display to properties specified in the argument. The argument should
|
||||
be a comma-separated list of property names. If not specified, all known properties
|
||||
are shown.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--value</option></term>
|
||||
<listitem>
|
||||
<para>When showing device properties using the <option>--query=property</option>
|
||||
option, print only their values, and skip the property name and <literal>=</literal>.</para>
|
||||
<para>Cannot be used together with <option>-x/--export</option> or
|
||||
<option>-P/--export-prefix</option>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-p</option></term>
|
||||
<term><option>--path=<replaceable>DEVPATH</replaceable></option></term>
|
||||
|
@ -49,8 +49,8 @@ _udevadm() {
|
||||
[COMMON]='-h --help -V --version'
|
||||
[DEBUG]='-d --debug'
|
||||
[INFO_STANDALONE]='-r --root -a --attribute-walk -x --export -e --export-db -c --cleanup-db
|
||||
-w --wait-for-initialization'
|
||||
[INFO_ARG]='-q --query -p --path -n --name -P --export-prefix -d --device-id-of-file'
|
||||
-w --wait-for-initialization --value'
|
||||
[INFO_ARG]='-q --query -p --path -n --name -P --export-prefix -d --device-id-of-file --property'
|
||||
[TRIGGER_STANDALONE]='-v --verbose -n --dry-run -q --quiet -w --settle --wait-daemon --uuid'
|
||||
[TRIGGER_ARG]='-t --type -c --action -s --subsystem-match -S --subsystem-nomatch
|
||||
-a --attr-match -A --attr-nomatch -p --property-match
|
||||
|
@ -13,7 +13,9 @@ _udevadm_info(){
|
||||
'--export-prefix=[Add a prefix to the key name of exported values.]:prefix' \
|
||||
'--device-id-of-file=[Print major/minor numbers of the underlying device, where the file lives on.]:files:_udevadm_mounts' \
|
||||
'--export-db[Export the content of the udev database.]' \
|
||||
'--cleanup-db[Cleanup the udev database.]'
|
||||
'--cleanup-db[Cleanup the udev database.]' \
|
||||
'--value[When showing properties, print only their values.]' \
|
||||
'--property=[Show only properties by this name.]'
|
||||
}
|
||||
|
||||
(( $+functions[_udevadm_trigger] )) ||
|
||||
|
@ -300,6 +300,24 @@ int strv_split_full(char ***t, const char *s, const char *separators, ExtractFla
|
||||
return (int) n;
|
||||
}
|
||||
|
||||
int strv_split_and_extend_full(char ***t, const char *s, const char *separators, bool filter_duplicates, ExtractFlags flags) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
int r;
|
||||
|
||||
assert(t);
|
||||
assert(s);
|
||||
|
||||
r = strv_split_full(&l, s, separators, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_extend_strv(t, l, filter_duplicates);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return (int) strv_length(*t);
|
||||
}
|
||||
|
||||
int strv_split_colon_pairs(char ***t, const char *s) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
size_t n = 0;
|
||||
|
@ -83,6 +83,9 @@ static inline char **strv_split(const char *s, const char *separators) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int strv_split_and_extend_full(char ***t, const char *s, const char *separators, bool filter_duplicates, ExtractFlags flags);
|
||||
#define strv_split_and_extend(t, s, sep, dup) strv_split_and_extend_full(t, s, sep, dup, 0)
|
||||
|
||||
int strv_split_newlines_full(char ***ret, const char *s, ExtractFlags flags);
|
||||
static inline char **strv_split_newlines(const char *s) {
|
||||
char **ret;
|
||||
|
@ -390,6 +390,28 @@ static void test_strv_split_full(void) {
|
||||
assert_se(streq_ptr(l[5], NULL));
|
||||
}
|
||||
|
||||
static void test_strv_split_and_extend_full(void) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
const char *str1 = ":foo\\:bar:";
|
||||
const char *str2 = "waldo::::::baz";
|
||||
int r;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
r = strv_split_and_extend(&l, "", ":", false);
|
||||
assert_se(r == (int) strv_length(l));
|
||||
r = strv_split_and_extend_full(&l, str1, ":", false, EXTRACT_DONT_COALESCE_SEPARATORS);
|
||||
assert_se(r == (int) strv_length(l));
|
||||
assert_se(streq_ptr(l[0], ""));
|
||||
assert_se(streq_ptr(l[1], "foo:bar"));
|
||||
assert_se(streq_ptr(l[2], ""));
|
||||
r = strv_split_and_extend_full(&l, str2, ":", false, 0);
|
||||
assert_se(r == (int) strv_length(l));
|
||||
assert_se(streq_ptr(l[3], "waldo"));
|
||||
assert_se(streq_ptr(l[4], "baz"));
|
||||
assert_se(streq_ptr(l[5], NULL));
|
||||
}
|
||||
|
||||
static void test_strv_split_colon_pairs(void) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
const char *str = "one:two three four:five six seven:eight\\:nine ten\\:eleven\\\\",
|
||||
@ -1028,6 +1050,7 @@ int main(int argc, char *argv[]) {
|
||||
test_strv_split();
|
||||
test_strv_split_empty();
|
||||
test_strv_split_full();
|
||||
test_strv_split_and_extend_full();
|
||||
test_strv_split_colon_pairs();
|
||||
test_strv_split_newlines();
|
||||
test_strv_split_newlines_full();
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "dirent-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "sort-util.h"
|
||||
#include "static-destruct.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "udev-util.h"
|
||||
@ -38,8 +39,10 @@ typedef enum QueryType {
|
||||
QUERY_ALL,
|
||||
} QueryType;
|
||||
|
||||
static char **arg_properties = NULL;
|
||||
static bool arg_root = false;
|
||||
static bool arg_export = false;
|
||||
static bool arg_value = false;
|
||||
static const char *arg_export_prefix = NULL;
|
||||
static usec_t arg_wait_for_initialization_timeout = 0;
|
||||
|
||||
@ -60,6 +63,8 @@ typedef struct SysAttr {
|
||||
const char *value;
|
||||
} SysAttr;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_properties, strv_freep);
|
||||
|
||||
static int sysattr_compare(const SysAttr *a, const SysAttr *b) {
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
@ -316,11 +321,18 @@ static int query_device(QueryType query, sd_device* device) {
|
||||
case QUERY_PROPERTY: {
|
||||
const char *key, *value;
|
||||
|
||||
FOREACH_DEVICE_PROPERTY(device, key, value)
|
||||
FOREACH_DEVICE_PROPERTY(device, key, value) {
|
||||
if (arg_properties && !strv_contains(arg_properties, key))
|
||||
continue;
|
||||
|
||||
if (arg_export)
|
||||
printf("%s%s='%s'\n", strempty(arg_export_prefix), key, value);
|
||||
else if (arg_value)
|
||||
printf("%s\n", value);
|
||||
else
|
||||
printf("%s=%s\n", key, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -343,6 +355,8 @@ static int help(void) {
|
||||
" path sysfs device path\n"
|
||||
" property The device properties\n"
|
||||
" all All values\n"
|
||||
" --property=NAME Show only properties by this name\n"
|
||||
" --value When showing properties, print only their values\n"
|
||||
" -p --path=SYSPATH sysfs device path used for query or attribute walk\n"
|
||||
" -n --name=NAME Node or symlink name used for query or attribute walk\n"
|
||||
" -r --root Prepend dev directory to path names\n"
|
||||
@ -365,20 +379,27 @@ int info_main(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
int c, r;
|
||||
|
||||
enum {
|
||||
ARG_PROPERTY = 0x100,
|
||||
ARG_VALUE,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "name", required_argument, NULL, 'n' },
|
||||
{ "path", required_argument, NULL, 'p' },
|
||||
{ "query", required_argument, NULL, 'q' },
|
||||
{ "attribute-walk", no_argument, NULL, 'a' },
|
||||
{ "cleanup-db", no_argument, NULL, 'c' },
|
||||
{ "export-db", no_argument, NULL, 'e' },
|
||||
{ "root", no_argument, NULL, 'r' },
|
||||
{ "device-id-of-file", required_argument, NULL, 'd' },
|
||||
{ "export", no_argument, NULL, 'x' },
|
||||
{ "export-prefix", required_argument, NULL, 'P' },
|
||||
{ "wait-for-initialization", optional_argument, NULL, 'w' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "attribute-walk", no_argument, NULL, 'a' },
|
||||
{ "cleanup-db", no_argument, NULL, 'c' },
|
||||
{ "device-id-of-file", required_argument, NULL, 'd' },
|
||||
{ "export", no_argument, NULL, 'x' },
|
||||
{ "export-db", no_argument, NULL, 'e' },
|
||||
{ "export-prefix", required_argument, NULL, 'P' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "name", required_argument, NULL, 'n' },
|
||||
{ "path", required_argument, NULL, 'p' },
|
||||
{ "property", required_argument, NULL, ARG_PROPERTY },
|
||||
{ "query", required_argument, NULL, 'q' },
|
||||
{ "root", no_argument, NULL, 'r' },
|
||||
{ "value", no_argument, NULL, ARG_VALUE },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "wait-for-initialization", optional_argument, NULL, 'w' },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -387,6 +408,22 @@ int info_main(int argc, char *argv[], void *userdata) {
|
||||
|
||||
while ((c = getopt_long(argc, argv, "aced:n:p:q:rxP:w::Vh", options, NULL)) >= 0)
|
||||
switch (c) {
|
||||
case ARG_PROPERTY:
|
||||
/* Make sure that if the empty property list was specified, we won't show any
|
||||
properties. */
|
||||
if (isempty(optarg) && !arg_properties) {
|
||||
arg_properties = new0(char*, 1);
|
||||
if (!arg_properties)
|
||||
return log_oom();
|
||||
} else {
|
||||
r = strv_split_and_extend(&arg_properties, optarg, ",", true);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
break;
|
||||
case ARG_VALUE:
|
||||
arg_value = true;
|
||||
break;
|
||||
case 'n':
|
||||
case 'p': {
|
||||
const char *prefix = c == 'n' ? "/dev/" : "/sys/";
|
||||
@ -478,6 +515,10 @@ int info_main(int argc, char *argv[], void *userdata) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Only one device may be specified with -a/--attribute-walk");
|
||||
|
||||
if (arg_export && arg_value)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"-x/--export or -P/--export-prefix cannot be used with --value");
|
||||
|
||||
char **p;
|
||||
STRV_FOREACH(p, devices) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user