]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libudev/libudev-device.c
libudev: drop unnecessary check
[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 **/
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;
fd05c424
YW
58 else if (r < 0)
59 return_with_errno(0, r);
905555dc 60
f4ac4d1a 61 r = safe_atollu(seqnum, &ret);
fd05c424
YW
62 if (r < 0)
63 return_with_errno(0, r);
905555dc 64
f4ac4d1a 65 return ret;
905555dc
KS
66}
67
68/**
69 * udev_device_get_devnum:
70 * @udev_device: udev device
71 *
21dbe43a
KS
72 * Get the device major/minor number.
73 *
74 * Returns: the dev_t number.
905555dc 75 **/
76387b9a 76_public_ dev_t udev_device_get_devnum(struct udev_device *udev_device) {
f4ac4d1a
TG
77 dev_t devnum;
78 int r;
905555dc 79
f4ac4d1a 80 assert_return_errno(udev_device, makedev(0, 0), EINVAL);
905555dc 81
f4ac4d1a 82 r = sd_device_get_devnum(udev_device->device, &devnum);
fd05c424 83 if (r == -ENOENT)
f4ac4d1a 84 return makedev(0, 0);
fd05c424
YW
85 if (r < 0)
86 return_with_errno(makedev(0, 0), r);
905555dc 87
f4ac4d1a 88 return devnum;
905555dc
KS
89}
90
91/**
92 * udev_device_get_driver:
93 * @udev_device: udev device
94 *
21dbe43a
KS
95 * Get the kernel driver name.
96 *
97 * Returns: the driver name string, or #NULL if there is no driver attached.
905555dc 98 **/
76387b9a 99_public_ const char *udev_device_get_driver(struct udev_device *udev_device) {
f4ac4d1a
TG
100 const char *driver;
101 int r;
102
103 assert_return_errno(udev_device, NULL, EINVAL);
905555dc 104
f4ac4d1a 105 r = sd_device_get_driver(udev_device->device, &driver);
fd05c424
YW
106 if (r < 0)
107 return_with_errno(NULL, r);
905555dc 108
f4ac4d1a 109 return driver;
905555dc
KS
110}
111
112/**
113 * udev_device_get_devtype:
114 * @udev_device: udev device
115 *
116 * Retrieve the devtype string of the udev device.
117 *
87ac8d99 118 * Returns: the devtype name of the udev device, or #NULL if it cannot be determined
905555dc 119 **/
76387b9a 120_public_ const char *udev_device_get_devtype(struct udev_device *udev_device) {
f4ac4d1a
TG
121 const char *devtype;
122 int r;
123
124 assert_return_errno(udev_device, NULL, EINVAL);
125
126 r = sd_device_get_devtype(udev_device->device, &devtype);
fd05c424 127 if (r == -ENOENT)
912541b0 128 return NULL;
fd05c424
YW
129 if (r < 0)
130 return_with_errno(NULL, r);
905555dc 131
f4ac4d1a 132 return devtype;
905555dc
KS
133}
134
135/**
136 * udev_device_get_subsystem:
137 * @udev_device: udev device
138 *
139 * Retrieve the subsystem string of the udev device. The string does not
140 * contain any "/".
141 *
87ac8d99 142 * Returns: the subsystem name of the udev device, or #NULL if it cannot be determined
905555dc 143 **/
76387b9a 144_public_ const char *udev_device_get_subsystem(struct udev_device *udev_device) {
f4ac4d1a
TG
145 const char *subsystem;
146 int r;
df546eb5 147
f4ac4d1a 148 assert_return_errno(udev_device, NULL, EINVAL);
fc8d61c5 149
f4ac4d1a 150 r = sd_device_get_subsystem(udev_device->device, &subsystem);
fd05c424
YW
151 if (r < 0)
152 return_with_errno(NULL, r);
fc8d61c5 153
f4ac4d1a 154 return subsystem;
fc8d61c5
KS
155}
156
157/**
158 * udev_device_get_property_value:
159 * @udev_device: udev device
160 * @key: property name
161 *
21dbe43a
KS
162 * Get the value of a given property.
163 *
164 * Returns: the property string, or #NULL if there is no such property.
fc8d61c5 165 **/
76387b9a 166_public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key) {
fd05c424 167 const char *value;
f4ac4d1a 168 int r;
912541b0 169
f4ac4d1a 170 assert_return_errno(udev_device && key, NULL, EINVAL);
912541b0 171
f4ac4d1a 172 r = sd_device_get_property_value(udev_device->device, key, &value);
fd05c424
YW
173 if (r < 0)
174 return_with_errno(NULL, r);
912541b0 175
f4ac4d1a 176 return value;
99214844
KS
177}
178
02e7ae2f 179struct udev_device *udev_device_new(struct udev *udev, sd_device *device) {
912541b0 180 struct udev_device *udev_device;
912541b0 181
02e7ae2f
YW
182 assert(device);
183
71074e3a 184 udev_device = new(struct udev_device, 1);
fd05c424
YW
185 if (!udev_device)
186 return_with_errno(NULL, ENOMEM);
71074e3a
YW
187
188 *udev_device = (struct udev_device) {
189 .n_ref = 1,
190 .udev = udev,
02e7ae2f 191 .device = sd_device_ref(device),
71074e3a
YW
192 };
193
f349626b
YW
194 udev_list_init(&udev_device->properties, true);
195 udev_list_init(&udev_device->tags, true);
196 udev_list_init(&udev_device->sysattrs, true);
197 udev_list_init(&udev_device->devlinks, true);
41b848b0 198
912541b0 199 return udev_device;
eb1f0e66
KS
200}
201
202/**
8753fadf 203 * udev_device_new_from_syspath:
eb1f0e66 204 * @udev: udev library context
8753fadf 205 * @syspath: sys device path including sys directory
eb1f0e66 206 *
8753fadf 207 * Create new udev device, and fill in information from the sys
214a6c79 208 * device and the udev database entry. The syspath is the absolute
8753fadf 209 * path to the device, including the sys mount point.
eb1f0e66
KS
210 *
211 * The initial refcount is 1, and needs to be decremented to
be7de409 212 * release the resources of the udev device.
eb1f0e66
KS
213 *
214 * Returns: a new udev device, or #NULL, if it does not exist
215 **/
f4ac4d1a 216_public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath) {
02e7ae2f 217 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a 218 int r;
912541b0 219
02e7ae2f 220 r = sd_device_new_from_syspath(&device, syspath);
fd05c424
YW
221 if (r < 0)
222 return_with_errno(NULL, r);
912541b0 223
02e7ae2f 224 return udev_device_new(udev, device);
eb1f0e66
KS
225}
226
1e511322
KS
227/**
228 * udev_device_new_from_devnum:
229 * @udev: udev library context
230 * @type: char or block device
231 * @devnum: device major/minor number
232 *
233 * Create new udev device, and fill in information from the sys
dbba7e40
KS
234 * device and the udev database entry. The device is looked-up
235 * by its major/minor number and type. Character and block device
236 * numbers are not unique across the two types.
1e511322
KS
237 *
238 * The initial refcount is 1, and needs to be decremented to
239 * release the resources of the udev device.
240 *
241 * Returns: a new udev device, or #NULL, if it does not exist
242 **/
76387b9a 243_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) {
02e7ae2f 244 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a
TG
245 int r;
246
02e7ae2f 247 r = sd_device_new_from_devnum(&device, type, devnum);
fd05c424
YW
248 if (r < 0)
249 return_with_errno(NULL, r);
4c9dff47 250
02e7ae2f 251 return udev_device_new(udev, device);
4c9dff47
KS
252}
253
dbf61afb
KS
254/**
255 * udev_device_new_from_device_id:
256 * @udev: udev library context
257 * @id: text string identifying a kernel device
258 *
259 * Create new udev device, and fill in information from the sys
260 * device and the udev database entry. The device is looked-up
261 * by a special string:
262 * b8:2 - block device major:minor
263 * c128:1 - char device major:minor
264 * n3 - network device ifindex
265 * +sound:card29 - kernel driver core subsystem:device name
266 *
267 * The initial refcount is 1, and needs to be decremented to
268 * release the resources of the udev device.
269 *
270 * Returns: a new udev device, or #NULL, if it does not exist
271 **/
76387b9a 272_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id) {
02e7ae2f 273 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a
TG
274 int r;
275
02e7ae2f 276 r = sd_device_new_from_device_id(&device, id);
fd05c424
YW
277 if (r < 0)
278 return_with_errno(NULL, r);
f4ac4d1a 279
02e7ae2f 280 return udev_device_new(udev, device);
cad40a5f
KS
281}
282
1e511322
KS
283/**
284 * udev_device_new_from_subsystem_sysname:
285 * @udev: udev library context
214a6c79 286 * @subsystem: the subsystem of the device
1e511322
KS
287 * @sysname: the name of the device
288 *
dbba7e40
KS
289 * Create new udev device, and fill in information from the sys device
290 * and the udev database entry. The device is looked up by the subsystem
291 * and name string of the device, like "mem" / "zero", or "block" / "sda".
1e511322
KS
292 *
293 * The initial refcount is 1, and needs to be decremented to
294 * release the resources of the udev device.
295 *
296 * Returns: a new udev device, or #NULL, if it does not exist
297 **/
76387b9a 298_public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) {
02e7ae2f 299 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a 300 int r;
912541b0 301
02e7ae2f 302 r = sd_device_new_from_subsystem_sysname(&device, subsystem, sysname);
fd05c424
YW
303 if (r < 0)
304 return_with_errno(NULL, r);
912541b0 305
02e7ae2f 306 return udev_device_new(udev, device);
90d80c2e
KS
307}
308
fc8d61c5
KS
309/**
310 * udev_device_new_from_environment
311 * @udev: udev library context
312 *
313 * Create new udev device, and fill in information from the
314 * current process environment. This only works reliable if
315 * the process is called from a udev rule. It is usually used
316 * for tools executed from IMPORT= rules.
317 *
318 * The initial refcount is 1, and needs to be decremented to
319 * release the resources of the udev device.
320 *
321 * Returns: a new udev device, or #NULL, if it does not exist
322 **/
76387b9a 323_public_ struct udev_device *udev_device_new_from_environment(struct udev *udev) {
02e7ae2f 324 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
f4ac4d1a 325 int r;
fc8d61c5 326
02e7ae2f 327 r = device_new_from_strv(&device, environ);
fd05c424
YW
328 if (r < 0)
329 return_with_errno(NULL, r);
fc8d61c5 330
02e7ae2f 331 return udev_device_new(udev, device);
fc8d61c5
KS
332}
333
76387b9a 334static struct udev_device *device_new_from_parent(struct udev_device *child) {
02e7ae2f 335 sd_device *parent;
f4ac4d1a
TG
336 int r;
337
338 assert_return_errno(child, NULL, EINVAL);
339
02e7ae2f 340 r = sd_device_get_parent(child->device, &parent);
fd05c424
YW
341 if (r < 0)
342 return_with_errno(NULL, r);
aa0e72ea 343
02e7ae2f 344 return udev_device_new(child->udev, parent);
4ad3a37f
KS
345}
346
1e511322
KS
347/**
348 * udev_device_get_parent:
349 * @udev_device: the device to start searching from
350 *
351 * Find the next parent device, and fill in information from the sys
352 * device and the udev database entry.
353 *
572ce4f7
ZJS
354 * Returned device is not referenced. It is attached to the child
355 * device, and will be cleaned up when the child device is cleaned up.
1e511322 356 *
214a6c79 357 * It is not necessarily just the upper level directory, empty or not
1e511322
KS
358 * recognized sys directories are ignored.
359 *
360 * It can be called as many times as needed, without caring about
361 * references.
362 *
363 * Returns: a new udev device, or #NULL, if it no parent exist.
364 **/
76387b9a 365_public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device) {
f4ac4d1a
TG
366 assert_return_errno(udev_device, NULL, EINVAL);
367
912541b0
KS
368 if (!udev_device->parent_set) {
369 udev_device->parent_set = true;
f4ac4d1a 370 udev_device->parent = device_new_from_parent(udev_device);
912541b0 371 }
f4ac4d1a
TG
372
373 /* TODO: errno will differ here in case parent == NULL */
374 return udev_device->parent;
b2d9e4f2
KS
375}
376
1e511322
KS
377/**
378 * udev_device_get_parent_with_subsystem_devtype:
379 * @udev_device: udev device to start searching from
214a6c79 380 * @subsystem: the subsystem of the device
1e511322
KS
381 * @devtype: the type (DEVTYPE) of the device
382 *
383 * Find the next parent device, with a matching subsystem and devtype
384 * value, and fill in information from the sys device and the udev
385 * database entry.
386 *
79ef2e97 387 * If devtype is #NULL, only subsystem is checked, and any devtype will
54d4f54e
MP
388 * match.
389 *
572ce4f7
ZJS
390 * Returned device is not referenced. It is attached to the child
391 * device, and will be cleaned up when the child device is cleaned up.
1e511322
KS
392 *
393 * It can be called as many times as needed, without caring about
394 * references.
395 *
8d6bc73a 396 * Returns: a new udev device, or #NULL if no matching parent exists.
1e511322 397 **/
76387b9a 398_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype) {
f4ac4d1a
TG
399 sd_device *parent;
400 int r;
bf8b2ae1 401
f4ac4d1a
TG
402 assert_return_errno(udev_device, NULL, EINVAL);
403
404 /* this relies on the fact that finding the subdevice of a parent or the
405 parent of a subdevice commute */
406
407 /* first find the correct sd_device */
408 r = sd_device_get_parent_with_subsystem_devtype(udev_device->device, subsystem, devtype, &parent);
fd05c424
YW
409 if (r < 0)
410 return_with_errno(NULL, r);
883012d4 411
bbb04088 412 /* then walk the chain of udev_device parents until the corresponding
f4ac4d1a 413 one is found */
fd05c424 414 while ((udev_device = udev_device_get_parent(udev_device)))
f4ac4d1a
TG
415 if (udev_device->device == parent)
416 return udev_device;
aa0e72ea 417
fd05c424 418 return_with_errno(NULL, ENOENT);
bf8b2ae1
MH
419}
420
eb1f0e66
KS
421/**
422 * udev_device_get_udev:
7d8787b3 423 * @udev_device: udev device
eb1f0e66
KS
424 *
425 * Retrieve the udev library context the device was created with.
426 *
427 * Returns: the udev library context
428 **/
76387b9a 429_public_ struct udev *udev_device_get_udev(struct udev_device *udev_device) {
f4ac4d1a
TG
430 assert_return_errno(udev_device, NULL, EINVAL);
431
912541b0 432 return udev_device->udev;
eb1f0e66
KS
433}
434
3c6ac219
YW
435static struct udev_device *udev_device_free(struct udev_device *udev_device) {
436 assert(udev_device);
437
438 sd_device_unref(udev_device->device);
439 udev_device_unref(udev_device->parent);
440
441 udev_list_cleanup(&udev_device->properties);
442 udev_list_cleanup(&udev_device->sysattrs);
443 udev_list_cleanup(&udev_device->tags);
444 udev_list_cleanup(&udev_device->devlinks);
445
446 return mfree(udev_device);
447}
448
eb1f0e66
KS
449/**
450 * udev_device_ref:
451 * @udev_device: udev device
452 *
453 * Take a reference of a udev device.
454 *
455 * Returns: the passed udev device
456 **/
eb1f0e66
KS
457
458/**
459 * udev_device_unref:
460 * @udev_device: udev device
461 *
462 * Drop a reference of a udev device. If the refcount reaches zero,
be7de409 463 * the resources of the device will be released.
eb1f0e66 464 *
725d7e6c 465 * Returns: #NULL
eb1f0e66 466 **/
3c6ac219 467DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_device, udev_device, udev_device_free);
eb1f0e66
KS
468
469/**
470 * udev_device_get_devpath:
471 * @udev_device: udev device
472 *
11d543c1
KS
473 * Retrieve the kernel devpath value of the udev device. The path
474 * does not contain the sys mount point, and starts with a '/'.
eb1f0e66 475 *
11d543c1 476 * Returns: the devpath of the udev device
eb1f0e66 477 **/
76387b9a 478_public_ const char *udev_device_get_devpath(struct udev_device *udev_device) {
f4ac4d1a
TG
479 const char *devpath;
480 int r;
481
482 assert_return_errno(udev_device, NULL, EINVAL);
483
484 r = sd_device_get_devpath(udev_device->device, &devpath);
fd05c424
YW
485 if (r < 0)
486 return_with_errno(NULL, r);
f4ac4d1a
TG
487
488 return devpath;
eb1f0e66
KS
489}
490
11d543c1
KS
491/**
492 * udev_device_get_syspath:
493 * @udev_device: udev device
494 *
495 * Retrieve the sys path of the udev device. The path is an
496 * absolute path and starts with the sys mount point.
497 *
498 * Returns: the sys path of the udev device
499 **/
76387b9a 500_public_ const char *udev_device_get_syspath(struct udev_device *udev_device) {
f4ac4d1a
TG
501 const char *syspath;
502 int r;
503
504 assert_return_errno(udev_device, NULL, EINVAL);
505
506 r = sd_device_get_syspath(udev_device->device, &syspath);
fd05c424
YW
507 if (r < 0)
508 return_with_errno(NULL, r);
f4ac4d1a
TG
509
510 return syspath;
11d543c1
KS
511}
512
1e511322
KS
513/**
514 * udev_device_get_sysname:
515 * @udev_device: udev device
516 *
21dbe43a
KS
517 * Get the kernel device name in /sys.
518 *
61233823 519 * Returns: the name string of the device
1e511322 520 **/
76387b9a 521_public_ const char *udev_device_get_sysname(struct udev_device *udev_device) {
f4ac4d1a
TG
522 const char *sysname;
523 int r;
524
525 assert_return_errno(udev_device, NULL, EINVAL);
526
527 r = sd_device_get_sysname(udev_device->device, &sysname);
fd05c424
YW
528 if (r < 0)
529 return_with_errno(NULL, r);
f4ac4d1a
TG
530
531 return sysname;
4ad3a37f
KS
532}
533
1e511322
KS
534/**
535 * udev_device_get_sysnum:
536 * @udev_device: udev device
537 *
21dbe43a
KS
538 * Get the instance number of the device.
539 *
c5315881 540 * Returns: the trailing number string of the device name
1e511322 541 **/
76387b9a 542_public_ const char *udev_device_get_sysnum(struct udev_device *udev_device) {
f4ac4d1a
TG
543 const char *sysnum;
544 int r;
545
546 assert_return_errno(udev_device, NULL, EINVAL);
547
548 r = sd_device_get_sysnum(udev_device->device, &sysnum);
fd05c424 549 if (r == -ENOENT)
912541b0 550 return NULL;
fd05c424
YW
551 if (r < 0)
552 return_with_errno(NULL, r);
f4ac4d1a
TG
553
554 return sysnum;
517814e7
KS
555}
556
eb1f0e66 557/**
fb762bb9 558 * udev_device_get_devnode:
eb1f0e66
KS
559 * @udev_device: udev device
560 *
561 * Retrieve the device node file name belonging to the udev device.
ba6929f6 562 * The path is an absolute path, and starts with the device directory.
eb1f0e66
KS
563 *
564 * Returns: the device node file name of the udev device, or #NULL if no device node exists
565 **/
76387b9a 566_public_ const char *udev_device_get_devnode(struct udev_device *udev_device) {
f4ac4d1a
TG
567 const char *devnode;
568 int r;
569
570 assert_return_errno(udev_device, NULL, EINVAL);
571
572 r = sd_device_get_devname(udev_device->device, &devnode);
fd05c424
YW
573 if (r < 0)
574 return_with_errno(NULL, r);
f4ac4d1a
TG
575
576 return devnode;
eb1f0e66
KS
577}
578
eb1f0e66 579/**
0de33a61 580 * udev_device_get_devlinks_list_entry:
eb1f0e66 581 * @udev_device: udev device
eb1f0e66 582 *
bf7ad0ea
KS
583 * Retrieve the list of device links pointing to the device file of
584 * the udev device. The next list entry can be retrieved with
bb061708 585 * udev_list_entry_get_next(), which returns #NULL if no more entries exist.
bf7ad0ea 586 * The devlink path can be retrieved from the list entry by
e345e267 587 * udev_list_entry_get_name(). The path is an absolute path, and starts with
bf7ad0ea 588 * the device directory.
eb1f0e66 589 *
bf7ad0ea 590 * Returns: the first entry of the device node link list
eb1f0e66 591 **/
76387b9a 592_public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device) {
f4ac4d1a 593 assert_return_errno(udev_device, NULL, EINVAL);
eb1f0e66 594
378f61eb
TG
595 if (device_get_devlinks_generation(udev_device->device) != udev_device->devlinks_generation ||
596 !udev_device->devlinks_read) {
f4ac4d1a
TG
597 const char *devlink;
598
599 udev_list_cleanup(&udev_device->devlinks);
600
601 FOREACH_DEVICE_DEVLINK(udev_device->device, devlink)
3f14e721
YW
602 if (!udev_list_entry_add(&udev_device->devlinks, devlink, NULL))
603 return_with_errno(NULL, ENOMEM);
f4ac4d1a 604
378f61eb 605 udev_device->devlinks_read = true;
f4ac4d1a
TG
606 udev_device->devlinks_generation = device_get_devlinks_generation(udev_device->device);
607 }
608
609 return udev_list_get_entry(&udev_device->devlinks);
979ff016
KS
610}
611
eb1f0e66 612/**
f4ac4d1a 613 * udev_device_get_event_properties_entry:
eb1f0e66 614 * @udev_device: udev device
eb1f0e66 615 *
bf7ad0ea 616 * Retrieve the list of key/value device properties of the udev
bb061708 617 * device. The next list entry can be retrieved with udev_list_entry_get_next(),
bf7ad0ea 618 * which returns #NULL if no more entries exist. The property name
bb061708
KS
619 * can be retrieved from the list entry by udev_list_entry_get_name(),
620 * the property value by udev_list_entry_get_value().
eb1f0e66 621 *
bf7ad0ea 622 * Returns: the first entry of the property list
eb1f0e66 623 **/
76387b9a 624_public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device) {
f4ac4d1a
TG
625 assert_return_errno(udev_device, NULL, EINVAL);
626
378f61eb
TG
627 if (device_get_properties_generation(udev_device->device) != udev_device->properties_generation ||
628 !udev_device->properties_read) {
f4ac4d1a
TG
629 const char *key, *value;
630
631 udev_list_cleanup(&udev_device->properties);
632
633 FOREACH_DEVICE_PROPERTY(udev_device->device, key, value)
3f14e721
YW
634 if (!udev_list_entry_add(&udev_device->properties, key, value))
635 return_with_errno(NULL, ENOMEM);
f4ac4d1a 636
378f61eb 637 udev_device->properties_read = true;
f4ac4d1a 638 udev_device->properties_generation = device_get_properties_generation(udev_device->device);
912541b0 639 }
f4ac4d1a
TG
640
641 return udev_list_get_entry(&udev_device->properties);
eb1f0e66 642}
11d543c1 643
1e511322
KS
644/**
645 * udev_device_get_action:
646 * @udev_device: udev device
647 *
648 * This is only valid if the device was received through a monitor. Devices read from
649 * sys do not have an action string. Usual actions are: add, remove, change, online,
650 * offline.
651 *
652 * Returns: the kernel action value, or #NULL if there is no action value available.
653 **/
f4ac4d1a 654_public_ const char *udev_device_get_action(struct udev_device *udev_device) {
fd05c424 655 const char *action;
f4ac4d1a
TG
656 int r;
657
658 assert_return_errno(udev_device, NULL, EINVAL);
659
660 r = sd_device_get_property_value(udev_device->device, "ACTION", &action);
fd05c424 661 if (r == -ENOENT)
912541b0 662 return NULL;
fd05c424
YW
663 if (r < 0)
664 return_with_errno(NULL, r);
f4ac4d1a
TG
665
666 return 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
f4ac4d1a 755 udev_list_cleanup(&udev_device->sysattrs);
11d543c1 756
f4ac4d1a 757 FOREACH_DEVICE_SYSATTR(udev_device->device, sysattr)
3f14e721
YW
758 if (!udev_list_entry_add(&udev_device->sysattrs, sysattr, NULL))
759 return_with_errno(NULL, ENOMEM);
11d543c1 760
f4ac4d1a 761 udev_device->sysattrs_read = true;
912541b0 762 }
f4ac4d1a
TG
763
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
810 udev_list_cleanup(&udev_device->tags);
811
812 FOREACH_DEVICE_TAG(udev_device->device, tag)
3f14e721
YW
813 if (!udev_list_entry_add(&udev_device->tags, tag, NULL))
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
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}