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