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