]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/udev/udevadm-test.c
Merge pull request #10117 from keszybz/undynamicify
[thirdparty/systemd.git] / src / udev / udevadm-test.c
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3 * Copyright © 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
4 */
5
6 #include <errno.h>
7 #include <getopt.h>
8 #include <signal.h>
9 #include <stddef.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <sys/signalfd.h>
13 #include <unistd.h>
14
15 #include "string-util.h"
16 #include "udev.h"
17 #include "udevadm.h"
18
19 static const char *arg_action = "add";
20 static int arg_resolve_names = 1;
21 static char arg_syspath[UTIL_PATH_SIZE] = {};
22
23 static int help(void) {
24
25 printf("%s test [OPTIONS] DEVPATH\n\n"
26 "Test an event run.\n\n"
27 " -h --help Show this help\n"
28 " -V --version Show package version\n"
29 " -a --action=ACTION Set action string\n"
30 " -N --resolve-names=early|late|never When to resolve names\n"
31 , program_invocation_short_name);
32
33 return 0;
34 }
35
36 static int parse_argv(int argc, char *argv[]) {
37 static const struct option options[] = {
38 { "action", required_argument, NULL, 'a' },
39 { "resolve-names", required_argument, NULL, 'N' },
40 { "version", no_argument, NULL, 'V' },
41 { "help", no_argument, NULL, 'h' },
42 {}
43 };
44
45 int c;
46
47 while ((c = getopt_long(argc, argv, "a:N:Vh", options, NULL)) >= 0)
48 switch (c) {
49 case 'a':
50 arg_action = optarg;
51 break;
52 case 'N':
53 if (streq (optarg, "early")) {
54 arg_resolve_names = 1;
55 } else if (streq (optarg, "late")) {
56 arg_resolve_names = 0;
57 } else if (streq (optarg, "never")) {
58 arg_resolve_names = -1;
59 } else {
60 log_error("resolve-names must be early, late or never");
61 return -EINVAL;
62 }
63 break;
64 case 'V':
65 return print_version();
66 case 'h':
67 return help();
68 case '?':
69 return -EINVAL;
70 default:
71 assert_not_reached("Unknown option");
72 }
73
74 if (!argv[optind]) {
75 log_error("syspath parameter missing.");
76 return -EINVAL;
77 }
78
79 /* add /sys if needed */
80 if (!startswith(argv[optind], "/sys"))
81 strscpyl(arg_syspath, sizeof(arg_syspath), "/sys", argv[optind], NULL);
82 else
83 strscpy(arg_syspath, sizeof(arg_syspath), argv[optind]);
84
85 return 1;
86 }
87
88 int test_main(int argc, char *argv[], void *userdata) {
89 _cleanup_(udev_rules_unrefp) struct udev_rules *rules = NULL;
90 _cleanup_(udev_device_unrefp) struct udev_device *dev = NULL;
91 _cleanup_(udev_event_unrefp) struct udev_event *event = NULL;
92 struct udev_list_entry *entry;
93 sigset_t mask, sigmask_orig;
94 int r;
95
96 log_set_max_level(LOG_DEBUG);
97
98 r = parse_argv(argc, argv);
99 if (r <= 0)
100 return r;
101
102 printf("This program is for debugging only, it does not run any program\n"
103 "specified by a RUN key. It may show incorrect results, because\n"
104 "some values may be different, or not available at a simulation run.\n"
105 "\n");
106
107 sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);
108
109 udev_builtin_init();
110
111 rules = udev_rules_new(arg_resolve_names);
112 if (!rules) {
113 log_error("Failed to read udev rules.");
114 r = -ENOMEM;
115 goto out;
116 }
117
118 dev = udev_device_new_from_synthetic_event(NULL, arg_syspath, arg_action);
119 if (dev == NULL) {
120 r = log_error_errno(errno, "Failed to open device '%s': %m", arg_syspath);
121 goto out;
122 }
123
124 /* don't read info from the db */
125 udev_device_set_info_loaded(dev);
126
127 event = udev_event_new(dev);
128
129 sigfillset(&mask);
130 sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
131
132 udev_event_execute_rules(event,
133 60 * USEC_PER_SEC, 20 * USEC_PER_SEC,
134 NULL,
135 rules);
136
137 udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
138 printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
139
140 udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) {
141 char program[UTIL_PATH_SIZE];
142
143 udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program), false);
144 printf("run: '%s'\n", program);
145 }
146
147 r = 0;
148 out:
149 udev_builtin_exit();
150 return r;
151 }