LCOV - code coverage report
Current view: top level - libudev - libudev-device.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 106 271 39.1 %
Date: 2015-07-29 18:47:03 Functions: 15 33 45.5 %

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

Generated by: LCOV version 1.11