chiark / gitweb /
65d84159cea5cefb68bd1d5a27508499205f265c
[elogind.git] / udev / lib / test-libudev.c
1 /*
2  * test-libudev
3  *
4  * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <getopt.h>
27 #include <syslog.h>
28 #include <fcntl.h>
29 #include <sys/select.h>
30
31 #include "libudev.h"
32
33 static void log_fn(struct udev *udev,
34                    int priority, const char *file, int line, const char *fn,
35                    const char *format, va_list args)
36 {
37         printf("test-libudev: %s %s:%d ", fn, file, line);
38         vprintf(format, args);
39 }
40
41 static void print_device(struct udev_device *device)
42 {
43         const char *str;
44         dev_t devnum;
45         int count;
46         struct udev_list_entry *list_entry;
47
48         printf("*** device: %p ***\n", device);
49         str = udev_device_get_action(device);
50         if (str != NULL)
51                 printf("action:    '%s'\n", str);
52
53         str = udev_device_get_syspath(device);
54         printf("syspath:   '%s'\n", str);
55
56         str = udev_device_get_devpath(device);
57         printf("devpath:   '%s'\n", str);
58
59         str = udev_device_get_subsystem(device);
60         if (str != NULL)
61                 printf("subsystem: '%s'\n", str);
62
63         str = udev_device_get_driver(device);
64         if (str != NULL)
65                 printf("driver:    '%s'\n", str);
66
67         str = udev_device_get_devnode(device);
68         if (str != NULL)
69                 printf("devname:   '%s'\n", str);
70
71         devnum = udev_device_get_devnum(device);
72         if (major(devnum) > 0)
73                 printf("devnum:    %u:%u\n", major(devnum), minor(devnum));
74
75         count = 0;
76         udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
77                 printf("link:      '%s'\n", udev_list_entry_get_name(list_entry));
78                 count++;
79         }
80         if (count > 0)
81                 printf("found %i links\n", count);
82
83         count = 0;
84         udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
85                 printf("property:  '%s=%s'\n",
86                        udev_list_entry_get_name(list_entry),
87                        udev_list_entry_get_value(list_entry));
88                 count++;
89         }
90         if (count > 0)
91                 printf("found %i properties\n", count);
92
93         str = udev_device_get_attr_value(device, "dev");
94         if (str != NULL)
95                 printf("attr{dev}: '%s'\n", str);
96
97         printf("\n");
98 }
99
100 static int test_device(struct udev *udev, const char *syspath)
101 {
102         struct udev_device *device;
103
104         printf("looking at device: %s\n", syspath);
105         device = udev_device_new_from_syspath(udev, syspath);
106         if (device == NULL) {
107                 printf("no device found\n");
108                 return -1;
109         }
110         print_device(device);
111         udev_device_unref(device);
112         return 0;
113 }
114
115 static int test_device_parents(struct udev *udev, const char *syspath)
116 {
117         struct udev_device *device;
118         struct udev_device *device_parent;
119
120         printf("looking at device: %s\n", syspath);
121         device = udev_device_new_from_syspath(udev, syspath);
122         if (device == NULL)
123                 return -1;
124
125         printf("looking at parents\n");
126         device_parent = device;
127         do {
128                 print_device(device_parent);
129                 device_parent = udev_device_get_parent(device_parent);
130         } while (device_parent != NULL);
131
132         printf("looking at parents again\n");
133         device_parent = device;
134         do {
135                 print_device(device_parent);
136                 device_parent = udev_device_get_parent(device_parent);
137         } while (device_parent != NULL);
138         udev_device_unref(device);
139
140         return 0;
141 }
142
143 static int test_device_devnum(struct udev *udev)
144 {
145         dev_t devnum = makedev(1, 3);
146         struct udev_device *device;
147
148         printf("looking up device: %u:%u\n", major(devnum), minor(devnum));
149         device = udev_device_new_from_devnum(udev, 'c', devnum);
150         if (device == NULL)
151                 return -1;
152         print_device(device);
153         udev_device_unref(device);
154         return 0;
155 }
156
157 static int test_device_subsys_name(struct udev *udev)
158 {
159         struct udev_device *device;
160
161         printf("looking up device: 'block':'sda'\n");
162         device = udev_device_new_from_subsystem_sysname(udev, "block", "sda");
163         if (device == NULL)
164                 return -1;
165         print_device(device);
166         udev_device_unref(device);
167
168         printf("looking up device: 'subsystem':'pci'\n");
169         device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
170         if (device == NULL)
171                 return -1;
172         print_device(device);
173         udev_device_unref(device);
174
175         printf("looking up device: 'drivers':'scsi:sd'\n");
176         device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd");
177         if (device == NULL)
178                 return -1;
179         print_device(device);
180         udev_device_unref(device);
181
182         printf("looking up device: 'module':'printk'\n");
183         device = udev_device_new_from_subsystem_sysname(udev, "module", "printk");
184         if (device == NULL)
185                 return -1;
186         print_device(device);
187         udev_device_unref(device);
188         return 0;
189 }
190
191 static int test_enumerate_print_list(struct udev_enumerate *enumerate)
192 {
193         struct udev_list_entry *list_entry;
194         int count = 0;
195
196         udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
197                 struct udev_device *device;
198
199                 device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
200                                                       udev_list_entry_get_name(list_entry));
201                 if (device != NULL) {
202                         printf("device: '%s' (%s)\n",
203                                udev_device_get_syspath(device),
204                                udev_device_get_subsystem(device));
205                         udev_device_unref(device);
206                         count++;
207                 }
208         }
209         printf("found %i devices\n\n", count);
210         return count;
211 }
212
213 static int test_monitor(struct udev *udev, const char *socket_path)
214 {
215         struct udev_monitor *udev_monitor;
216         fd_set readfds;
217         int fd;
218
219         udev_monitor = udev_monitor_new_from_socket(udev, socket_path);
220         if (udev_monitor == NULL) {
221                 printf("no socket\n");
222                 return -1;
223         }
224         if (udev_monitor_enable_receiving(udev_monitor) < 0) {
225                 printf("bind failed\n");
226                 return -1;
227         }
228
229         fd = udev_monitor_get_fd(udev_monitor);
230         FD_ZERO(&readfds);
231
232         while (1) {
233                 struct udev_device *device;
234                 int fdcount;
235
236                 FD_SET(STDIN_FILENO, &readfds);
237                 FD_SET(fd, &readfds);
238
239                 printf("waiting for events on %s, press ENTER to exit\n", socket_path);
240                 fdcount = select(fd+1, &readfds, NULL, NULL, NULL);
241                 printf("select fd count: %i\n", fdcount);
242
243                 if (FD_ISSET(fd, &readfds)) {
244                         device = udev_monitor_receive_device(udev_monitor);
245                         if (device == NULL) {
246                                 printf("no device from socket\n");
247                                 continue;
248                         }
249                         print_device(device);
250                         udev_device_unref(device);
251                 }
252
253                 if (FD_ISSET(STDIN_FILENO, &readfds)) {
254                         printf("exiting loop\n");
255                         break;
256                 }
257         }
258
259         udev_monitor_unref(udev_monitor);
260         return 0;
261 }
262
263 static int test_queue(struct udev *udev)
264 {
265         struct udev_queue *udev_queue;
266         unsigned long long int seqnum;
267         struct udev_list_entry *list_entry;
268
269         udev_queue = udev_queue_new(udev);
270         if (udev_queue == NULL)
271                 return -1;
272         seqnum = udev_queue_get_kernel_seqnum(udev_queue);
273         printf("seqnum kernel: %llu\n", seqnum);
274         seqnum = udev_queue_get_udev_seqnum(udev_queue);
275         printf("seqnum udev  : %llu\n", seqnum);
276
277         if (udev_queue_get_queue_is_empty(udev_queue))
278                 printf("queue is empty\n");
279         printf("get queue list\n");
280         udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
281                 printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
282         printf("\n");
283         printf("get queue list again\n");
284         udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
285                 printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
286         printf("\n");
287         printf("get failed list\n");
288         udev_list_entry_foreach(list_entry, udev_queue_get_failed_list_entry(udev_queue))
289                 printf("failed: '%s'\n", udev_list_entry_get_name(list_entry));
290         printf("\n");
291
292         list_entry = udev_queue_get_queued_list_entry(udev_queue);
293         if (list_entry != NULL) {
294                 printf("event [%llu] is queued\n", seqnum);
295                 seqnum = strtoull(udev_list_entry_get_value(list_entry), NULL, 10);
296                 if (udev_queue_get_seqnum_is_finished(udev_queue, seqnum))
297                         printf("event [%llu] is not finished\n", seqnum);
298                 else
299                         printf("event [%llu] is finished\n", seqnum);
300         }
301         printf("\n");
302         udev_queue_unref(udev_queue);
303         return 0;
304 }
305
306 static int test_enumerate(struct udev *udev, const char *subsystem)
307 {
308         struct udev_enumerate *udev_enumerate;
309
310         printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem);
311         udev_enumerate = udev_enumerate_new(udev);
312         if (udev_enumerate == NULL)
313                 return -1;
314         udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
315         udev_enumerate_scan_devices(udev_enumerate);
316         test_enumerate_print_list(udev_enumerate);
317         udev_enumerate_unref(udev_enumerate);
318
319         printf("enumerate 'block'\n");
320         udev_enumerate = udev_enumerate_new(udev);
321         if (udev_enumerate == NULL)
322                 return -1;
323         udev_enumerate_add_match_subsystem(udev_enumerate,"block");
324         udev_enumerate_scan_devices(udev_enumerate);
325         test_enumerate_print_list(udev_enumerate);
326         udev_enumerate_unref(udev_enumerate);
327
328         printf("enumerate 'not block'\n");
329         udev_enumerate = udev_enumerate_new(udev);
330         if (udev_enumerate == NULL)
331                 return -1;
332         udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block");
333         udev_enumerate_scan_devices(udev_enumerate);
334         test_enumerate_print_list(udev_enumerate);
335         udev_enumerate_unref(udev_enumerate);
336
337         printf("enumerate 'pci, mem, vc'\n");
338         udev_enumerate = udev_enumerate_new(udev);
339         if (udev_enumerate == NULL)
340                 return -1;
341         udev_enumerate_add_match_subsystem(udev_enumerate, "pci");
342         udev_enumerate_add_match_subsystem(udev_enumerate, "mem");
343         udev_enumerate_add_match_subsystem(udev_enumerate, "vc");
344         udev_enumerate_scan_devices(udev_enumerate);
345         test_enumerate_print_list(udev_enumerate);
346         udev_enumerate_unref(udev_enumerate);
347
348         printf("enumerate 'subsystem'\n");
349         udev_enumerate = udev_enumerate_new(udev);
350         if (udev_enumerate == NULL)
351                 return -1;
352         udev_enumerate_scan_subsystems(udev_enumerate);
353         test_enumerate_print_list(udev_enumerate);
354         udev_enumerate_unref(udev_enumerate);
355         return 0;
356 }
357
358 int main(int argc, char *argv[])
359 {
360         struct udev *udev = NULL;
361         static const struct option options[] = {
362                 { "syspath", required_argument, NULL, 'p' },
363                 { "subsystem", required_argument, NULL, 's' },
364                 { "socket", required_argument, NULL, 'S' },
365                 { "debug", no_argument, NULL, 'd' },
366                 { "help", no_argument, NULL, 'h' },
367                 { "version", no_argument, NULL, 'V' },
368                 {}
369         };
370         const char *syspath = "/devices/virtual/mem/null";
371         const char *subsystem = NULL;
372         const char *socket = "@/org/kernel/udev/monitor";
373         char path[1024];
374         const char *str;
375
376         udev = udev_new();
377         printf("context: %p\n", udev);
378         if (udev == NULL) {
379                 printf("no context\n");
380                 return 1;
381         }
382         udev_set_log_fn(udev, log_fn);
383         printf("set log: %p\n", log_fn);
384
385         while (1) {
386                 int option;
387
388                 option = getopt_long(argc, argv, "+dhV", options, NULL);
389                 if (option == -1)
390                         break;
391
392                 switch (option) {
393                 case 'p':
394                         syspath = optarg;
395                         break;
396                 case 's':
397                         subsystem = optarg;
398                         break;
399                 case 'S':
400                         socket = optarg;
401                         break;
402                 case 'd':
403                         if (udev_get_log_priority(udev) < LOG_INFO)
404                                 udev_set_log_priority(udev, LOG_INFO);
405                         break;
406                 case 'h':
407                         printf("--debug --syspath= --subsystem= --socket= --help\n");
408                         goto out;
409                 case 'V':
410                         printf("%s\n", VERSION);
411                         goto out;
412                 default:
413                         goto out;
414                 }
415         }
416
417         str = udev_get_sys_path(udev);
418         printf("sys_path: '%s'\n", str);
419         str = udev_get_dev_path(udev);
420         printf("dev_path: '%s'\n", str);
421
422         /* add sys path if needed */
423         if (strncmp(syspath, udev_get_sys_path(udev), strlen(udev_get_sys_path(udev))) != 0) {
424                 snprintf(path, sizeof(path), "%s%s", udev_get_sys_path(udev), syspath);
425                 syspath = path;
426         }
427
428         test_device(udev, syspath);
429         test_device_devnum(udev);
430         test_device_subsys_name(udev);
431         test_device_parents(udev, syspath);
432
433         test_enumerate(udev, subsystem);
434
435         test_queue(udev);
436
437         test_monitor(udev, socket);
438 out:
439         udev_unref(udev);
440         return 0;
441 }