]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-libudev.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / test / test-libudev.c
CommitLineData
601185b4 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1298001e
KS
2/***
3 This file is part of systemd.
4
5 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
33a5cc29 20
b2d9e4f2 21#include <getopt.h>
07630cea 22#include <stdio.h>
f2fd4d27 23#include <sys/epoll.h>
07630cea 24#include <unistd.h>
ba6929f6 25
33a5cc29 26#include "libudev.h"
07630cea
LP
27
28#include "string-util.h"
1ca208fb 29#include "udev-util.h"
33502ffe 30#include "util.h"
33a5cc29 31
f2fd4d27
KS
32#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
33
f168c273 34static void print_device(struct udev_device *device) {
912541b0
KS
35 const char *str;
36 dev_t devnum;
37 int count;
38 struct udev_list_entry *list_entry;
39
40 printf("*** device: %p ***\n", device);
41 str = udev_device_get_action(device);
42 if (str != NULL)
43 printf("action: '%s'\n", str);
44
45 str = udev_device_get_syspath(device);
46 printf("syspath: '%s'\n", str);
47
48 str = udev_device_get_sysname(device);
49 printf("sysname: '%s'\n", str);
50
51 str = udev_device_get_sysnum(device);
52 if (str != NULL)
53 printf("sysnum: '%s'\n", str);
54
55 str = udev_device_get_devpath(device);
56 printf("devpath: '%s'\n", str);
57
58 str = udev_device_get_subsystem(device);
59 if (str != NULL)
60 printf("subsystem: '%s'\n", str);
61
62 str = udev_device_get_devtype(device);
63 if (str != NULL)
64 printf("devtype: '%s'\n", str);
65
66 str = udev_device_get_driver(device);
67 if (str != NULL)
68 printf("driver: '%s'\n", str);
69
70 str = udev_device_get_devnode(device);
71 if (str != NULL)
72 printf("devname: '%s'\n", str);
73
74 devnum = udev_device_get_devnum(device);
75 if (major(devnum) > 0)
76 printf("devnum: %u:%u\n", major(devnum), minor(devnum));
77
78 count = 0;
79 udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
80 printf("link: '%s'\n", udev_list_entry_get_name(list_entry));
81 count++;
82 }
83 if (count > 0)
84 printf("found %i links\n", count);
85
86 count = 0;
87 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
88 printf("property: '%s=%s'\n",
89 udev_list_entry_get_name(list_entry),
90 udev_list_entry_get_value(list_entry));
91 count++;
92 }
93 if (count > 0)
94 printf("found %i properties\n", count);
95
96 str = udev_device_get_property_value(device, "MAJOR");
97 if (str != NULL)
98 printf("MAJOR: '%s'\n", str);
99
100 str = udev_device_get_sysattr_value(device, "dev");
101 if (str != NULL)
102 printf("attr{dev}: '%s'\n", str);
103
104 printf("\n");
ba6929f6
KS
105}
106
f168c273 107static int test_device(struct udev *udev, const char *syspath) {
1ca208fb 108 _cleanup_udev_device_unref_ struct udev_device *device;
912541b0
KS
109
110 printf("looking at device: %s\n", syspath);
111 device = udev_device_new_from_syspath(udev, syspath);
112 if (device == NULL) {
113 printf("no device found\n");
114 return -1;
115 }
116 print_device(device);
1ca208fb 117
912541b0 118 return 0;
33a5cc29
KS
119}
120
f168c273 121static int test_device_parents(struct udev *udev, const char *syspath) {
1ca208fb 122 _cleanup_udev_device_unref_ struct udev_device *device;
912541b0
KS
123 struct udev_device *device_parent;
124
125 printf("looking at device: %s\n", syspath);
126 device = udev_device_new_from_syspath(udev, syspath);
127 if (device == NULL)
128 return -1;
129
130 printf("looking at parents\n");
131 device_parent = device;
132 do {
133 print_device(device_parent);
134 device_parent = udev_device_get_parent(device_parent);
135 } while (device_parent != NULL);
136
137 printf("looking at parents again\n");
138 device_parent = device;
139 do {
140 print_device(device_parent);
141 device_parent = udev_device_get_parent(device_parent);
142 } while (device_parent != NULL);
912541b0
KS
143
144 return 0;
4ad3a37f
KS
145}
146
f168c273 147static int test_device_devnum(struct udev *udev) {
912541b0
KS
148 dev_t devnum = makedev(1, 3);
149 struct udev_device *device;
150
151 printf("looking up device: %u:%u\n", major(devnum), minor(devnum));
152 device = udev_device_new_from_devnum(udev, 'c', devnum);
153 if (device == NULL)
154 return -1;
155 print_device(device);
156 udev_device_unref(device);
157 return 0;
4c9dff47
KS
158}
159
f168c273 160static int test_device_subsys_name(struct udev *udev) {
912541b0
KS
161 struct udev_device *device;
162
163 printf("looking up device: 'block':'sda'\n");
164 device = udev_device_new_from_subsystem_sysname(udev, "block", "sda");
165 if (device == NULL)
166 return -1;
167 print_device(device);
168 udev_device_unref(device);
169
170 printf("looking up device: 'subsystem':'pci'\n");
171 device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
172 if (device == NULL)
173 return -1;
174 print_device(device);
175 udev_device_unref(device);
176
177 printf("looking up device: 'drivers':'scsi:sd'\n");
178 device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd");
179 if (device == NULL)
180 return -1;
181 print_device(device);
182 udev_device_unref(device);
183
184 printf("looking up device: 'module':'printk'\n");
185 device = udev_device_new_from_subsystem_sysname(udev, "module", "printk");
186 if (device == NULL)
187 return -1;
188 print_device(device);
189 udev_device_unref(device);
190 return 0;
90d80c2e
KS
191}
192
f168c273 193static int test_enumerate_print_list(struct udev_enumerate *enumerate) {
912541b0
KS
194 struct udev_list_entry *list_entry;
195 int count = 0;
196
197 udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
198 struct udev_device *device;
199
200 device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
201 udev_list_entry_get_name(list_entry));
202 if (device != NULL) {
203 printf("device: '%s' (%s)\n",
204 udev_device_get_syspath(device),
205 udev_device_get_subsystem(device));
206 udev_device_unref(device);
207 count++;
208 }
209 }
210 printf("found %i devices\n\n", count);
211 return count;
ba6929f6
KS
212}
213
f168c273 214static int test_monitor(struct udev *udev) {
912541b0
KS
215 struct udev_monitor *udev_monitor = NULL;
216 int fd_ep;
217 int fd_udev = -1;
218 struct epoll_event ep_udev, ep_stdin;
219
220 fd_ep = epoll_create1(EPOLL_CLOEXEC);
221 if (fd_ep < 0) {
222 printf("error creating epoll fd: %m\n");
223 goto out;
224 }
225
226 udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
227 if (udev_monitor == NULL) {
228 printf("no socket\n");
229 goto out;
230 }
231 fd_udev = udev_monitor_get_fd(udev_monitor);
232
233 if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) < 0 ||
234 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) < 0 ||
235 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") < 0) {
236 printf("filter failed\n");
237 goto out;
238 }
239
240 if (udev_monitor_enable_receiving(udev_monitor) < 0) {
241 printf("bind failed\n");
242 goto out;
243 }
244
29804cc1 245 memzero(&ep_udev, sizeof(struct epoll_event));
912541b0
KS
246 ep_udev.events = EPOLLIN;
247 ep_udev.data.fd = fd_udev;
248 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
249 printf("fail to add fd to epoll: %m\n");
250 goto out;
251 }
252
29804cc1 253 memzero(&ep_stdin, sizeof(struct epoll_event));
912541b0
KS
254 ep_stdin.events = EPOLLIN;
255 ep_stdin.data.fd = STDIN_FILENO;
256 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) < 0) {
257 printf("fail to add fd to epoll: %m\n");
258 goto out;
259 }
260
261 for (;;) {
262 int fdcount;
263 struct epoll_event ev[4];
264 struct udev_device *device;
265 int i;
266
267 printf("waiting for events from udev, press ENTER to exit\n");
268 fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1);
269 printf("epoll fd count: %i\n", fdcount);
270
271 for (i = 0; i < fdcount; i++) {
272 if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
273 device = udev_monitor_receive_device(udev_monitor);
274 if (device == NULL) {
275 printf("no device from socket\n");
276 continue;
277 }
278 print_device(device);
279 udev_device_unref(device);
280 } else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) {
281 printf("exiting loop\n");
282 goto out;
283 }
284 }
285 }
f2fd4d27 286out:
912541b0
KS
287 if (fd_ep >= 0)
288 close(fd_ep);
289 udev_monitor_unref(udev_monitor);
290 return 0;
33a5cc29
KS
291}
292
f168c273 293static int test_queue(struct udev *udev) {
912541b0 294 struct udev_queue *udev_queue;
912541b0
KS
295
296 udev_queue = udev_queue_new(udev);
297 if (udev_queue == NULL)
298 return -1;
912541b0
KS
299
300 if (udev_queue_get_queue_is_empty(udev_queue))
301 printf("queue is empty\n");
912541b0 302
912541b0
KS
303 udev_queue_unref(udev_queue);
304 return 0;
64ccdf82
KS
305}
306
f168c273 307static int test_enumerate(struct udev *udev, const char *subsystem) {
912541b0 308 struct udev_enumerate *udev_enumerate;
c0c6a4fc 309 int r;
912541b0
KS
310
311 printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem);
312 udev_enumerate = udev_enumerate_new(udev);
313 if (udev_enumerate == NULL)
314 return -1;
315 udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
316 udev_enumerate_scan_devices(udev_enumerate);
317 test_enumerate_print_list(udev_enumerate);
318 udev_enumerate_unref(udev_enumerate);
319
320 printf("enumerate 'net' + duplicated scan + null + zero\n");
321 udev_enumerate = udev_enumerate_new(udev);
322 if (udev_enumerate == NULL)
323 return -1;
324 udev_enumerate_add_match_subsystem(udev_enumerate, "net");
325 udev_enumerate_scan_devices(udev_enumerate);
326 udev_enumerate_scan_devices(udev_enumerate);
327 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
328 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
329 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
330 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
331 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
332 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
333 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
334 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
335 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
336 udev_enumerate_scan_devices(udev_enumerate);
337 test_enumerate_print_list(udev_enumerate);
338 udev_enumerate_unref(udev_enumerate);
339
340 printf("enumerate 'block'\n");
341 udev_enumerate = udev_enumerate_new(udev);
342 if (udev_enumerate == NULL)
343 return -1;
344 udev_enumerate_add_match_subsystem(udev_enumerate,"block");
c0c6a4fc 345 r = udev_enumerate_add_match_is_initialized(udev_enumerate);
86ff9f11
TA
346 if (r < 0) {
347 udev_enumerate_unref(udev_enumerate);
c0c6a4fc 348 return r;
86ff9f11 349 }
912541b0
KS
350 udev_enumerate_scan_devices(udev_enumerate);
351 test_enumerate_print_list(udev_enumerate);
352 udev_enumerate_unref(udev_enumerate);
353
354 printf("enumerate 'not block'\n");
355 udev_enumerate = udev_enumerate_new(udev);
356 if (udev_enumerate == NULL)
357 return -1;
358 udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block");
359 udev_enumerate_scan_devices(udev_enumerate);
360 test_enumerate_print_list(udev_enumerate);
361 udev_enumerate_unref(udev_enumerate);
362
363 printf("enumerate 'pci, mem, vc'\n");
364 udev_enumerate = udev_enumerate_new(udev);
365 if (udev_enumerate == NULL)
366 return -1;
367 udev_enumerate_add_match_subsystem(udev_enumerate, "pci");
368 udev_enumerate_add_match_subsystem(udev_enumerate, "mem");
369 udev_enumerate_add_match_subsystem(udev_enumerate, "vc");
370 udev_enumerate_scan_devices(udev_enumerate);
371 test_enumerate_print_list(udev_enumerate);
372 udev_enumerate_unref(udev_enumerate);
373
374 printf("enumerate 'subsystem'\n");
375 udev_enumerate = udev_enumerate_new(udev);
376 if (udev_enumerate == NULL)
377 return -1;
378 udev_enumerate_scan_subsystems(udev_enumerate);
379 test_enumerate_print_list(udev_enumerate);
380 udev_enumerate_unref(udev_enumerate);
381
382 printf("enumerate 'property IF_FS_*=filesystem'\n");
383 udev_enumerate = udev_enumerate_new(udev);
384 if (udev_enumerate == NULL)
385 return -1;
386 udev_enumerate_add_match_property(udev_enumerate, "ID_FS*", "filesystem");
387 udev_enumerate_scan_devices(udev_enumerate);
388 test_enumerate_print_list(udev_enumerate);
389 udev_enumerate_unref(udev_enumerate);
390 return 0;
90d80c2e
KS
391}
392
872c8faa 393static void test_hwdb(struct udev *udev, const char *modalias) {
960787ae 394 struct udev_hwdb *hwdb;
2001208c
KS
395 struct udev_list_entry *entry;
396
397 hwdb = udev_hwdb_new(udev);
398
399 udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
400 printf("'%s'='%s'\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
401 printf("\n");
402
403 hwdb = udev_hwdb_unref(hwdb);
bdf7026e 404 assert_se(hwdb == NULL);
2001208c
KS
405}
406
f168c273 407int main(int argc, char *argv[]) {
912541b0
KS
408 struct udev *udev = NULL;
409 static const struct option options[] = {
410 { "syspath", required_argument, NULL, 'p' },
411 { "subsystem", required_argument, NULL, 's' },
412 { "debug", no_argument, NULL, 'd' },
413 { "help", no_argument, NULL, 'h' },
414 { "version", no_argument, NULL, 'V' },
415 {}
416 };
417 const char *syspath = "/devices/virtual/mem/null";
418 const char *subsystem = NULL;
419 char path[1024];
601185b4 420 int c;
912541b0
KS
421
422 udev = udev_new();
423 printf("context: %p\n", udev);
424 if (udev == NULL) {
425 printf("no context\n");
426 return 1;
427 }
912541b0 428
601185b4
ZJS
429 while ((c = getopt_long(argc, argv, "p:s:dhV", options, NULL)) >= 0)
430 switch (c) {
912541b0 431
912541b0
KS
432 case 'p':
433 syspath = optarg;
434 break;
601185b4 435
912541b0
KS
436 case 's':
437 subsystem = optarg;
438 break;
601185b4 439
912541b0 440 case 'd':
25e773ee
KS
441 if (log_get_max_level() < LOG_INFO)
442 log_set_max_level(LOG_INFO);
912541b0 443 break;
601185b4 444
912541b0
KS
445 case 'h':
446 printf("--debug --syspath= --subsystem= --help\n");
447 goto out;
601185b4 448
912541b0
KS
449 case 'V':
450 printf("%s\n", VERSION);
451 goto out;
601185b4
ZJS
452
453 case '?':
912541b0 454 goto out;
601185b4
ZJS
455
456 default:
457 assert_not_reached("Unhandled option code.");
912541b0 458 }
601185b4 459
912541b0 460
912541b0 461 /* add sys path if needed */
33502ffe 462 if (!startswith(syspath, "/sys")) {
6ada823a 463 snprintf(path, sizeof(path), "/sys/%s", syspath);
912541b0
KS
464 syspath = path;
465 }
466
467 test_device(udev, syspath);
468 test_device_devnum(udev);
469 test_device_subsys_name(udev);
470 test_device_parents(udev, syspath);
471
472 test_enumerate(udev, subsystem);
473
474 test_queue(udev);
475
2001208c
KS
476 test_hwdb(udev, "usb:v0D50p0011*");
477
912541b0 478 test_monitor(udev);
b2d9e4f2 479out:
912541b0
KS
480 udev_unref(udev);
481 return 0;
33a5cc29 482}