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