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