]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-monitor.c
pkgconfig: define variables relative to ${prefix}/${rootprefix}/${sysconfdir}
[thirdparty/systemd.git] / src / libudev / libudev-monitor.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <poll.h>
5
6 #include "libudev.h"
7
8 #include "alloc-util.h"
9 #include "device-monitor-private.h"
10 #include "device-private.h"
11 #include "device-util.h"
12 #include "libudev-device-internal.h"
13 #include "libudev-private.h"
14 #include "string-util.h"
15
16 /**
17 * SECTION:libudev-monitor
18 * @short_description: device event source
19 *
20 * Connects to a device event source.
21 */
22
23 /**
24 * udev_monitor:
25 *
26 * Opaque object handling an event source.
27 */
28 struct udev_monitor {
29 struct udev *udev;
30 unsigned n_ref;
31 sd_device_monitor *monitor;
32 };
33
34 static MonitorNetlinkGroup monitor_netlink_group_from_string(const char *name) {
35 if (!name)
36 return MONITOR_GROUP_NONE;
37 if (streq(name, "udev"))
38 return MONITOR_GROUP_UDEV;
39 if (streq(name, "kernel"))
40 return MONITOR_GROUP_KERNEL;
41 return _MONITOR_NETLINK_GROUP_INVALID;
42 }
43
44 struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd) {
45 _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL;
46 _cleanup_(udev_monitor_unrefp) struct udev_monitor *udev_monitor = NULL;
47 MonitorNetlinkGroup g;
48 int r;
49
50 g = monitor_netlink_group_from_string(name);
51 if (g < 0) {
52 errno = EINVAL;
53 return NULL;
54 }
55
56 r = device_monitor_new_full(&m, g, fd);
57 if (r < 0) {
58 errno = -r;
59 return NULL;
60 }
61
62 udev_monitor = new(struct udev_monitor, 1);
63 if (!udev_monitor) {
64 errno = ENOMEM;
65 return NULL;
66 }
67
68 *udev_monitor = (struct udev_monitor) {
69 .udev = udev,
70 .n_ref = 1,
71 .monitor = TAKE_PTR(m),
72 };
73
74 return TAKE_PTR(udev_monitor);
75 }
76
77 /**
78 * udev_monitor_new_from_netlink:
79 * @udev: udev library context
80 * @name: name of event source
81 *
82 * Create new udev monitor and connect to a specified event
83 * source. Valid sources identifiers are "udev" and "kernel".
84 *
85 * Applications should usually not connect directly to the
86 * "kernel" events, because the devices might not be useable
87 * at that time, before udev has configured them, and created
88 * device nodes. Accessing devices at the same time as udev,
89 * might result in unpredictable behavior. The "udev" events
90 * are sent out after udev has finished its event processing,
91 * all rules have been processed, and needed device nodes are
92 * created.
93 *
94 * The initial refcount is 1, and needs to be decremented to
95 * release the resources of the udev monitor.
96 *
97 * Returns: a new udev monitor, or #NULL, in case of an error
98 **/
99 _public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name) {
100 return udev_monitor_new_from_netlink_fd(udev, name, -1);
101 }
102
103 /**
104 * udev_monitor_filter_update:
105 * @udev_monitor: monitor
106 *
107 * Update the installed socket filter. This is only needed,
108 * if the filter was removed or changed.
109 *
110 * Returns: 0 on success, otherwise a negative error value.
111 */
112 _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) {
113 assert_return(udev_monitor, -EINVAL);
114
115 return sd_device_monitor_filter_update(udev_monitor->monitor);
116 }
117
118 int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender) {
119 assert_return(udev_monitor, -EINVAL);
120 assert_return(sender, -EINVAL);
121
122 return device_monitor_allow_unicast_sender(udev_monitor->monitor, sender->monitor);
123 }
124
125 /**
126 * udev_monitor_enable_receiving:
127 * @udev_monitor: the monitor which should receive events
128 *
129 * Binds the @udev_monitor socket to the event source.
130 *
131 * Returns: 0 on success, otherwise a negative error value.
132 */
133 _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) {
134 assert_return(udev_monitor, -EINVAL);
135
136 return device_monitor_enable_receiving(udev_monitor->monitor);
137 }
138
139 /**
140 * udev_monitor_set_receive_buffer_size:
141 * @udev_monitor: the monitor which should receive events
142 * @size: the size in bytes
143 *
144 * Set the size of the kernel socket buffer. This call needs the
145 * appropriate privileges to succeed.
146 *
147 * Returns: 0 on success, otherwise -1 on error.
148 */
149 _public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size) {
150 assert_return(udev_monitor, -EINVAL);
151
152 return sd_device_monitor_set_receive_buffer_size(udev_monitor->monitor, (size_t) size);
153 }
154
155 int udev_monitor_disconnect(struct udev_monitor *udev_monitor) {
156 assert(udev_monitor);
157
158 return device_monitor_disconnect(udev_monitor->monitor);
159 }
160
161 static struct udev_monitor *udev_monitor_free(struct udev_monitor *udev_monitor) {
162 assert(udev_monitor);
163
164 sd_device_monitor_unref(udev_monitor->monitor);
165 return mfree(udev_monitor);
166 }
167
168 /**
169 * udev_monitor_ref:
170 * @udev_monitor: udev monitor
171 *
172 * Take a reference of a udev monitor.
173 *
174 * Returns: the passed udev monitor
175 **/
176
177 /**
178 * udev_monitor_unref:
179 * @udev_monitor: udev monitor
180 *
181 * Drop a reference of a udev monitor. If the refcount reaches zero,
182 * the bound socket will be closed, and the resources of the monitor
183 * will be released.
184 *
185 * Returns: #NULL
186 **/
187 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_monitor, udev_monitor, udev_monitor_free);
188
189 /**
190 * udev_monitor_get_udev:
191 * @udev_monitor: udev monitor
192 *
193 * Retrieve the udev library context the monitor was created with.
194 *
195 * Returns: the udev library context
196 **/
197 _public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) {
198 assert_return(udev_monitor, NULL);
199
200 return udev_monitor->udev;
201 }
202
203 /**
204 * udev_monitor_get_fd:
205 * @udev_monitor: udev monitor
206 *
207 * Retrieve the socket file descriptor associated with the monitor.
208 *
209 * Returns: the socket file descriptor
210 **/
211 _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) {
212 assert_return(udev_monitor, -EINVAL);
213
214 return device_monitor_get_fd(udev_monitor->monitor);
215 }
216
217 int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) {
218 struct pollfd pfd;
219 int r;
220
221 assert(udev_monitor);
222 assert(ret);
223
224 pfd = (struct pollfd) {
225 .fd = device_monitor_get_fd(udev_monitor->monitor),
226 .events = POLLIN,
227 };
228
229 for (;;) {
230 /* r == 0 means a device is received but it does not pass the current filter. */
231 r = device_monitor_receive_device(udev_monitor->monitor, ret);
232 if (r != 0)
233 return r;
234
235 for (;;) {
236 /* wait next message */
237 r = poll(&pfd, 1, 0);
238 if (r < 0) {
239 if (IN_SET(errno, EINTR, EAGAIN))
240 continue;
241
242 return -errno;
243 } else if (r == 0)
244 return -EAGAIN;
245
246 /* receive next message */
247 break;
248 }
249 }
250 }
251
252 /**
253 * udev_monitor_receive_device:
254 * @udev_monitor: udev monitor
255 *
256 * Receive data from the udev monitor socket, allocate a new udev
257 * device, fill in the received data, and return the device.
258 *
259 * Only socket connections with uid=0 are accepted.
260 *
261 * The monitor socket is by default set to NONBLOCK. A variant of poll() on
262 * the file descriptor returned by udev_monitor_get_fd() should to be used to
263 * wake up when new devices arrive, or alternatively the file descriptor
264 * switched into blocking mode.
265 *
266 * The initial refcount is 1, and needs to be decremented to
267 * release the resources of the udev device.
268 *
269 * Returns: a new udev device, or #NULL, in case of an error
270 **/
271 _public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor) {
272 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
273 int r;
274
275 assert_return(udev_monitor, NULL);
276
277 r = udev_monitor_receive_sd_device(udev_monitor, &device);
278 if (r < 0) {
279 errno = -r;
280 return NULL;
281 }
282
283 return udev_device_new(udev_monitor->udev, device);
284 }
285
286 int udev_monitor_send_device(
287 struct udev_monitor *udev_monitor,
288 struct udev_monitor *destination,
289 struct udev_device *udev_device) {
290 assert(udev_monitor);
291 assert(udev_device);
292
293 return device_monitor_send_device(udev_monitor->monitor,
294 destination ? destination->monitor : NULL,
295 udev_device->device);
296 }
297
298 /**
299 * udev_monitor_filter_add_match_subsystem_devtype:
300 * @udev_monitor: the monitor
301 * @subsystem: the subsystem value to match the incoming devices against
302 * @devtype: the devtype value to match the incoming devices against
303 *
304 * This filter is efficiently executed inside the kernel, and libudev subscribers
305 * will usually not be woken up for devices which do not match.
306 *
307 * The filter must be installed before the monitor is switched to listening mode.
308 *
309 * Returns: 0 on success, otherwise a negative error value.
310 */
311 _public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype) {
312 assert_return(udev_monitor, -EINVAL);
313
314 return sd_device_monitor_filter_add_match_subsystem_devtype(udev_monitor->monitor, subsystem, devtype);
315 }
316
317 /**
318 * udev_monitor_filter_add_match_tag:
319 * @udev_monitor: the monitor
320 * @tag: the name of a tag
321 *
322 * This filter is efficiently executed inside the kernel, and libudev subscribers
323 * will usually not be woken up for devices which do not match.
324 *
325 * The filter must be installed before the monitor is switched to listening mode.
326 *
327 * Returns: 0 on success, otherwise a negative error value.
328 */
329 _public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag) {
330 assert_return(udev_monitor, -EINVAL);
331
332 return sd_device_monitor_filter_add_match_tag(udev_monitor->monitor, tag);
333 }
334
335 /**
336 * udev_monitor_filter_remove:
337 * @udev_monitor: monitor
338 *
339 * Remove all filters from monitor.
340 *
341 * Returns: 0 on success, otherwise a negative error value.
342 */
343 _public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor) {
344 assert_return(udev_monitor, -EINVAL);
345
346 return sd_device_monitor_filter_remove(udev_monitor->monitor);
347 }