1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3 This file is part of systemd.
5 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
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.
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.
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/>.
30 #include <sys/epoll.h>
33 #include "udev-util.h"
36 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
39 static void log_fn(struct udev *udev,
40 int priority, const char *file, int line, const char *fn,
41 const char *format, va_list args) {
42 printf("test-libudev: %s %s:%d ", fn, file, line);
43 vprintf(format, args);
46 static void print_device(struct udev_device *device) {
50 struct udev_list_entry *list_entry;
52 printf("*** device: %p ***\n", device);
53 str = udev_device_get_action(device);
55 printf("action: '%s'\n", str);
57 str = udev_device_get_syspath(device);
58 printf("syspath: '%s'\n", str);
60 str = udev_device_get_sysname(device);
61 printf("sysname: '%s'\n", str);
63 str = udev_device_get_sysnum(device);
65 printf("sysnum: '%s'\n", str);
67 str = udev_device_get_devpath(device);
68 printf("devpath: '%s'\n", str);
70 str = udev_device_get_subsystem(device);
72 printf("subsystem: '%s'\n", str);
74 str = udev_device_get_devtype(device);
76 printf("devtype: '%s'\n", str);
78 str = udev_device_get_driver(device);
80 printf("driver: '%s'\n", str);
82 str = udev_device_get_devnode(device);
84 printf("devname: '%s'\n", str);
86 devnum = udev_device_get_devnum(device);
87 if (major(devnum) > 0)
88 printf("devnum: %u:%u\n", major(devnum), minor(devnum));
91 udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
92 printf("link: '%s'\n", udev_list_entry_get_name(list_entry));
96 printf("found %i links\n", count);
99 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
100 printf("property: '%s=%s'\n",
101 udev_list_entry_get_name(list_entry),
102 udev_list_entry_get_value(list_entry));
106 printf("found %i properties\n", count);
108 str = udev_device_get_property_value(device, "MAJOR");
110 printf("MAJOR: '%s'\n", str);
112 str = udev_device_get_sysattr_value(device, "dev");
114 printf("attr{dev}: '%s'\n", str);
119 static int test_device(struct udev *udev, const char *syspath) {
120 _cleanup_udev_device_unref_ struct udev_device *device;
122 printf("looking at device: %s\n", syspath);
123 device = udev_device_new_from_syspath(udev, syspath);
124 if (device == NULL) {
125 printf("no device found\n");
128 print_device(device);
133 static int test_device_parents(struct udev *udev, const char *syspath) {
134 _cleanup_udev_device_unref_ struct udev_device *device;
135 struct udev_device *device_parent;
137 printf("looking at device: %s\n", syspath);
138 device = udev_device_new_from_syspath(udev, syspath);
142 printf("looking at parents\n");
143 device_parent = device;
145 print_device(device_parent);
146 device_parent = udev_device_get_parent(device_parent);
147 } while (device_parent != NULL);
149 printf("looking at parents again\n");
150 device_parent = device;
152 print_device(device_parent);
153 device_parent = udev_device_get_parent(device_parent);
154 } while (device_parent != NULL);
159 static int test_device_devnum(struct udev *udev) {
160 dev_t devnum = makedev(1, 3);
161 struct udev_device *device;
163 printf("looking up device: %u:%u\n", major(devnum), minor(devnum));
164 device = udev_device_new_from_devnum(udev, 'c', devnum);
167 print_device(device);
168 udev_device_unref(device);
172 static int test_device_subsys_name(struct udev *udev) {
173 struct udev_device *device;
175 printf("looking up device: 'block':'sda'\n");
176 device = udev_device_new_from_subsystem_sysname(udev, "block", "sda");
179 print_device(device);
180 udev_device_unref(device);
182 printf("looking up device: 'subsystem':'pci'\n");
183 device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
186 print_device(device);
187 udev_device_unref(device);
189 printf("looking up device: 'drivers':'scsi:sd'\n");
190 device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd");
193 print_device(device);
194 udev_device_unref(device);
196 printf("looking up device: 'module':'printk'\n");
197 device = udev_device_new_from_subsystem_sysname(udev, "module", "printk");
200 print_device(device);
201 udev_device_unref(device);
205 static int test_enumerate_print_list(struct udev_enumerate *enumerate) {
206 struct udev_list_entry *list_entry;
209 udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
210 struct udev_device *device;
212 device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
213 udev_list_entry_get_name(list_entry));
214 if (device != NULL) {
215 printf("device: '%s' (%s)\n",
216 udev_device_get_syspath(device),
217 udev_device_get_subsystem(device));
218 udev_device_unref(device);
222 printf("found %i devices\n\n", count);
226 static int test_monitor(struct udev *udev) {
227 struct udev_monitor *udev_monitor = NULL;
230 struct epoll_event ep_udev, ep_stdin;
232 fd_ep = epoll_create1(EPOLL_CLOEXEC);
234 printf("error creating epoll fd: %m\n");
238 udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
239 if (udev_monitor == NULL) {
240 printf("no socket\n");
243 fd_udev = udev_monitor_get_fd(udev_monitor);
245 if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) < 0 ||
246 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) < 0 ||
247 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") < 0) {
248 printf("filter failed\n");
252 if (udev_monitor_enable_receiving(udev_monitor) < 0) {
253 printf("bind failed\n");
257 memzero(&ep_udev, sizeof(struct epoll_event));
258 ep_udev.events = EPOLLIN;
259 ep_udev.data.fd = fd_udev;
260 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
261 printf("fail to add fd to epoll: %m\n");
265 memzero(&ep_stdin, sizeof(struct epoll_event));
266 ep_stdin.events = EPOLLIN;
267 ep_stdin.data.fd = STDIN_FILENO;
268 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) < 0) {
269 printf("fail to add fd to epoll: %m\n");
275 struct epoll_event ev[4];
276 struct udev_device *device;
279 printf("waiting for events from udev, press ENTER to exit\n");
280 fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1);
281 printf("epoll fd count: %i\n", fdcount);
283 for (i = 0; i < fdcount; i++) {
284 if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
285 device = udev_monitor_receive_device(udev_monitor);
286 if (device == NULL) {
287 printf("no device from socket\n");
290 print_device(device);
291 udev_device_unref(device);
292 } else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) {
293 printf("exiting loop\n");
301 udev_monitor_unref(udev_monitor);
305 static int test_queue(struct udev *udev) {
306 struct udev_queue *udev_queue;
308 udev_queue = udev_queue_new(udev);
309 if (udev_queue == NULL)
312 if (udev_queue_get_queue_is_empty(udev_queue))
313 printf("queue is empty\n");
315 udev_queue_unref(udev_queue);
319 static int test_enumerate(struct udev *udev, const char *subsystem) {
320 struct udev_enumerate *udev_enumerate;
322 printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem);
323 udev_enumerate = udev_enumerate_new(udev);
324 if (udev_enumerate == NULL)
326 udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
327 udev_enumerate_scan_devices(udev_enumerate);
328 test_enumerate_print_list(udev_enumerate);
329 udev_enumerate_unref(udev_enumerate);
331 printf("enumerate 'net' + duplicated scan + null + zero\n");
332 udev_enumerate = udev_enumerate_new(udev);
333 if (udev_enumerate == NULL)
335 udev_enumerate_add_match_subsystem(udev_enumerate, "net");
336 udev_enumerate_scan_devices(udev_enumerate);
337 udev_enumerate_scan_devices(udev_enumerate);
338 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
339 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
340 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
341 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
342 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
343 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
344 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
345 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
346 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
347 udev_enumerate_scan_devices(udev_enumerate);
348 test_enumerate_print_list(udev_enumerate);
349 udev_enumerate_unref(udev_enumerate);
351 printf("enumerate 'block'\n");
352 udev_enumerate = udev_enumerate_new(udev);
353 if (udev_enumerate == NULL)
355 udev_enumerate_add_match_subsystem(udev_enumerate,"block");
356 udev_enumerate_add_match_is_initialized(udev_enumerate);
357 udev_enumerate_scan_devices(udev_enumerate);
358 test_enumerate_print_list(udev_enumerate);
359 udev_enumerate_unref(udev_enumerate);
361 printf("enumerate 'not block'\n");
362 udev_enumerate = udev_enumerate_new(udev);
363 if (udev_enumerate == NULL)
365 udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block");
366 udev_enumerate_scan_devices(udev_enumerate);
367 test_enumerate_print_list(udev_enumerate);
368 udev_enumerate_unref(udev_enumerate);
370 printf("enumerate 'pci, mem, vc'\n");
371 udev_enumerate = udev_enumerate_new(udev);
372 if (udev_enumerate == NULL)
374 udev_enumerate_add_match_subsystem(udev_enumerate, "pci");
375 udev_enumerate_add_match_subsystem(udev_enumerate, "mem");
376 udev_enumerate_add_match_subsystem(udev_enumerate, "vc");
377 udev_enumerate_scan_devices(udev_enumerate);
378 test_enumerate_print_list(udev_enumerate);
379 udev_enumerate_unref(udev_enumerate);
381 printf("enumerate 'subsystem'\n");
382 udev_enumerate = udev_enumerate_new(udev);
383 if (udev_enumerate == NULL)
385 udev_enumerate_scan_subsystems(udev_enumerate);
386 test_enumerate_print_list(udev_enumerate);
387 udev_enumerate_unref(udev_enumerate);
389 printf("enumerate 'property IF_FS_*=filesystem'\n");
390 udev_enumerate = udev_enumerate_new(udev);
391 if (udev_enumerate == NULL)
393 udev_enumerate_add_match_property(udev_enumerate, "ID_FS*", "filesystem");
394 udev_enumerate_scan_devices(udev_enumerate);
395 test_enumerate_print_list(udev_enumerate);
396 udev_enumerate_unref(udev_enumerate);
400 static void test_hwdb(struct udev *udev, const char *modalias) {
401 struct udev_hwdb *hwdb;
402 struct udev_list_entry *entry;
404 hwdb = udev_hwdb_new(udev);
406 udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
407 printf("'%s'='%s'\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
410 hwdb = udev_hwdb_unref(hwdb);
411 assert(hwdb == NULL);
414 int main(int argc, char *argv[]) {
415 struct udev *udev = NULL;
416 static const struct option options[] = {
417 { "syspath", required_argument, NULL, 'p' },
418 { "subsystem", required_argument, NULL, 's' },
419 { "debug", no_argument, NULL, 'd' },
420 { "help", no_argument, NULL, 'h' },
421 { "version", no_argument, NULL, 'V' },
424 const char *syspath = "/devices/virtual/mem/null";
425 const char *subsystem = NULL;
430 printf("context: %p\n", udev);
432 printf("no context\n");
435 udev_set_log_fn(udev, log_fn);
436 printf("set log: %p\n", log_fn);
439 while ((c = getopt_long(argc, argv, "p:s:dhV", options, NULL)) >= 0)
451 if (udev_get_log_priority(udev) < LOG_INFO)
452 udev_set_log_priority(udev, LOG_INFO);
456 printf("--debug --syspath= --subsystem= --help\n");
460 printf("%s\n", VERSION);
467 assert_not_reached("Unhandled option code.");
471 /* add sys path if needed */
472 if (!startswith(syspath, "/sys")) {
473 snprintf(path, sizeof(path), "/sys/%s", syspath);
477 test_device(udev, syspath);
478 test_device_devnum(udev);
479 test_device_subsys_name(udev);
480 test_device_parents(udev, syspath);
482 test_enumerate(udev, subsystem);
486 test_hwdb(udev, "usb:v0D50p0011*");