libudev-device.c revision 1b14c3cfbe25f9bf1183bd26875f3c68847559c0
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek This file is part of systemd.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek (at your option) any later version.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic struct udev_list_entry *udev_device_add_property_internal(struct udev_device *udev_device, const char *key, const char *value);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * SECTION:libudev-device
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * @short_description: kernel sys devices
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Representation of kernel sys devices. Devices are uniquely identified
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * by their syspath, every device has exactly one path in the kernel sys
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * filesystem. Devices usually belong to a kernel subsystem, and have
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * a unique name inside that subsystem.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Opaque object representing one kernel sys device.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek struct udev_device *parent_device;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek struct udev_list properties_list;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek struct udev_list sysattr_value_list;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek unsigned long long int seqnum;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * udev_device_get_seqnum:
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * @udev_device: udev device
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * This is only valid if the device was received through a monitor. Devices read from
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * sys do not have a sequence number.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Returns: the kernel event sequence number, or 0 if there is no sequence number available.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek_public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek snprintf(num, sizeof(num), "%llu", seqnum);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "SEQNUM", num);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint udev_device_get_ifindex(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_read_uevent_file(udev_device);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek snprintf(num, sizeof(num), "%d", ifindex);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "IFINDEX", num);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * udev_device_get_devnum:
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * @udev_device: udev device
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Get the device major/minor number.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Returns: the dev_t number.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek_public_ dev_t udev_device_get_devnum(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_read_uevent_file(udev_device);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek snprintf(num, sizeof(num), "%u", major(devnum));
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "MAJOR", num);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek snprintf(num, sizeof(num), "%u", minor(devnum));
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "MINOR", num);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekconst char *udev_device_get_devpath_old(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return udev_device->devpath_old;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_devpath_old(struct udev_device *udev_device, const char *devpath_old)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->devpath_old = strdup(devpath_old);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (udev_device->devpath_old == NULL)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "DEVPATH_OLD", udev_device->devpath_old);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek pos = strrchr(udev_device->devpath_old, '/');
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * udev_device_get_driver:
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * @udev_device: udev device
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Get the kernel driver name.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Returns: the driver name string, or #NULL if there is no driver attached.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek_public_ const char *udev_device_get_driver(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (util_get_sys_core_link_value(udev_device->udev, "driver", udev_device->syspath, driver, sizeof(driver)) > 0)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->driver = strdup(driver);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_driver(struct udev_device *udev_device, const char *driver)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->driver = strdup(driver);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (udev_device->driver == NULL)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "DRIVER", udev_device->driver);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * udev_device_get_devtype:
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * @udev_device: udev device
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Retrieve the devtype string of the udev device.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Returns: the devtype name of the udev device, or #NULL if it can not be determined
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek_public_ const char *udev_device_get_devtype(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (!udev_device->devtype_set) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->devtype_set = true;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_read_uevent_file(udev_device);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->devtype = strdup(devtype);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (udev_device->devtype == NULL)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->devtype_set = true;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "DEVTYPE", udev_device->devtype);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->subsystem = strdup(subsystem);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (udev_device->subsystem == NULL)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->subsystem_set = true;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "SUBSYSTEM", udev_device->subsystem);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * udev_device_get_subsystem:
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * @udev_device: udev device
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Retrieve the subsystem string of the udev device. The string does not
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * contain any "/".
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Returns: the subsystem name of the udev device, or #NULL if it can not be determined
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek_public_ const char *udev_device_get_subsystem(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (!udev_device->subsystem_set) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->subsystem_set = true;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* read "subsystem" link */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (util_get_sys_core_link_value(udev_device->udev, "subsystem", udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_subsystem(udev_device, subsystem);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* implicit names */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (startswith(udev_device->devpath, "/module/")) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_subsystem(udev_device, "module");
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (strstr(udev_device->devpath, "/drivers/") != NULL) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_subsystem(udev_device, "drivers");
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (startswith(udev_device->devpath, "/subsystem/") ||
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek startswith(udev_device->devpath, "/class/") ||
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek startswith(udev_device->devpath, "/bus/")) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_subsystem(udev_device, "subsystem");
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekmode_t udev_device_get_devnode_mode(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_read_uevent_file(udev_device);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return udev_device->devnode_mode;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t mode)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->devnode_mode = mode;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek snprintf(num, sizeof(num), "%#o", mode);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "DEVMODE", num);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekuid_t udev_device_get_devnode_uid(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_read_uevent_file(udev_device);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return udev_device->devnode_uid;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_devnode_uid(struct udev_device *udev_device, uid_t uid)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek snprintf(num, sizeof(num), "%u", uid);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "DEVUID", num);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekgid_t udev_device_get_devnode_gid(struct udev_device *udev_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_read_uevent_file(udev_device);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return udev_device->devnode_gid;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_devnode_gid(struct udev_device *udev_device, gid_t gid)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek snprintf(num, sizeof(num), "%u", gid);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "DEVGID", num);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic struct udev_list_entry *udev_device_add_property_internal(struct udev_device *udev_device, const char *key, const char *value)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->envp_uptodate = false;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek struct udev_list_entry *list_entry;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek list_entry = udev_device_get_properties_list_entry(udev_device);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek list_entry = udev_list_entry_get_by_name(list_entry, key);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_list_entry_delete(list_entry);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return udev_list_entry_add(&udev_device->properties_list, key, value);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek struct udev_list_entry *property;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek property = udev_device_add_property_internal(udev_device, key, value);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* store in db, skip private keys */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_list_entry_set_num(property, true);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek strscpy(name, sizeof(name), property);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return udev_device_add_property_internal(udev_device, name, val);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->syspath = strdup(syspath);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (udev_device->syspath == NULL)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->devpath = udev_device->syspath + strlen("/sys");
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "DEVPATH", udev_device->devpath);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek pos = strrchr(udev_device->syspath, '/');
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->sysname = strdup(&pos[1]);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (udev_device->sysname == NULL)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* some devices have '!' in their name, change that to '/' */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek while (udev_device->sysname[len] != '\0') {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (udev_device->sysname[len] == '!')
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->sysname[len] = '/';
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* trailing number */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek while (len > 0 && isdigit(udev_device->sysname[--len]))
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->sysnum = &udev_device->sysname[len];
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* sysname is completely numeric */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic void udev_device_set_usec_initialized(struct udev_device *udev_device, usec_t usec_initialized)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek char num[DECIMAL_STR_MAX(usec_t)];
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device->usec_initialized = usec_initialized;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek snprintf(num, sizeof(num), USEC_FMT, usec_initialized);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_property_internal(udev_device, "USEC_INITIALIZED", num);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekvoid udev_device_ensure_usec_initialized(struct udev_device *udev_device, struct udev_device *old_device)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (old_device && old_device->usec_initialized != 0)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_usec_initialized(udev_device, old_device->usec_initialized);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_usec_initialized(udev_device, now(CLOCK_MONOTONIC));
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * parse property string, and if needed, update internal values accordingly
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * udev_device_add_property_from_string_parse_finish() needs to be
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * called after adding properties, and its return value checked
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * udev_device_set_info_loaded() needs to be set, to avoid trying
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * to use a device without a DEVPATH set
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic void udev_device_add_property_from_string_parse(struct udev_device *udev_device, const char *property)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (startswith(property, "DEVPATH=")) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek strscpyl(path, sizeof(path), "/sys", &property[8], NULL);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_syspath(udev_device, path);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek } else if (startswith(property, "SUBSYSTEM=")) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_subsystem(udev_device, &property[10]);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek } else if (startswith(property, "DEVTYPE=")) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_devtype(udev_device, &property[8]);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek } else if (startswith(property, "DEVNAME=")) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_set_devnode(udev_device, &property[8]);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek } else if (startswith(property, "DEVLINKS=")) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek strscpy(devlinks, sizeof(devlinks), &property[9]);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_devlink(udev_device, slink);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek udev_device_add_devlink(udev_device, slink);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek } else if (startswith(property, "TAGS=")) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek strscpy(tags, sizeof(tags), &property[5]);
next++;
return -EINVAL;
_public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key)
return NULL;
return NULL;
const char *id;
FILE *f;
if (f == NULL)
const char *val;
switch(line[0]) {
fclose(f);
FILE *f;
int maj = 0;
int min = 0;
if (f == NULL)
return -errno;
char *pos;
fclose(f);
return NULL;
return NULL;
return udev_device;
const char *subdir;
char *pos;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return udev_device;
_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum)
const char *type_str;
return NULL;
char type;
char *sysname;
switch(id[0]) {
return NULL;
int sk;
int ifindex;
if (ifindex <= 0) {
return NULL;
if (sk < 0)
return NULL;
return NULL;
return NULL;
return dev;
return NULL;
return NULL;
return NULL;
_public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname)
goto found;
goto found;
goto found;
goto out;
goto found;
goto out;
char *driver;
goto found;
goto found;
goto out;
goto found;
goto found;
goto found;
out:
return NULL;
return NULL;
return udev_device;
const char *subdir;
char *pos;
return udev_device_parent;
return NULL;
return NULL;
_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype)
return NULL;
const char *parent_subsystem;
const char *parent_devtype;
if (!parent)
return parent;
return NULL;
return NULL;
return udev_device;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
_public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device)
return NULL;
_public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device)
return NULL;
size_t l;
s = symlinks;
size_t l;
s = tags;
return NULL;
_public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device)
if (now_ts == 0)
_public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr)
int fd;
return NULL;
return NULL;
goto out;
return NULL;
goto out;
goto out;
goto out;
goto out;
if (fd < 0)
goto out;
if (size < 0)
goto out;
goto out;
out:
return val;
_public_ int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, char *value)
int fd;
int ret = 0;
return -EINVAL;
return -EINVAL;
value_len = 0;
goto out;
goto out;
goto out;
goto out;
goto out;
if (fd < 0) {
goto out;
if (size < 0) {
goto out;
goto out;
out:
return ret;
int num = 0;
return -EINVAL;
if (!dir)
return -errno;
num++;
return num;
_public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device)
int ret;
if (0 > ret)
return NULL;
return -ENOMEM;
return -ENOMEM;
return NULL;
const char *sysname;
return NULL;
if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0)
return -EINVAL;
return -ENOMEM;
struct udev_list_entry *e;
return NULL;
size_t l;
return -ENOMEM;
return -ENOMEM;
l = MONITOR_BUF_SIZE;
const char *key;
return -EINVAL;
return -EINVAL;
return NULL;
return -EINVAL;
return -ENOMEM;
const char *interface;
char *new_syspath;
return -EINVAL;
if (!dirname)
return -ENOMEM;
if (interface) {
/* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
return NULL;
if (!device) {
return NULL;
return device;
if (!device)
return NULL;
return device;
return NULL;
if (!device) {
return NULL;
char *key;
if (keylen == 0)
return NULL;
return device;
for ((entry = udev_device_get_properties_list_entry(src)); entry; entry = udev_list_entry_get_next(entry)) {