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