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