]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libudev/libudev-device.c
libudev: hide definition of struct udev_list from other libudev components
[thirdparty/systemd.git] / src / libudev / libudev-device.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
eb1f0e66 2
07630cea 3#include <ctype.h>
eb1f0e66 4#include <dirent.h>
07630cea 5#include <errno.h>
93b0f384 6#include <fcntl.h>
07630cea 7#include <linux/sockios.h>
3e0a2c9a 8#include <net/if.h>
07630cea
LP
9#include <stdbool.h>
10#include <stddef.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
3e0a2c9a
KS
14#include <sys/ioctl.h>
15#include <sys/socket.h>
07630cea
LP
16#include <sys/stat.h>
17#include <unistd.h>
eb1f0e66 18
b4bbcaa9 19#include "libudev.h"
f4ac4d1a 20#include "sd-device.h"
f4ac4d1a 21
b5efdb8a 22#include "alloc-util.h"
07630cea
LP
23#include "device-private.h"
24#include "device-util.h"
f4ac4d1a 25#include "libudev-device-internal.h"
6bedfcbb 26#include "parse-util.h"
5ea78a39 27#include "time-util.h"
b2661839 28
ce1d6d7f
KS
29/**
30 * SECTION:libudev-device
31 * @short_description: kernel sys devices
32 *
33 * Representation of kernel sys devices. Devices are uniquely identified
34 * by their syspath, every device has exactly one path in the kernel sys
5eec7de6 35 * filesystem. Devices usually belong to a kernel subsystem, and have
214a6c79 36 * a unique name inside that subsystem.
ce1d6d7f
KS
37 */
38
905555dc 39/**
a3321f68 40 * udev_device_get_seqnum:
905555dc
KS
41 * @udev_device: udev device
42 *
43 * This is only valid if the device was received through a monitor. Devices read from
44 * sys do not have a sequence number.
45 *
46 * Returns: the kernel event sequence number, or 0 if there is no sequence number available.
47 **/
40769ccc
YW
48_public_ unsigned long long udev_device_get_seqnum(struct udev_device *udev_device) {
49 uint64_t seqnum;
905555dc 50
f4ac4d1a 51 assert_return_errno(udev_device, 0, EINVAL);
905555dc 52
40769ccc 53 if (device_get_seqnum(udev_device->device, &seqnum) < 0)
f4ac4d1a 54 return 0;
905555dc 55
40769ccc 56 return seqnum;
905555dc
KS
57}
58
59/**
60 * udev_device_get_devnum:
61 * @udev_device: udev device
62 *
21dbe43a
KS
63 * Get the device major/minor number.
64 *
65 * Returns: the dev_t number.
905555dc 66 **/
76387b9a 67_public_ dev_t udev_device_get_devnum(struct udev_device *udev_device) {
f4ac4d1a
TG
68 dev_t devnum;
69 int r;
905555dc 70
f4ac4d1a 71 assert_return_errno(udev_device, makedev(0, 0), EINVAL);
905555dc 72
f4ac4d1a 73 r = sd_device_get_devnum(udev_device->device, &devnum);
fd05c424 74 if (r == -ENOENT)
f4ac4d1a 75 return makedev(0, 0);
fd05c424
YW
76 if (r < 0)
77 return_with_errno(makedev(0, 0), r);
905555dc 78
f4ac4d1a 79 return devnum;
905555dc
KS
80}
81
82/**
83 * udev_device_get_driver:
84 * @udev_device: udev device
85 *
21dbe43a
KS
86 * Get the kernel driver name.
87 *
88 * Returns: the driver name string, or #NULL if there is no driver attached.
905555dc 89 **/
76387b9a 90_public_ const char *udev_device_get_driver(struct udev_device *udev_device) {
f4ac4d1a
TG
91 const char *driver;
92 int r;
93
94 assert_return_errno(udev_device, NULL, EINVAL);
905555dc 95
f4ac4d1a 96 r = sd_device_get_driver(udev_device->device, &driver);
fd05c424
YW
97 if (r < 0)
98 return_with_errno(NULL, r);
905555dc 99
f4ac4d1a 100 return driver;
905555dc
KS
101}
102
103/**
104 * udev_device_get_devtype:
105 * @udev_device: udev device
106 *
107 * Retrieve the devtype string of the udev device.
108 *
87ac8d99 109 * Returns: the devtype name of the udev device, or #NULL if it cannot be determined
905555dc 110 **/
76387b9a 111_public_ const char *udev_device_get_devtype(struct udev_device *udev_device) {
f4ac4d1a
TG
112 const char *devtype;
113 int r;
114
115 assert_return_errno(udev_device, NULL, EINVAL);
116
117 r = sd_device_get_devtype(udev_device->device, &devtype);
fd05c424 118 if (r == -ENOENT)
912541b0 119 return NULL;
fd05c424
YW
120 if (r < 0)
121 return_with_errno(NULL, r);
905555dc 122
f4ac4d1a 123 return devtype;
905555dc
KS
124}
125
126/**
127 * udev_device_get_subsystem:
128 * @udev_device: udev device
129 *
130 * Retrieve the subsystem string of the udev device. The string does not
131 * contain any "/".
132 *
87ac8d99 133 * Returns: the subsystem name of the udev device, or #NULL if it cannot be determined
905555dc 134 **/
76387b9a 135_public_ const char *udev_device_get_subsystem(struct udev_device *udev_device) {
f4ac4d1a
TG
136 const char *subsystem;
137 int r;
df546eb5 138
f4ac4d1a 139 assert_return_errno(udev_device, NULL, EINVAL);
fc8d61c5 140
f4ac4d1a 141 r = sd_device_get_subsystem(udev_device->device, &subsystem);
fd05c424
YW
142 if (r < 0)
143 return_with_errno(NULL, r);
fc8d61c5 144
f4ac4d1a 145 return subsystem;
fc8d61c5
KS
146}
147
148/**
149 * udev_device_get_property_value:
150 * @udev_device: udev device
151 * @key: property name
152 *
21dbe43a
KS
153 * Get the value of a given property.
154 *
155 * Returns: the property string, or #NULL if there is no such property.
fc8d61c5 156 **/
76387b9a 157_public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key) {
fd05c424 158 const char *value;
f4ac4d1a 159 int r;
912541b0 160
f4ac4d1a 161 assert_return_errno(udev_device && key, NULL, EINVAL);
912541b0 162
f4ac4d1a 163 r = sd_device_get_property_value(udev_device->device, key, &value);
fd05c424
YW
164 if (r < 0)
165 return_with_errno(NULL, r);
912541b0 166
f4ac4d1a 167 return value;
99214844
KS
168}
169
02e7ae2f 170struct udev_device *udev_device_new(struct udev *udev, sd_device *device) {
dcf557f7 171 _cleanup_(udev_list_freep) struct udev_list *properties = NULL, *tags = NULL, *sysattrs = NULL, *devlinks = NULL;
912541b0 172 struct udev_device *udev_device;
912541b0 173
02e7ae2f
YW
174 assert(device);
175
dcf557f7
YW
176 properties = udev_list_new(true);
177 if (!properties)
178 return_with_errno(NULL, ENOMEM);
179 tags = udev_list_new(true);
180 if (!tags)
181 return_with_errno(NULL, ENOMEM);
182 sysattrs = udev_list_new(true);
183 if (!sysattrs)
184 return_with_errno(NULL, ENOMEM);
185 devlinks = udev_list_new(true);
186 if (!devlinks)
187 return_with_errno(NULL, ENOMEM);
188
71074e3a 189 udev_device = new(struct udev_device, 1);
fd05c424
YW
190 if (!udev_device)
191 return_with_errno(NULL, ENOMEM);
71074e3a
YW
192
193 *udev_device = (struct udev_device) {
194 .n_ref = 1,
195 .udev = udev,
02e7ae2f 196 .device = sd_device_ref(device),
dcf557f7
YW
197 .properties = TAKE_PTR(properties),
198 .tags = TAKE_PTR(tags),
199 .sysattrs = TAKE_PTR(sysattrs),
200 .devlinks = TAKE_PTR(devlinks),
71074e3a
YW
201 };
202
912541b0 203 return udev_device;
eb1f0e66
KS
204}
205
206/**
8753fadf 207 * udev_device_new_from_syspath:
eb1f0e66 208 * @udev: udev library context
8753fadf 209 * @syspath: sys device path including sys directory
eb1f0e66 210 *
8753fadf 211 * Create new udev device, and fill in information from the sys
214a6c79 212 * device and the udev database entry. The syspath is the absolute
8753fadf 213 * path to the device, including the sys mount point.
eb1f0e66
KS
214 *
215 * The initial refcount is 1, and needs to be decremented to
be7de409 216 * release the resources of the udev device.
eb1f0e66
KS
217 *
218 * Returns: a new udev device, or #NULL, if it does not exist
219 **/
f4ac4d1a 220_public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath) {
02e7ae2f 221 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a 222 int r;
912541b0 223
02e7ae2f 224 r = sd_device_new_from_syspath(&device, syspath);
fd05c424
YW
225 if (r < 0)
226 return_with_errno(NULL, r);
912541b0 227
02e7ae2f 228 return udev_device_new(udev, device);
eb1f0e66
KS
229}
230
1e511322
KS
231/**
232 * udev_device_new_from_devnum:
233 * @udev: udev library context
234 * @type: char or block device
235 * @devnum: device major/minor number
236 *
237 * Create new udev device, and fill in information from the sys
dbba7e40
KS
238 * device and the udev database entry. The device is looked-up
239 * by its major/minor number and type. Character and block device
240 * numbers are not unique across the two types.
1e511322
KS
241 *
242 * The initial refcount is 1, and needs to be decremented to
243 * release the resources of the udev device.
244 *
245 * Returns: a new udev device, or #NULL, if it does not exist
246 **/
76387b9a 247_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) {
02e7ae2f 248 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a
TG
249 int r;
250
02e7ae2f 251 r = sd_device_new_from_devnum(&device, type, devnum);
fd05c424
YW
252 if (r < 0)
253 return_with_errno(NULL, r);
4c9dff47 254
02e7ae2f 255 return udev_device_new(udev, device);
4c9dff47
KS
256}
257
dbf61afb
KS
258/**
259 * udev_device_new_from_device_id:
260 * @udev: udev library context
261 * @id: text string identifying a kernel device
262 *
263 * Create new udev device, and fill in information from the sys
264 * device and the udev database entry. The device is looked-up
265 * by a special string:
266 * b8:2 - block device major:minor
267 * c128:1 - char device major:minor
268 * n3 - network device ifindex
269 * +sound:card29 - kernel driver core subsystem:device name
270 *
271 * The initial refcount is 1, and needs to be decremented to
272 * release the resources of the udev device.
273 *
274 * Returns: a new udev device, or #NULL, if it does not exist
275 **/
76387b9a 276_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id) {
02e7ae2f 277 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a
TG
278 int r;
279
02e7ae2f 280 r = sd_device_new_from_device_id(&device, id);
fd05c424
YW
281 if (r < 0)
282 return_with_errno(NULL, r);
f4ac4d1a 283
02e7ae2f 284 return udev_device_new(udev, device);
cad40a5f
KS
285}
286
1e511322
KS
287/**
288 * udev_device_new_from_subsystem_sysname:
289 * @udev: udev library context
214a6c79 290 * @subsystem: the subsystem of the device
1e511322
KS
291 * @sysname: the name of the device
292 *
dbba7e40
KS
293 * Create new udev device, and fill in information from the sys device
294 * and the udev database entry. The device is looked up by the subsystem
295 * and name string of the device, like "mem" / "zero", or "block" / "sda".
1e511322
KS
296 *
297 * The initial refcount is 1, and needs to be decremented to
298 * release the resources of the udev device.
299 *
300 * Returns: a new udev device, or #NULL, if it does not exist
301 **/
76387b9a 302_public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) {
02e7ae2f 303 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a 304 int r;
912541b0 305
02e7ae2f 306 r = sd_device_new_from_subsystem_sysname(&device, subsystem, sysname);
fd05c424
YW
307 if (r < 0)
308 return_with_errno(NULL, r);
912541b0 309
02e7ae2f 310 return udev_device_new(udev, device);
90d80c2e
KS
311}
312
fc8d61c5
KS
313/**
314 * udev_device_new_from_environment
315 * @udev: udev library context
316 *
317 * Create new udev device, and fill in information from the
318 * current process environment. This only works reliable if
319 * the process is called from a udev rule. It is usually used
320 * for tools executed from IMPORT= rules.
321 *
322 * The initial refcount is 1, and needs to be decremented to
323 * release the resources of the udev device.
324 *
325 * Returns: a new udev device, or #NULL, if it does not exist
326 **/
76387b9a 327_public_ struct udev_device *udev_device_new_from_environment(struct udev *udev) {
02e7ae2f 328 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a 329 int r;
fc8d61c5 330
02e7ae2f 331 r = device_new_from_strv(&device, environ);
fd05c424
YW
332 if (r < 0)
333 return_with_errno(NULL, r);
fc8d61c5 334
02e7ae2f 335 return udev_device_new(udev, device);
fc8d61c5
KS
336}
337
76387b9a 338static struct udev_device *device_new_from_parent(struct udev_device *child) {
02e7ae2f 339 sd_device *parent;
f4ac4d1a
TG
340 int r;
341
342 assert_return_errno(child, NULL, EINVAL);
343
02e7ae2f 344 r = sd_device_get_parent(child->device, &parent);
fd05c424
YW
345 if (r < 0)
346 return_with_errno(NULL, r);
aa0e72ea 347
02e7ae2f 348 return udev_device_new(child->udev, parent);
4ad3a37f
KS
349}
350
1e511322
KS
351/**
352 * udev_device_get_parent:
353 * @udev_device: the device to start searching from
354 *
355 * Find the next parent device, and fill in information from the sys
356 * device and the udev database entry.
357 *
572ce4f7
ZJS
358 * Returned device is not referenced. It is attached to the child
359 * device, and will be cleaned up when the child device is cleaned up.
1e511322 360 *
214a6c79 361 * It is not necessarily just the upper level directory, empty or not
1e511322
KS
362 * recognized sys directories are ignored.
363 *
364 * It can be called as many times as needed, without caring about
365 * references.
366 *
367 * Returns: a new udev device, or #NULL, if it no parent exist.
368 **/
76387b9a 369_public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device) {
f4ac4d1a
TG
370 assert_return_errno(udev_device, NULL, EINVAL);
371
912541b0
KS
372 if (!udev_device->parent_set) {
373 udev_device->parent_set = true;
f4ac4d1a 374 udev_device->parent = device_new_from_parent(udev_device);
912541b0 375 }
f4ac4d1a
TG
376
377 /* TODO: errno will differ here in case parent == NULL */
378 return udev_device->parent;
b2d9e4f2
KS
379}
380
1e511322
KS
381/**
382 * udev_device_get_parent_with_subsystem_devtype:
383 * @udev_device: udev device to start searching from
214a6c79 384 * @subsystem: the subsystem of the device
1e511322
KS
385 * @devtype: the type (DEVTYPE) of the device
386 *
387 * Find the next parent device, with a matching subsystem and devtype
388 * value, and fill in information from the sys device and the udev
389 * database entry.
390 *
79ef2e97 391 * If devtype is #NULL, only subsystem is checked, and any devtype will
54d4f54e
MP
392 * match.
393 *
572ce4f7
ZJS
394 * Returned device is not referenced. It is attached to the child
395 * device, and will be cleaned up when the child device is cleaned up.
1e511322
KS
396 *
397 * It can be called as many times as needed, without caring about
398 * references.
399 *
8d6bc73a 400 * Returns: a new udev device, or #NULL if no matching parent exists.
1e511322 401 **/
76387b9a 402_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype) {
f4ac4d1a
TG
403 sd_device *parent;
404 int r;
bf8b2ae1 405
f4ac4d1a
TG
406 assert_return_errno(udev_device, NULL, EINVAL);
407
408 /* this relies on the fact that finding the subdevice of a parent or the
409 parent of a subdevice commute */
410
411 /* first find the correct sd_device */
412 r = sd_device_get_parent_with_subsystem_devtype(udev_device->device, subsystem, devtype, &parent);
fd05c424
YW
413 if (r < 0)
414 return_with_errno(NULL, r);
883012d4 415
bbb04088 416 /* then walk the chain of udev_device parents until the corresponding
f4ac4d1a 417 one is found */
fd05c424 418 while ((udev_device = udev_device_get_parent(udev_device)))
f4ac4d1a
TG
419 if (udev_device->device == parent)
420 return udev_device;
aa0e72ea 421
fd05c424 422 return_with_errno(NULL, ENOENT);
bf8b2ae1
MH
423}
424
eb1f0e66
KS
425/**
426 * udev_device_get_udev:
7d8787b3 427 * @udev_device: udev device
eb1f0e66
KS
428 *
429 * Retrieve the udev library context the device was created with.
430 *
431 * Returns: the udev library context
432 **/
76387b9a 433_public_ struct udev *udev_device_get_udev(struct udev_device *udev_device) {
f4ac4d1a
TG
434 assert_return_errno(udev_device, NULL, EINVAL);
435
912541b0 436 return udev_device->udev;
eb1f0e66
KS
437}
438
3c6ac219
YW
439static struct udev_device *udev_device_free(struct udev_device *udev_device) {
440 assert(udev_device);
441
442 sd_device_unref(udev_device->device);
443 udev_device_unref(udev_device->parent);
444
dcf557f7
YW
445 udev_list_free(udev_device->properties);
446 udev_list_free(udev_device->sysattrs);
447 udev_list_free(udev_device->tags);
448 udev_list_free(udev_device->devlinks);
3c6ac219
YW
449
450 return mfree(udev_device);
451}
452
eb1f0e66
KS
453/**
454 * udev_device_ref:
455 * @udev_device: udev device
456 *
457 * Take a reference of a udev device.
458 *
459 * Returns: the passed udev device
460 **/
eb1f0e66
KS
461
462/**
463 * udev_device_unref:
464 * @udev_device: udev device
465 *
466 * Drop a reference of a udev device. If the refcount reaches zero,
be7de409 467 * the resources of the device will be released.
eb1f0e66 468 *
725d7e6c 469 * Returns: #NULL
eb1f0e66 470 **/
3c6ac219 471DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_device, udev_device, udev_device_free);
eb1f0e66
KS
472
473/**
474 * udev_device_get_devpath:
475 * @udev_device: udev device
476 *
11d543c1
KS
477 * Retrieve the kernel devpath value of the udev device. The path
478 * does not contain the sys mount point, and starts with a '/'.
eb1f0e66 479 *
11d543c1 480 * Returns: the devpath of the udev device
eb1f0e66 481 **/
76387b9a 482_public_ const char *udev_device_get_devpath(struct udev_device *udev_device) {
f4ac4d1a
TG
483 const char *devpath;
484 int r;
485
486 assert_return_errno(udev_device, NULL, EINVAL);
487
488 r = sd_device_get_devpath(udev_device->device, &devpath);
fd05c424
YW
489 if (r < 0)
490 return_with_errno(NULL, r);
f4ac4d1a
TG
491
492 return devpath;
eb1f0e66
KS
493}
494
11d543c1
KS
495/**
496 * udev_device_get_syspath:
497 * @udev_device: udev device
498 *
499 * Retrieve the sys path of the udev device. The path is an
500 * absolute path and starts with the sys mount point.
501 *
502 * Returns: the sys path of the udev device
503 **/
76387b9a 504_public_ const char *udev_device_get_syspath(struct udev_device *udev_device) {
f4ac4d1a
TG
505 const char *syspath;
506 int r;
507
508 assert_return_errno(udev_device, NULL, EINVAL);
509
510 r = sd_device_get_syspath(udev_device->device, &syspath);
fd05c424
YW
511 if (r < 0)
512 return_with_errno(NULL, r);
f4ac4d1a
TG
513
514 return syspath;
11d543c1
KS
515}
516
1e511322
KS
517/**
518 * udev_device_get_sysname:
519 * @udev_device: udev device
520 *
21dbe43a
KS
521 * Get the kernel device name in /sys.
522 *
61233823 523 * Returns: the name string of the device
1e511322 524 **/
76387b9a 525_public_ const char *udev_device_get_sysname(struct udev_device *udev_device) {
f4ac4d1a
TG
526 const char *sysname;
527 int r;
528
529 assert_return_errno(udev_device, NULL, EINVAL);
530
531 r = sd_device_get_sysname(udev_device->device, &sysname);
fd05c424
YW
532 if (r < 0)
533 return_with_errno(NULL, r);
f4ac4d1a
TG
534
535 return sysname;
4ad3a37f
KS
536}
537
1e511322
KS
538/**
539 * udev_device_get_sysnum:
540 * @udev_device: udev device
541 *
21dbe43a
KS
542 * Get the instance number of the device.
543 *
c5315881 544 * Returns: the trailing number string of the device name
1e511322 545 **/
76387b9a 546_public_ const char *udev_device_get_sysnum(struct udev_device *udev_device) {
f4ac4d1a
TG
547 const char *sysnum;
548 int r;
549
550 assert_return_errno(udev_device, NULL, EINVAL);
551
552 r = sd_device_get_sysnum(udev_device->device, &sysnum);
fd05c424 553 if (r == -ENOENT)
912541b0 554 return NULL;
fd05c424
YW
555 if (r < 0)
556 return_with_errno(NULL, r);
f4ac4d1a
TG
557
558 return sysnum;
517814e7
KS
559}
560
eb1f0e66 561/**
fb762bb9 562 * udev_device_get_devnode:
eb1f0e66
KS
563 * @udev_device: udev device
564 *
565 * Retrieve the device node file name belonging to the udev device.
ba6929f6 566 * The path is an absolute path, and starts with the device directory.
eb1f0e66
KS
567 *
568 * Returns: the device node file name of the udev device, or #NULL if no device node exists
569 **/
76387b9a 570_public_ const char *udev_device_get_devnode(struct udev_device *udev_device) {
f4ac4d1a
TG
571 const char *devnode;
572 int r;
573
574 assert_return_errno(udev_device, NULL, EINVAL);
575
576 r = sd_device_get_devname(udev_device->device, &devnode);
fd05c424
YW
577 if (r < 0)
578 return_with_errno(NULL, r);
f4ac4d1a
TG
579
580 return devnode;
eb1f0e66
KS
581}
582
eb1f0e66 583/**
0de33a61 584 * udev_device_get_devlinks_list_entry:
eb1f0e66 585 * @udev_device: udev device
eb1f0e66 586 *
bf7ad0ea
KS
587 * Retrieve the list of device links pointing to the device file of
588 * the udev device. The next list entry can be retrieved with
bb061708 589 * udev_list_entry_get_next(), which returns #NULL if no more entries exist.
bf7ad0ea 590 * The devlink path can be retrieved from the list entry by
e345e267 591 * udev_list_entry_get_name(). The path is an absolute path, and starts with
bf7ad0ea 592 * the device directory.
eb1f0e66 593 *
bf7ad0ea 594 * Returns: the first entry of the device node link list
eb1f0e66 595 **/
76387b9a 596_public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device) {
f4ac4d1a 597 assert_return_errno(udev_device, NULL, EINVAL);
eb1f0e66 598
378f61eb
TG
599 if (device_get_devlinks_generation(udev_device->device) != udev_device->devlinks_generation ||
600 !udev_device->devlinks_read) {
f4ac4d1a
TG
601 const char *devlink;
602
dcf557f7 603 udev_list_cleanup(udev_device->devlinks);
f4ac4d1a
TG
604
605 FOREACH_DEVICE_DEVLINK(udev_device->device, devlink)
dcf557f7 606 if (!udev_list_entry_add(udev_device->devlinks, devlink, NULL))
3f14e721 607 return_with_errno(NULL, ENOMEM);
f4ac4d1a 608
378f61eb 609 udev_device->devlinks_read = true;
f4ac4d1a
TG
610 udev_device->devlinks_generation = device_get_devlinks_generation(udev_device->device);
611 }
612
dcf557f7 613 return udev_list_get_entry(udev_device->devlinks);
979ff016
KS
614}
615
eb1f0e66 616/**
f4ac4d1a 617 * udev_device_get_event_properties_entry:
eb1f0e66 618 * @udev_device: udev device
eb1f0e66 619 *
bf7ad0ea 620 * Retrieve the list of key/value device properties of the udev
bb061708 621 * device. The next list entry can be retrieved with udev_list_entry_get_next(),
bf7ad0ea 622 * which returns #NULL if no more entries exist. The property name
bb061708
KS
623 * can be retrieved from the list entry by udev_list_entry_get_name(),
624 * the property value by udev_list_entry_get_value().
eb1f0e66 625 *
bf7ad0ea 626 * Returns: the first entry of the property list
eb1f0e66 627 **/
76387b9a 628_public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device) {
f4ac4d1a
TG
629 assert_return_errno(udev_device, NULL, EINVAL);
630
378f61eb
TG
631 if (device_get_properties_generation(udev_device->device) != udev_device->properties_generation ||
632 !udev_device->properties_read) {
f4ac4d1a
TG
633 const char *key, *value;
634
dcf557f7 635 udev_list_cleanup(udev_device->properties);
f4ac4d1a
TG
636
637 FOREACH_DEVICE_PROPERTY(udev_device->device, key, value)
dcf557f7 638 if (!udev_list_entry_add(udev_device->properties, key, value))
3f14e721 639 return_with_errno(NULL, ENOMEM);
f4ac4d1a 640
378f61eb 641 udev_device->properties_read = true;
f4ac4d1a 642 udev_device->properties_generation = device_get_properties_generation(udev_device->device);
912541b0 643 }
f4ac4d1a 644
dcf557f7 645 return udev_list_get_entry(udev_device->properties);
eb1f0e66 646}
11d543c1 647
1e511322
KS
648/**
649 * udev_device_get_action:
650 * @udev_device: udev device
651 *
652 * This is only valid if the device was received through a monitor. Devices read from
653 * sys do not have an action string. Usual actions are: add, remove, change, online,
654 * offline.
655 *
656 * Returns: the kernel action value, or #NULL if there is no action value available.
657 **/
f4ac4d1a 658_public_ const char *udev_device_get_action(struct udev_device *udev_device) {
40769ccc 659 DeviceAction action;
f4ac4d1a
TG
660
661 assert_return_errno(udev_device, NULL, EINVAL);
662
40769ccc 663 if (device_get_action(udev_device->device, &action) < 0)
912541b0 664 return NULL;
f4ac4d1a 665
40769ccc 666 return device_action_to_string(action);
c4f5f942
KS
667}
668
9c6a11b1
KS
669/**
670 * udev_device_get_usec_since_initialized:
671 * @udev_device: udev device
672 *
673 * Return the number of microseconds passed since udev set up the
674 * device for the first time.
675 *
676 * This is only implemented for devices with need to store properties
677 * in the udev database. All other devices return 0 here.
678 *
679 * Returns: the number of microseconds since the device was first seen.
680 **/
76387b9a 681_public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device) {
f4ac4d1a
TG
682 usec_t ts;
683 int r;
9c6a11b1 684
f4ac4d1a
TG
685 assert_return(udev_device, -EINVAL);
686
687 r = sd_device_get_usec_since_initialized(udev_device->device, &ts);
fd05c424
YW
688 if (r < 0)
689 return_with_errno(0, r);
9c6a11b1 690
f4ac4d1a 691 return ts;
9c6a11b1
KS
692}
693
1e511322
KS
694/**
695 * udev_device_get_sysattr_value:
696 * @udev_device: udev device
697 * @sysattr: attribute name
698 *
456719b6 699 * The retrieved value is cached in the device. Repeated calls will return the same
1e511322
KS
700 * value and not open the attribute again.
701 *
702 * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value.
703 **/
76387b9a 704_public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr) {
f4ac4d1a
TG
705 const char *value;
706 int r;
912541b0 707
f4ac4d1a 708 assert_return_errno(udev_device, NULL, EINVAL);
912541b0 709
f4ac4d1a 710 r = sd_device_get_sysattr_value(udev_device->device, sysattr, &value);
fd05c424
YW
711 if (r < 0)
712 return_with_errno(NULL, r);
912541b0 713
f4ac4d1a 714 return value;
93b0f384 715}
517814e7 716
946f1825
HR
717/**
718 * udev_device_set_sysattr_value:
719 * @udev_device: udev device
720 * @sysattr: attribute name
721 * @value: new value to be set
722 *
723 * Update the contents of the sys attribute and the cached value of the device.
724 *
725 * Returns: Negative error code on failure or 0 on success.
726 **/
8aae9a66 727_public_ int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, const char *value) {
f4ac4d1a 728 int r;
f180ad25 729
f4ac4d1a 730 assert_return(udev_device, -EINVAL);
f180ad25 731
f4ac4d1a
TG
732 r = sd_device_set_sysattr_value(udev_device->device, sysattr, value);
733 if (r < 0)
734 return r;
f180ad25 735
f4ac4d1a 736 return 0;
f180ad25
TE
737}
738
739/**
740 * udev_device_get_sysattr_list_entry:
741 * @udev_device: udev device
742 *
743 * Retrieve the list of available sysattrs, with value being empty;
20bee04c
KS
744 * This just return all available sysfs attributes for a particular
745 * device without reading their values.
f180ad25
TE
746 *
747 * Returns: the first entry of the property list
748 **/
76387b9a 749_public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device) {
f4ac4d1a 750 assert_return_errno(udev_device, NULL, EINVAL);
f180ad25 751
f4ac4d1a
TG
752 if (!udev_device->sysattrs_read) {
753 const char *sysattr;
f180ad25 754
dcf557f7 755 udev_list_cleanup(udev_device->sysattrs);
11d543c1 756
f4ac4d1a 757 FOREACH_DEVICE_SYSATTR(udev_device->device, sysattr)
dcf557f7 758 if (!udev_list_entry_add(udev_device->sysattrs, sysattr, NULL))
3f14e721 759 return_with_errno(NULL, ENOMEM);
11d543c1 760
f4ac4d1a 761 udev_device->sysattrs_read = true;
912541b0 762 }
f4ac4d1a 763
dcf557f7 764 return udev_list_get_entry(udev_device->sysattrs);
4281da1f
KS
765}
766
48a0170b
KS
767/**
768 * udev_device_get_is_initialized:
769 * @udev_device: udev device
770 *
771 * Check if udev has already handled the device and has set up
772 * device node permissions and context, or has renamed a network
773 * device.
774 *
9c6a11b1 775 * This is only implemented for devices with a device node
48a0170b
KS
776 * or network interfaces. All other devices return 1 here.
777 *
778 * Returns: 1 if the device is set up. 0 otherwise.
779 **/
76387b9a 780_public_ int udev_device_get_is_initialized(struct udev_device *udev_device) {
5a937ea2 781 int r;
48a0170b 782
f4ac4d1a 783 assert_return(udev_device, -EINVAL);
48a0170b 784
5a937ea2 785 r = sd_device_get_is_initialized(udev_device->device);
fd05c424
YW
786 if (r < 0)
787 return_with_errno(0, r);
8e3ba377 788
5a937ea2 789 return r;
28460195
KS
790}
791
f712894d
KS
792/**
793 * udev_device_get_tags_list_entry:
794 * @udev_device: udev device
795 *
796 * Retrieve the list of tags attached to the udev device. The next
bb061708 797 * list entry can be retrieved with udev_list_entry_get_next(),
f712894d 798 * which returns #NULL if no more entries exist. The tag string
bb061708 799 * can be retrieved from the list entry by udev_list_entry_get_name().
f712894d
KS
800 *
801 * Returns: the first entry of the tag list
802 **/
76387b9a 803_public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device) {
f4ac4d1a
TG
804 assert_return_errno(udev_device, NULL, EINVAL);
805
378f61eb
TG
806 if (device_get_tags_generation(udev_device->device) != udev_device->tags_generation ||
807 !udev_device->tags_read) {
f4ac4d1a
TG
808 const char *tag;
809
dcf557f7 810 udev_list_cleanup(udev_device->tags);
f4ac4d1a
TG
811
812 FOREACH_DEVICE_TAG(udev_device->device, tag)
dcf557f7 813 if (!udev_list_entry_add(udev_device->tags, tag, NULL))
3f14e721 814 return_with_errno(NULL, ENOMEM);
f4ac4d1a 815
378f61eb 816 udev_device->tags_read = true;
f4ac4d1a
TG
817 udev_device->tags_generation = device_get_tags_generation(udev_device->device);
818 }
819
dcf557f7 820 return udev_list_get_entry(udev_device->tags);
28460195
KS
821}
822
21dbe43a
KS
823/**
824 * udev_device_has_tag:
825 * @udev_device: udev device
826 * @tag: tag name
827 *
828 * Check if a given device has a certain tag associated.
829 *
830 * Returns: 1 if the tag is found. 0 otherwise.
831 **/
33a03e6e 832_public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag) {
f4ac4d1a 833 assert_return(udev_device, 0);
fa639f3a 834
33a03e6e 835 return sd_device_has_tag(udev_device->device, tag) > 0;
1cd0a770 836}