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