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/>.
29 #include <sys/epoll.h>
32 #include "udev-util.h"
35 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
38 static void log_fn(struct udev *udev,
39 int priority, const char *file, int line, const char *fn,
40 const char *format, va_list args) {
41 printf("test-libudev: %s %s:%d ", fn, file, line);
42 vprintf(format, args);
45 static void print_device(struct udev_device *device) {
49 struct udev_list_entry *list_entry;
51 printf("*** device: %p ***\n", device);
52 str = udev_device_get_action(device);
54 printf("action: '%s'\n", str);
56 str = udev_device_get_syspath(device);
57 printf("syspath: '%s'\n", str);
59 str = udev_device_get_sysname(device);
60 printf("sysname: '%s'\n", str);
62 str = udev_device_get_sysnum(device);
64 printf("sysnum: '%s'\n", str);
66 str = udev_device_get_devpath(device);
67 printf("devpath: '%s'\n", str);
69 str = udev_device_get_subsystem(device);
71 printf("subsystem: '%s'\n", str);
73 str = udev_device_get_devtype(device);
75 printf("devtype: '%s'\n", str);
77 str = udev_device_get_driver(device);
79 printf("driver: '%s'\n", str);
81 str = udev_device_get_devnode(device);
83 printf("devname: '%s'\n", str);
85 devnum = udev_device_get_devnum(device);
86 if (major(devnum) > 0)
87 printf("devnum: %u:%u\n", major(devnum), minor(devnum));
90 udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
91 printf("link: '%s'\n", udev_list_entry_get_name(list_entry));
95 printf("found %i links\n", count);
98 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
99 printf("property: '%s=%s'\n",
100 udev_list_entry_get_name(list_entry),
101 udev_list_entry_get_value(list_entry));
105 printf("found %i properties\n", count);
107 str = udev_device_get_property_value(device, "MAJOR");
109 printf("MAJOR: '%s'\n", str);
111 str = udev_device_get_sysattr_value(device, "dev");
113 printf("attr{dev}: '%s'\n", str);
118 static int test_device(struct udev *udev, const char *syspath) {
119 _cleanup_udev_device_unref_ struct udev_device *device;
121 printf("looking at device: %s\n", syspath);
122 device = udev_device_new_from_syspath(udev, syspath);
123 if (device == NULL) {
124 printf("no device found\n");
127 print_device(device);
132 static int test_device_parents(struct udev *udev, const char *syspath) {
133 _cleanup_udev_device_unref_ struct udev_device *device;
134 struct udev_device *device_parent;
136 printf("looking at device: %s\n", syspath);
137 device = udev_device_new_from_syspath(udev, syspath);
141 printf("looking at parents\n");
142 device_parent = device;
144 print_device(device_parent);
145 device_parent = udev_device_get_parent(device_parent);
146 } while (device_parent != NULL);
148 printf("looking at parents again\n");
149 device_parent = device;
151 print_device(device_parent);
152 device_parent = udev_device_get_parent(device_parent);
153 } while (device_parent != NULL);
158 static int test_device_devnum(struct udev *udev) {
159 dev_t devnum = makedev(1, 3);
160 struct udev_device *device;
162 printf("looking up device: %u:%u\n", major(devnum), minor(devnum));
163 device = udev_device_new_from_devnum(udev, 'c', devnum);
166 print_device(device);
167 udev_device_unref(device);
171 static int test_device_subsys_name(struct udev *udev) {
172 struct udev_device *device;
174 printf("looking up device: 'block':'sda'\n");
175 device = udev_device_new_from_subsystem_sysname(udev, "block", "sda");
178 print_device(device);
179 udev_device_unref(device);
181 printf("looking up device: 'subsystem':'pci'\n");
182 device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
185 print_device(device);
186 udev_device_unref(device);
188 printf("looking up device: 'drivers':'scsi:sd'\n");
189 device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd");
192 print_device(device);
193 udev_device_unref(device);
195 printf("looking up device: 'module':'printk'\n");
196 device = udev_device_new_from_subsystem_sysname(udev, "module", "printk");
199 print_device(device);
200 udev_device_unref(device);
204 static int test_enumerate_print_list(struct udev_enumerate *enumerate) {
205 struct udev_list_entry *list_entry;
208 udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
209 struct udev_device *device;
211 device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
212 udev_list_entry_get_name(list_entry));
213 if (device != NULL) {
214 printf("device: '%s' (%s)\n",
215 udev_device_get_syspath(device),
216 udev_device_get_subsystem(device));
217 udev_device_unref(device);
221 printf("found %i devices\n\n", count);
225 static int test_monitor(struct udev *udev) {
226 struct udev_monitor *udev_monitor = NULL;
229 struct epoll_event ep_udev, ep_stdin;
231 fd_ep = epoll_create1(EPOLL_CLOEXEC);
233 printf("error creating epoll fd: %m\n");
237 udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
238 if (udev_monitor == NULL) {
239 printf("no socket\n");
242 fd_udev = udev_monitor_get_fd(udev_monitor);
244 if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) < 0 ||
245 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) < 0 ||
246 udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") < 0) {
247 printf("filter failed\n");
251 if (udev_monitor_enable_receiving(udev_monitor) < 0) {
252 printf("bind failed\n");
256 memzero(&ep_udev, sizeof(struct epoll_event));
257 ep_udev.events = EPOLLIN;
258 ep_udev.data.fd = fd_udev;
259 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
260 printf("fail to add fd to epoll: %m\n");
264 memzero(&ep_stdin, sizeof(struct epoll_event));
265 ep_stdin.events = EPOLLIN;
266 ep_stdin.data.fd = STDIN_FILENO;
267 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) < 0) {
268 printf("fail to add fd to epoll: %m\n");
274 struct epoll_event ev[4];
275 struct udev_device *device;
278 printf("waiting for events from udev, press ENTER to exit\n");
279 fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1);
280 printf("epoll fd count: %i\n", fdcount);
282 for (i = 0; i < fdcount; i++) {
283 if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
284 device = udev_monitor_receive_device(udev_monitor);
285 if (device == NULL) {
286 printf("no device from socket\n");
289 print_device(device);
290 udev_device_unref(device);
291 } else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) {
292 printf("exiting loop\n");
300 udev_monitor_unref(udev_monitor);
304 static int test_queue(struct udev *udev) {
305 struct udev_queue *udev_queue;
307 udev_queue = udev_queue_new(udev);
308 if (udev_queue == NULL)
311 if (udev_queue_get_queue_is_empty(udev_queue))
312 printf("queue is empty\n");
314 udev_queue_unref(udev_queue);
318 static int test_enumerate(struct udev *udev, const char *subsystem) {
319 struct udev_enumerate *udev_enumerate;
321 printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem);
322 udev_enumerate = udev_enumerate_new(udev);
323 if (udev_enumerate == NULL)
325 udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
326 udev_enumerate_scan_devices(udev_enumerate);
327 test_enumerate_print_list(udev_enumerate);
328 udev_enumerate_unref(udev_enumerate);
330 printf("enumerate 'net' + duplicated scan + null + zero\n");
331 udev_enumerate = udev_enumerate_new(udev);
332 if (udev_enumerate == NULL)
334 udev_enumerate_add_match_subsystem(udev_enumerate, "net");
335 udev_enumerate_scan_devices(udev_enumerate);
336 udev_enumerate_scan_devices(udev_enumerate);
337 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
338 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
339 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
340 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
341 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
342 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
343 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
344 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
345 udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
346 udev_enumerate_scan_devices(udev_enumerate);
347 test_enumerate_print_list(udev_enumerate);
348 udev_enumerate_unref(udev_enumerate);
350 printf("enumerate 'block'\n");
351 udev_enumerate = udev_enumerate_new(udev);
352 if (udev_enumerate == NULL)
354 udev_enumerate_add_match_subsystem(udev_enumerate,"block");
355 udev_enumerate_add_match_is_initialized(udev_enumerate);
356 udev_enumerate_scan_devices(udev_enumerate);
357 test_enumerate_print_list(udev_enumerate);
358 udev_enumerate_unref(udev_enumerate);
360 printf("enumerate 'not block'\n");
361 udev_enumerate = udev_enumerate_new(udev);
362 if (udev_enumerate == NULL)
364 udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block");
365 udev_enumerate_scan_devices(udev_enumerate);
366 test_enumerate_print_list(udev_enumerate);
367 udev_enumerate_unref(udev_enumerate);
369 printf("enumerate 'pci, mem, vc'\n");
370 udev_enumerate = udev_enumerate_new(udev);
371 if (udev_enumerate == NULL)
373 udev_enumerate_add_match_subsystem(udev_enumerate, "pci");
374 udev_enumerate_add_match_subsystem(udev_enumerate, "mem");
375 udev_enumerate_add_match_subsystem(udev_enumerate, "vc");
376 udev_enumerate_scan_devices(udev_enumerate);
377 test_enumerate_print_list(udev_enumerate);
378 udev_enumerate_unref(udev_enumerate);
380 printf("enumerate 'subsystem'\n");
381 udev_enumerate = udev_enumerate_new(udev);
382 if (udev_enumerate == NULL)
384 udev_enumerate_scan_subsystems(udev_enumerate);
385 test_enumerate_print_list(udev_enumerate);
386 udev_enumerate_unref(udev_enumerate);
388 printf("enumerate 'property IF_FS_*=filesystem'\n");
389 udev_enumerate = udev_enumerate_new(udev);
390 if (udev_enumerate == NULL)
392 udev_enumerate_add_match_property(udev_enumerate, "ID_FS*", "filesystem");
393 udev_enumerate_scan_devices(udev_enumerate);
394 test_enumerate_print_list(udev_enumerate);
395 udev_enumerate_unref(udev_enumerate);
399 static void test_hwdb(struct udev *udev, const char *modalias) {
400 struct udev_hwdb *hwdb;
401 struct udev_list_entry *entry;
403 hwdb = udev_hwdb_new(udev);
405 udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
406 printf("'%s'='%s'\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
409 hwdb = udev_hwdb_unref(hwdb);
410 assert(hwdb == NULL);
413 int main(int argc, char *argv[]) {
414 struct udev *udev = NULL;
415 static const struct option options[] = {
416 { "syspath", required_argument, NULL, 'p' },
417 { "subsystem", required_argument, NULL, 's' },
418 { "debug", no_argument, NULL, 'd' },
419 { "help", no_argument, NULL, 'h' },
420 { "version", no_argument, NULL, 'V' },
423 const char *syspath = "/devices/virtual/mem/null";
424 const char *subsystem = NULL;
429 printf("context: %p\n", udev);
431 printf("no context\n");
434 udev_set_log_fn(udev, log_fn);
435 printf("set log: %p\n", log_fn);
438 while ((c = getopt_long(argc, argv, "p:s:dhV", options, NULL)) >= 0)
450 if (udev_get_log_priority(udev) < LOG_INFO)
451 udev_set_log_priority(udev, LOG_INFO);
455 printf("--debug --syspath= --subsystem= --help\n");
459 printf("%s\n", VERSION);
466 assert_not_reached("Unhandled option code.");
470 /* add sys path if needed */
471 if (!startswith(syspath, "/sys")) {
472 snprintf(path, sizeof(path), "/sys/%s", syspath);
476 test_device(udev, syspath);
477 test_device_devnum(udev);
478 test_device_subsys_name(udev);
479 test_device_parents(udev, syspath);
481 test_enumerate(udev, subsystem);
485 test_hwdb(udev, "usb:v0D50p0011*");