static int find_device( const struct rfkill_event *event, sd_device **ret) { _cleanup_(sd_device_unrefp) sd_device *device = NULL; _cleanup_free_ char *sysname = NULL; const char *name; int r; assert(event); assert(ret); if (asprintf(&sysname, "rfkill%i", event->idx) < 0) return log_oom(); r = sd_device_new_from_subsystem_sysname(&device, "rfkill", sysname); if (r < 0) return log_full_errno(IN_SET(r, -ENOENT, -ENXIO, -ENODEV) ? LOG_DEBUG : LOG_ERR, r, "Failed to open device '%s': %m", sysname); r = sd_device_get_sysattr_value(device, "name", &name); if (r < 0) return log_debug_errno(r, "Device has no name, ignoring: %m"); log_debug("Operating on rfkill device '%s'.", name); *ret = TAKE_PTR(device); return 0; }
/* handle "[<SUBSYSTEM>/<KERNEL>]<attribute>" format */ int util_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value) { char temp[UTIL_PATH_SIZE], *subsys, *sysname, *attr; _cleanup_(sd_device_unrefp) sd_device *dev = NULL; const char *val; int r; if (string[0] != '[') return -EINVAL; strscpy(temp, sizeof(temp), string); subsys = &temp[1]; sysname = strchr(subsys, '/'); if (!sysname) return -EINVAL; sysname[0] = '\0'; sysname = &sysname[1]; attr = strchr(sysname, ']'); if (!attr) return -EINVAL; attr[0] = '\0'; attr = &attr[1]; if (attr[0] == '/') attr = &attr[1]; if (attr[0] == '\0') attr = NULL; if (read_value && !attr) return -EINVAL; r = sd_device_new_from_subsystem_sysname(&dev, subsys, sysname); if (r < 0) return r; if (read_value) { r = sd_device_get_sysattr_value(dev, attr, &val); if (r < 0 && r != -ENOENT) return r; if (r == -ENOENT) result[0] = '\0'; else strscpy(result, maxsize, val); log_debug("value '[%s/%s]%s' is '%s'", subsys, sysname, attr, result); } else { r = sd_device_get_syspath(dev, &val); if (r < 0) return r; strscpyl(result, maxsize, val, attr ? "/" : NULL, attr ?: NULL, NULL); log_debug("path '[%s/%s]%s' is '%s'", subsys, sysname, strempty(attr), result); } return 0; }
/** * udev_device_new_from_subsystem_sysname: * @udev: udev library context * @subsystem: the subsystem of the device * @sysname: the name of the device * * Create new udev device, and fill in information from the sys device * and the udev database entry. The device is looked up by the subsystem * and name string of the device, like "mem" / "zero", or "block" / "sda". * * The initial refcount is 1, and needs to be decremented to * release the resources of the udev device. * * Returns: a new udev device, or #NULL, if it does not exist **/ _public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) { struct udev_device *udev_device; int r; udev_device = udev_device_new(udev); if (!udev_device) return NULL; r = sd_device_new_from_subsystem_sysname(&udev_device->device, subsystem, sysname); if (r < 0) { errno = -r; udev_device_unref(udev_device); return NULL; } return udev_device; }