]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-device.c
Merge pull request #3986 from whot/wip/click-wheel-angle-horiz
[thirdparty/systemd.git] / src / libudev / libudev-device.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
5 Copyright 2015 Tom Gundersen <teg@jklm.no>
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 ***/
20
21 #include <ctype.h>
22 #include <dirent.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <linux/sockios.h>
26 #include <net/if.h>
27 #include <stdbool.h>
28 #include <stddef.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/ioctl.h>
33 #include <sys/socket.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36
37 #include "libudev.h"
38 #include "sd-device.h"
39
40 #include "alloc-util.h"
41 #include "device-private.h"
42 #include "device-util.h"
43 #include "libudev-device-internal.h"
44 #include "libudev-private.h"
45 #include "parse-util.h"
46
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
53 * filesystem. Devices usually belong to a kernel subsystem, and have
54 * a unique name inside that subsystem.
55 */
56
57 /**
58 * udev_device_get_seqnum:
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 **/
66 _public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device)
67 {
68 const char *seqnum;
69 unsigned long long ret;
70 int r;
71
72 assert_return_errno(udev_device, 0, EINVAL);
73
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 }
81
82 r = safe_atollu(seqnum, &ret);
83 if (r < 0) {
84 errno = -r;
85 return 0;
86 }
87
88 return ret;
89 }
90
91 /**
92 * udev_device_get_devnum:
93 * @udev_device: udev device
94 *
95 * Get the device major/minor number.
96 *
97 * Returns: the dev_t number.
98 **/
99 _public_ dev_t udev_device_get_devnum(struct udev_device *udev_device)
100 {
101 dev_t devnum;
102 int r;
103
104 assert_return_errno(udev_device, makedev(0, 0), EINVAL);
105
106 r = sd_device_get_devnum(udev_device->device, &devnum);
107 if (r < 0) {
108 errno = -r;
109 return makedev(0, 0);
110 }
111
112 return devnum;
113 }
114
115 /**
116 * udev_device_get_driver:
117 * @udev_device: udev device
118 *
119 * Get the kernel driver name.
120 *
121 * Returns: the driver name string, or #NULL if there is no driver attached.
122 **/
123 _public_ const char *udev_device_get_driver(struct udev_device *udev_device)
124 {
125 const char *driver;
126 int r;
127
128 assert_return_errno(udev_device, NULL, EINVAL);
129
130 r = sd_device_get_driver(udev_device->device, &driver);
131 if (r < 0) {
132 errno = -r;
133 return NULL;
134 }
135
136 return driver;
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 **/
147 _public_ const char *udev_device_get_devtype(struct udev_device *udev_device)
148 {
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;
157 return NULL;
158 }
159
160 return devtype;
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 **/
172 _public_ const char *udev_device_get_subsystem(struct udev_device *udev_device)
173 {
174 const char *subsystem;
175 int r;
176
177 assert_return_errno(udev_device, NULL, EINVAL);
178
179 r = sd_device_get_subsystem(udev_device->device, &subsystem);
180 if (r < 0) {
181 errno = -r;
182 return NULL;
183 } else if (!subsystem)
184 errno = ENODATA;
185
186 return subsystem;
187 }
188
189 /**
190 * udev_device_get_property_value:
191 * @udev_device: udev device
192 * @key: property name
193 *
194 * Get the value of a given property.
195 *
196 * Returns: the property string, or #NULL if there is no such property.
197 **/
198 _public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key)
199 {
200 const char *value = NULL;
201 int r;
202
203 assert_return_errno(udev_device && key, NULL, EINVAL);
204
205 r = sd_device_get_property_value(udev_device->device, key, &value);
206 if (r < 0) {
207 errno = -r;
208 return NULL;
209 }
210
211 return value;
212 }
213
214 struct udev_device *udev_device_new(struct udev *udev) {
215 struct udev_device *udev_device;
216
217 assert_return_errno(udev, NULL, EINVAL);
218
219 udev_device = new0(struct udev_device, 1);
220 if (!udev_device) {
221 errno = ENOMEM;
222 return NULL;
223 }
224 udev_device->refcount = 1;
225 udev_device->udev = udev;
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);
230
231 return udev_device;
232 }
233
234 /**
235 * udev_device_new_from_syspath:
236 * @udev: udev library context
237 * @syspath: sys device path including sys directory
238 *
239 * Create new udev device, and fill in information from the sys
240 * device and the udev database entry. The syspath is the absolute
241 * path to the device, including the sys mount point.
242 *
243 * The initial refcount is 1, and needs to be decremented to
244 * release the resources of the udev device.
245 *
246 * Returns: a new udev device, or #NULL, if it does not exist
247 **/
248 _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath) {
249 struct udev_device *udev_device;
250 int r;
251
252 udev_device = udev_device_new(udev);
253 if (!udev_device)
254 return NULL;
255
256 r = sd_device_new_from_syspath(&udev_device->device, syspath);
257 if (r < 0) {
258 errno = -r;
259 udev_device_unref(udev_device);
260 return NULL;
261 }
262
263 return udev_device;
264 }
265
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
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.
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 **/
282 _public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum)
283 {
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);
295 return NULL;
296 }
297
298 return udev_device;
299 }
300
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 **/
319 _public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id)
320 {
321 struct udev_device *udev_device;
322 int r;
323
324 udev_device = udev_device_new(udev);
325 if (!udev_device)
326 return NULL;
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);
332 return NULL;
333 }
334
335 return udev_device;
336 }
337
338 /**
339 * udev_device_new_from_subsystem_sysname:
340 * @udev: udev library context
341 * @subsystem: the subsystem of the device
342 * @sysname: the name of the device
343 *
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".
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 **/
353 _public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname)
354 {
355 struct udev_device *udev_device;
356 int r;
357
358 udev_device = udev_device_new(udev);
359 if (!udev_device)
360 return NULL;
361
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;
367 }
368
369 return udev_device;
370 }
371
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 **/
386 _public_ struct udev_device *udev_device_new_from_environment(struct udev *udev)
387 {
388 struct udev_device *udev_device;
389 int r;
390
391 udev_device = udev_device_new(udev);
392 if (!udev_device)
393 return NULL;
394
395 r = device_new_from_strv(&udev_device->device, environ);
396 if (r < 0) {
397 errno = -r;
398 udev_device_unref(udev_device);
399 return NULL;
400 }
401
402 return udev_device;
403 }
404
405 static struct udev_device *device_new_from_parent(struct udev_device *child)
406 {
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;
421 }
422
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;
427 }
428
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 *
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.
438 *
439 * It is not necessarily just the upper level directory, empty or not
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 **/
447 _public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device)
448 {
449 assert_return_errno(udev_device, NULL, EINVAL);
450
451 if (!udev_device->parent_set) {
452 udev_device->parent_set = true;
453 udev_device->parent = device_new_from_parent(udev_device);
454 }
455
456 /* TODO: errno will differ here in case parent == NULL */
457 return udev_device->parent;
458 }
459
460 /**
461 * udev_device_get_parent_with_subsystem_devtype:
462 * @udev_device: udev device to start searching from
463 * @subsystem: the subsystem of the device
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 *
470 * If devtype is #NULL, only subsystem is checked, and any devtype will
471 * match.
472 *
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.
475 *
476 * It can be called as many times as needed, without caring about
477 * references.
478 *
479 * Returns: a new udev device, or #NULL if no matching parent exists.
480 **/
481 _public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype)
482 {
483 sd_device *parent;
484 int r;
485
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;
495 return NULL;
496 }
497
498 /* then walk the chain of udev_device parents until the corresponding
499 one is found */
500 while ((udev_device = udev_device_get_parent(udev_device))) {
501 if (udev_device->device == parent)
502 return udev_device;
503 }
504
505 errno = ENOENT;
506 return NULL;
507 }
508
509 /**
510 * udev_device_get_udev:
511 * @udev_device: udev device
512 *
513 * Retrieve the udev library context the device was created with.
514 *
515 * Returns: the udev library context
516 **/
517 _public_ struct udev *udev_device_get_udev(struct udev_device *udev_device)
518 {
519 assert_return_errno(udev_device, NULL, EINVAL);
520
521 return udev_device->udev;
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 **/
532 _public_ struct udev_device *udev_device_ref(struct udev_device *udev_device)
533 {
534 if (udev_device)
535 udev_device->refcount++;
536
537 return udev_device;
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,
545 * the resources of the device will be released.
546 *
547 * Returns: #NULL
548 **/
549 _public_ struct udev_device *udev_device_unref(struct udev_device *udev_device)
550 {
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
563 return NULL;
564 }
565
566 /**
567 * udev_device_get_devpath:
568 * @udev_device: udev device
569 *
570 * Retrieve the kernel devpath value of the udev device. The path
571 * does not contain the sys mount point, and starts with a '/'.
572 *
573 * Returns: the devpath of the udev device
574 **/
575 _public_ const char *udev_device_get_devpath(struct udev_device *udev_device)
576 {
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;
585 return NULL;
586 }
587
588 return devpath;
589 }
590
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 **/
600 _public_ const char *udev_device_get_syspath(struct udev_device *udev_device)
601 {
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;
610 return NULL;
611 }
612
613 return syspath;
614 }
615
616 /**
617 * udev_device_get_sysname:
618 * @udev_device: udev device
619 *
620 * Get the kernel device name in /sys.
621 *
622 * Returns: the name string of the device
623 **/
624 _public_ const char *udev_device_get_sysname(struct udev_device *udev_device)
625 {
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;
634 return NULL;
635 }
636
637 return sysname;
638 }
639
640 /**
641 * udev_device_get_sysnum:
642 * @udev_device: udev device
643 *
644 * Get the instance number of the device.
645 *
646 * Returns: the trailing number string of the device name
647 **/
648 _public_ const char *udev_device_get_sysnum(struct udev_device *udev_device)
649 {
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;
658 return NULL;
659 }
660
661 return sysnum;
662 }
663
664 /**
665 * udev_device_get_devnode:
666 * @udev_device: udev device
667 *
668 * Retrieve the device node file name belonging to the udev device.
669 * The path is an absolute path, and starts with the device directory.
670 *
671 * Returns: the device node file name of the udev device, or #NULL if no device node exists
672 **/
673 _public_ const char *udev_device_get_devnode(struct udev_device *udev_device)
674 {
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;
683 return NULL;
684 }
685
686 return devnode;
687 }
688
689 /**
690 * udev_device_get_devlinks_list_entry:
691 * @udev_device: udev device
692 *
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
695 * udev_list_entry_get_next(), which returns #NULL if no more entries exist.
696 * The devlink path can be retrieved from the list entry by
697 * udev_list_entry_get_name(). The path is an absolute path, and starts with
698 * the device directory.
699 *
700 * Returns: the first entry of the device node link list
701 **/
702 _public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device)
703 {
704 assert_return_errno(udev_device, NULL, EINVAL);
705
706 if (device_get_devlinks_generation(udev_device->device) != udev_device->devlinks_generation ||
707 !udev_device->devlinks_read) {
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
715 udev_device->devlinks_read = true;
716 udev_device->devlinks_generation = device_get_devlinks_generation(udev_device->device);
717 }
718
719 return udev_list_get_entry(&udev_device->devlinks);
720 }
721
722 /**
723 * udev_device_get_event_properties_entry:
724 * @udev_device: udev device
725 *
726 * Retrieve the list of key/value device properties of the udev
727 * device. The next list entry can be retrieved with udev_list_entry_get_next(),
728 * which returns #NULL if no more entries exist. The property name
729 * can be retrieved from the list entry by udev_list_entry_get_name(),
730 * the property value by udev_list_entry_get_value().
731 *
732 * Returns: the first entry of the property list
733 **/
734 _public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device)
735 {
736 assert_return_errno(udev_device, NULL, EINVAL);
737
738 if (device_get_properties_generation(udev_device->device) != udev_device->properties_generation ||
739 !udev_device->properties_read) {
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
747 udev_device->properties_read = true;
748 udev_device->properties_generation = device_get_properties_generation(udev_device->device);
749 }
750
751 return udev_list_get_entry(&udev_device->properties);
752 }
753
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 **/
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;
773 return NULL;
774 }
775
776 return action;
777 }
778
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 **/
791 _public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device)
792 {
793 usec_t ts;
794 int r;
795
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;
801 return 0;
802 }
803
804 return ts;
805 }
806
807 /**
808 * udev_device_get_sysattr_value:
809 * @udev_device: udev device
810 * @sysattr: attribute name
811 *
812 * The retrieved value is cached in the device. Repeated calls will return the same
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 **/
817 _public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr)
818 {
819 const char *value;
820 int r;
821
822 assert_return_errno(udev_device, NULL, EINVAL);
823
824 r = sd_device_get_sysattr_value(udev_device->device, sysattr, &value);
825 if (r < 0) {
826 errno = -r;
827 return NULL;
828 }
829
830 return value;
831 }
832
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 {
845 int r;
846
847 assert_return(udev_device, -EINVAL);
848
849 r = sd_device_set_sysattr_value(udev_device->device, sysattr, value);
850 if (r < 0)
851 return r;
852
853 return 0;
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;
861 * This just return all available sysfs attributes for a particular
862 * device without reading their values.
863 *
864 * Returns: the first entry of the property list
865 **/
866 _public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device)
867 {
868 assert_return_errno(udev_device, NULL, EINVAL);
869
870 if (!udev_device->sysattrs_read) {
871 const char *sysattr;
872
873 udev_list_cleanup(&udev_device->sysattrs);
874
875 FOREACH_DEVICE_SYSATTR(udev_device->device, sysattr)
876 udev_list_entry_add(&udev_device->sysattrs, sysattr, NULL);
877
878 udev_device->sysattrs_read = true;
879 }
880
881 return udev_list_get_entry(&udev_device->sysattrs);
882 }
883
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 *
892 * This is only implemented for devices with a device node
893 * or network interfaces. All other devices return 1 here.
894 *
895 * Returns: 1 if the device is set up. 0 otherwise.
896 **/
897 _public_ int udev_device_get_is_initialized(struct udev_device *udev_device)
898 {
899 int r, initialized;
900
901 assert_return(udev_device, -EINVAL);
902
903 r = sd_device_get_is_initialized(udev_device->device, &initialized);
904 if (r < 0) {
905 errno = -r;
906
907 return 0;
908 }
909
910 return initialized;
911 }
912
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
918 * list entry can be retrieved with udev_list_entry_get_next(),
919 * which returns #NULL if no more entries exist. The tag string
920 * can be retrieved from the list entry by udev_list_entry_get_name().
921 *
922 * Returns: the first entry of the tag list
923 **/
924 _public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device)
925 {
926 assert_return_errno(udev_device, NULL, EINVAL);
927
928 if (device_get_tags_generation(udev_device->device) != udev_device->tags_generation ||
929 !udev_device->tags_read) {
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
937 udev_device->tags_read = true;
938 udev_device->tags_generation = device_get_tags_generation(udev_device->device);
939 }
940
941 return udev_list_get_entry(&udev_device->tags);
942 }
943
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 **/
953 _public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag)
954 {
955 assert_return(udev_device, 0);
956
957 return sd_device_has_tag(udev_device->device, tag);
958 }