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