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