chiark / gitweb /
libudev: pass udev_device in enumerate
[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 "config.h"
21
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <getopt.h>
28 #include <syslog.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 int print_devlinks_cb(struct udev_device *udev_device, const char *value, void *data)
42 {
43         printf("link:      '%s'\n", value);
44         return 0;
45 }
46
47 static int print_properties_cb(struct udev_device *udev_device, const char *key, const char *value, void *data)
48 {
49         printf("property:  '%s=%s'\n", key, value);
50         return 0;
51 }
52
53 static void print_device(struct udev_device *device)
54 {
55         const char *str;
56         int count;
57
58         printf("*** device: %p ***\n", device);
59         str = udev_device_get_action(device);
60         printf("action:    '%s'\n", str);
61         str = udev_device_get_syspath(device);
62         printf("syspath:   '%s'\n", str);
63         str = udev_device_get_devpath(device);
64         printf("devpath:   '%s'\n", str);
65         str = udev_device_get_subsystem(device);
66         printf("subsystem: '%s'\n", str);
67         str = udev_device_get_driver(device);
68         printf("driver:    '%s'\n", str);
69         str = udev_device_get_devname(device);
70         printf("devname:   '%s'\n", str);
71         count = udev_device_get_devlinks(device, print_devlinks_cb, NULL);
72         printf("found %i links\n", count);
73         count = udev_device_get_properties(device, print_properties_cb, NULL);
74         printf("found %i properties\n", count);
75         printf("\n");
76 }
77
78 static int test_device(struct udev *udev, const char *syspath)
79 {
80         struct udev_device *device;
81
82         printf("looking at device: %s\n", syspath);
83         device = udev_device_new_from_syspath(udev, syspath);
84         if (device == NULL) {
85                 printf("no device\n");
86                 return -1;
87         }
88         print_device(device);
89         udev_device_unref(device);
90         return 0;
91 }
92
93 static int test_device_parents(struct udev *udev, const char *syspath)
94 {
95         struct udev_device *device;
96         struct udev_device *device_parent;
97
98         printf("looking at device: %s\n", syspath);
99         device = udev_device_new_from_syspath(udev, syspath);
100         if (device == NULL)
101                 return -1;
102
103         device_parent = device;
104         do {
105                 print_device(device_parent);
106                 device_parent = udev_device_get_parent(device_parent);
107         } while (device_parent != NULL);
108
109         device_parent = device;
110         do {
111                 print_device(device_parent);
112                 device_parent = udev_device_get_parent(device_parent);
113         } while (device_parent != NULL);
114         udev_device_unref(device);
115
116         return 0;
117 }
118
119 static int devices_enum_cb(struct udev_device *device, void *data)
120 {
121         printf("device:    '%s' (%s) '%s'\n",
122                udev_device_get_syspath(device),
123                udev_device_get_subsystem(device),
124                udev_device_get_sysname(device));
125         return 0;
126 }
127
128 static int test_enumerate(struct udev *udev, const char *subsystem)
129 {
130         int count;
131
132         count = udev_enumerate_devices(udev, subsystem, devices_enum_cb, NULL);
133         printf("found %i devices\n\n", count);
134         return count;
135 }
136
137 static int test_monitor(struct udev *udev, const char *socket_path)
138 {
139         struct udev_monitor *udev_monitor;
140         fd_set readfds;
141         int fd;
142
143         udev_monitor = udev_monitor_new_from_socket(udev, socket_path);
144         if (udev_monitor == NULL) {
145                 printf("no socket\n");
146                 return -1;
147         }
148         if (udev_monitor_enable_receiving(udev_monitor) < 0) {
149                 printf("bind failed\n");
150                 return -1;
151         }
152
153         fd = udev_monitor_get_fd(udev_monitor);
154         FD_ZERO(&readfds);
155
156         while (1) {
157                 struct udev_device *device;
158                 int fdcount;
159
160                 FD_SET(STDIN_FILENO, &readfds);
161                 FD_SET(fd, &readfds);
162
163                 printf("waiting for events on %s, press ENTER to exit\n", socket_path);
164                 fdcount = select(fd+1, &readfds, NULL, NULL, NULL);
165                 printf("select fd count: %i\n", fdcount);
166
167                 if (FD_ISSET(fd, &readfds)) {
168                         device = udev_monitor_receive_device(udev_monitor);
169                         if (device == NULL) {
170                                 printf("no device from socket\n");
171                                 continue;
172                         }
173                         print_device(device);
174                         udev_device_unref(device);
175                 }
176
177                 if (FD_ISSET(STDIN_FILENO, &readfds)) {
178                         printf("exiting loop\n");
179                         break;
180                 }
181         }
182
183         udev_monitor_unref(udev_monitor);
184         return 0;
185 }
186
187 int main(int argc, char *argv[], char *envp[])
188 {
189         struct udev *udev = NULL;
190         static const struct option options[] = {
191                 { "syspath", 1, NULL, 'p' },
192                 { "subsystem", 1, NULL, 's' },
193                 { "socket", 1, NULL, 'S' },
194                 { "debug", 0, NULL, 'd' },
195                 { "help", 0, NULL, 'h' },
196                 { "version", 0, NULL, 'V' },
197                 {}
198         };
199         const char *syspath = "/devices/virtual/mem/null";
200         const char *subsystem = NULL;
201         const char *socket = "@/org/kernel/udev/monitor";
202         char path[1024];
203         const char *str;
204
205         udev = udev_new();
206         printf("context: %p\n", udev);
207         if (udev == NULL) {
208                 printf("no context\n");
209                 return 1;
210         }
211         udev_set_log_fn(udev, log_fn);
212         printf("set log: %p\n", log_fn);
213
214         while (1) {
215                 int option;
216
217                 option = getopt_long(argc, argv, "+dhV", options, NULL);
218                 if (option == -1)
219                         break;
220
221                 switch (option) {
222                 case 'p':
223                         syspath = optarg;
224                         break;
225                 case 's':
226                         subsystem = optarg;
227                         break;
228                 case 'S':
229                         socket = optarg;
230                         break;
231                 case 'd':
232                         if (udev_get_log_priority(udev) < LOG_INFO)
233                                 udev_set_log_priority(udev, LOG_INFO);
234                         break;
235                 case 'h':
236                         printf("--debug --syspath= --subsystem= --socket= --help\n");
237                         goto out;
238                 case 'V':
239                         printf("%s\n", VERSION);
240                         goto out;
241                 default:
242                         goto out;
243                 }
244         }
245
246         str = udev_get_sys_path(udev);
247         printf("sys_path: '%s'\n", str);
248         str = udev_get_dev_path(udev);
249         printf("dev_path: '%s'\n", str);
250
251         /* add sys path if needed */
252         if (strncmp(syspath, udev_get_sys_path(udev), strlen(udev_get_sys_path(udev))) != 0) {
253                 snprintf(path, sizeof(path), "%s%s", udev_get_sys_path(udev), syspath);
254                 syspath = path;
255         }
256
257         test_device(udev, syspath);
258         test_device_parents(udev, syspath);
259         test_enumerate(udev, subsystem);
260         test_monitor(udev, socket);
261 out:
262         udev_unref(udev);
263         return 0;
264 }