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