X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibudev-device.c;h=10f28b8cd5bb5a4a4fb40067d2f4cfdd3b1155d3;hp=e5950bb4b13bb7176626fc10b64e1c01b6887037;hb=a1525d172014e66f97d82fc1e9096444597abcc7;hpb=ad29a9f14fa8b1932c0e418bfcf1c10ce6a35a33 diff --git a/src/libudev-device.c b/src/libudev-device.c index e5950bb4b..10f28b8cd 100644 --- a/src/libudev-device.c +++ b/src/libudev-device.c @@ -44,49 +44,49 @@ * Opaque object representing one kernel sys device. */ struct udev_device { - struct udev *udev; - struct udev_device *parent_device; - char *syspath; - const char *devpath; - char *sysname; - const char *sysnum; - char *devnode; - mode_t devnode_mode; - char *subsystem; - char *devtype; - char *driver; - char *action; - char *devpath_old; - char *id_filename; - char **envp; - char *monitor_buf; - size_t monitor_buf_len; - struct udev_list devlinks_list; - struct udev_list properties_list; - struct udev_list sysattr_value_list; - struct udev_list sysattr_list; - struct udev_list tags_list; - unsigned long long int seqnum; - unsigned long long int usec_initialized; - int devlink_priority; - int refcount; - dev_t devnum; - int ifindex; - int watch_handle; - int maj, min; - bool parent_set; - bool subsystem_set; - bool devtype_set; - bool devlinks_uptodate; - bool envp_uptodate; - bool tags_uptodate; - bool driver_set; - bool info_loaded; - bool db_loaded; - bool uevent_loaded; - bool is_initialized; - bool sysattr_list_read; - bool db_persist; + struct udev *udev; + struct udev_device *parent_device; + char *syspath; + const char *devpath; + char *sysname; + const char *sysnum; + char *devnode; + mode_t devnode_mode; + char *subsystem; + char *devtype; + char *driver; + char *action; + char *devpath_old; + char *id_filename; + char **envp; + char *monitor_buf; + size_t monitor_buf_len; + struct udev_list devlinks_list; + struct udev_list properties_list; + struct udev_list sysattr_value_list; + struct udev_list sysattr_list; + struct udev_list tags_list; + unsigned long long int seqnum; + unsigned long long int usec_initialized; + int devlink_priority; + int refcount; + dev_t devnum; + int ifindex; + int watch_handle; + int maj, min; + bool parent_set; + bool subsystem_set; + bool devtype_set; + bool devlinks_uptodate; + bool envp_uptodate; + bool tags_uptodate; + bool driver_set; + bool info_loaded; + bool db_loaded; + bool uevent_loaded; + bool is_initialized; + bool sysattr_list_read; + bool db_persist; }; /** @@ -100,36 +100,36 @@ struct udev_device { **/ UDEV_EXPORT unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device) { - if (udev_device == NULL) - return 0; - return udev_device->seqnum; + if (udev_device == NULL) + return 0; + return udev_device->seqnum; } static int udev_device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum) { - char num[32]; + char num[32]; - udev_device->seqnum = seqnum; - snprintf(num, sizeof(num), "%llu", seqnum); - udev_device_add_property(udev_device, "SEQNUM", num); - return 0; + udev_device->seqnum = seqnum; + snprintf(num, sizeof(num), "%llu", seqnum); + udev_device_add_property(udev_device, "SEQNUM", num); + return 0; } int udev_device_get_ifindex(struct udev_device *udev_device) { - if (!udev_device->info_loaded) - udev_device_read_uevent_file(udev_device); - return udev_device->ifindex; + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->ifindex; } static int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex) { - char num[32]; + char num[32]; - udev_device->ifindex = ifindex; - snprintf(num, sizeof(num), "%u", ifindex); - udev_device_add_property(udev_device, "IFINDEX", num); - return 0; + udev_device->ifindex = ifindex; + snprintf(num, sizeof(num), "%u", ifindex); + udev_device_add_property(udev_device, "IFINDEX", num); + return 0; } /** @@ -140,45 +140,45 @@ static int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex) **/ UDEV_EXPORT dev_t udev_device_get_devnum(struct udev_device *udev_device) { - if (udev_device == NULL) - return makedev(0, 0); - if (!udev_device->info_loaded) - udev_device_read_uevent_file(udev_device); - return udev_device->devnum; + if (udev_device == NULL) + return makedev(0, 0); + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnum; } static int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum) { - char num[32]; + char num[32]; - udev_device->devnum = devnum; + udev_device->devnum = devnum; - snprintf(num, sizeof(num), "%u", major(devnum)); - udev_device_add_property(udev_device, "MAJOR", num); - snprintf(num, sizeof(num), "%u", minor(devnum)); - udev_device_add_property(udev_device, "MINOR", num); - return 0; + snprintf(num, sizeof(num), "%u", major(devnum)); + udev_device_add_property(udev_device, "MAJOR", num); + snprintf(num, sizeof(num), "%u", minor(devnum)); + udev_device_add_property(udev_device, "MINOR", num); + return 0; } const char *udev_device_get_devpath_old(struct udev_device *udev_device) { - return udev_device->devpath_old; + return udev_device->devpath_old; } static int udev_device_set_devpath_old(struct udev_device *udev_device, const char *devpath_old) { - const char *pos; + const char *pos; - free(udev_device->devpath_old); - udev_device->devpath_old = strdup(devpath_old); - if (udev_device->devpath_old == NULL) - return -ENOMEM; - udev_device_add_property(udev_device, "DEVPATH_OLD", udev_device->devpath_old); + free(udev_device->devpath_old); + udev_device->devpath_old = strdup(devpath_old); + if (udev_device->devpath_old == NULL) + return -ENOMEM; + udev_device_add_property(udev_device, "DEVPATH_OLD", udev_device->devpath_old); - pos = strrchr(udev_device->devpath_old, '/'); - if (pos == NULL) - return -EINVAL; - return 0; + pos = strrchr(udev_device->devpath_old, '/'); + if (pos == NULL) + return -EINVAL; + return 0; } /** @@ -189,27 +189,27 @@ static int udev_device_set_devpath_old(struct udev_device *udev_device, const ch **/ UDEV_EXPORT const char *udev_device_get_driver(struct udev_device *udev_device) { - char driver[UTIL_NAME_SIZE]; + char driver[UTIL_NAME_SIZE]; - if (udev_device == NULL) - return NULL; - if (!udev_device->driver_set) { - udev_device->driver_set = true; - if (util_get_sys_core_link_value(udev_device->udev, "driver", udev_device->syspath, driver, sizeof(driver)) > 0) - udev_device->driver = strdup(driver); - } - return udev_device->driver; + if (udev_device == NULL) + return NULL; + if (!udev_device->driver_set) { + udev_device->driver_set = true; + if (util_get_sys_core_link_value(udev_device->udev, "driver", udev_device->syspath, driver, sizeof(driver)) > 0) + udev_device->driver = strdup(driver); + } + return udev_device->driver; } static int udev_device_set_driver(struct udev_device *udev_device, const char *driver) { - free(udev_device->driver); - udev_device->driver = strdup(driver); - if (udev_device->driver == NULL) - return -ENOMEM; - udev_device->driver_set = true; - udev_device_add_property(udev_device, "DRIVER", udev_device->driver); - return 0; + free(udev_device->driver); + udev_device->driver = strdup(driver); + if (udev_device->driver == NULL) + return -ENOMEM; + udev_device->driver_set = true; + udev_device_add_property(udev_device, "DRIVER", udev_device->driver); + return 0; } /** @@ -222,35 +222,35 @@ static int udev_device_set_driver(struct udev_device *udev_device, const char *d **/ UDEV_EXPORT const char *udev_device_get_devtype(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - if (!udev_device->devtype_set) { - udev_device->devtype_set = true; - udev_device_read_uevent_file(udev_device); - } - return udev_device->devtype; + if (udev_device == NULL) + return NULL; + if (!udev_device->devtype_set) { + udev_device->devtype_set = true; + udev_device_read_uevent_file(udev_device); + } + return udev_device->devtype; } static int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype) { - free(udev_device->devtype); - udev_device->devtype = strdup(devtype); - if (udev_device->devtype == NULL) - return -ENOMEM; - udev_device->devtype_set = true; - udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype); - return 0; + free(udev_device->devtype); + udev_device->devtype = strdup(devtype); + if (udev_device->devtype == NULL) + return -ENOMEM; + udev_device->devtype_set = true; + udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype); + return 0; } static int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem) { - free(udev_device->subsystem); - udev_device->subsystem = strdup(subsystem); - if (udev_device->subsystem == NULL) - return -ENOMEM; - udev_device->subsystem_set = true; - udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem); - return 0; + free(udev_device->subsystem); + udev_device->subsystem = strdup(subsystem); + if (udev_device->subsystem == NULL) + return -ENOMEM; + udev_device->subsystem_set = true; + udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem); + return 0; } /** @@ -264,82 +264,82 @@ static int udev_device_set_subsystem(struct udev_device *udev_device, const char **/ UDEV_EXPORT const char *udev_device_get_subsystem(struct udev_device *udev_device) { - char subsystem[UTIL_NAME_SIZE]; - - if (udev_device == NULL) - return NULL; - if (!udev_device->subsystem_set) { - udev_device->subsystem_set = true; - /* read "subsystem" link */ - if (util_get_sys_core_link_value(udev_device->udev, "subsystem", udev_device->syspath, subsystem, sizeof(subsystem)) > 0) { - udev_device_set_subsystem(udev_device, subsystem); - return udev_device->subsystem; - } - /* implicit names */ - if (strncmp(udev_device->devpath, "/module/", 8) == 0) { - udev_device_set_subsystem(udev_device, "module"); - return udev_device->subsystem; - } - if (strstr(udev_device->devpath, "/drivers/") != NULL) { - udev_device_set_subsystem(udev_device, "drivers"); - return udev_device->subsystem; - } - if (strncmp(udev_device->devpath, "/subsystem/", 11) == 0 || - strncmp(udev_device->devpath, "/class/", 7) == 0 || - strncmp(udev_device->devpath, "/bus/", 5) == 0) { - udev_device_set_subsystem(udev_device, "subsystem"); - return udev_device->subsystem; - } - } - return udev_device->subsystem; + char subsystem[UTIL_NAME_SIZE]; + + if (udev_device == NULL) + return NULL; + if (!udev_device->subsystem_set) { + udev_device->subsystem_set = true; + /* read "subsystem" link */ + if (util_get_sys_core_link_value(udev_device->udev, "subsystem", udev_device->syspath, subsystem, sizeof(subsystem)) > 0) { + udev_device_set_subsystem(udev_device, subsystem); + return udev_device->subsystem; + } + /* implicit names */ + if (strncmp(udev_device->devpath, "/module/", 8) == 0) { + udev_device_set_subsystem(udev_device, "module"); + return udev_device->subsystem; + } + if (strstr(udev_device->devpath, "/drivers/") != NULL) { + udev_device_set_subsystem(udev_device, "drivers"); + return udev_device->subsystem; + } + if (strncmp(udev_device->devpath, "/subsystem/", 11) == 0 || + strncmp(udev_device->devpath, "/class/", 7) == 0 || + strncmp(udev_device->devpath, "/bus/", 5) == 0) { + udev_device_set_subsystem(udev_device, "subsystem"); + return udev_device->subsystem; + } + } + return udev_device->subsystem; } mode_t udev_device_get_devnode_mode(struct udev_device *udev_device) { - if (!udev_device->info_loaded) - udev_device_read_uevent_file(udev_device); - return udev_device->devnode_mode; + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnode_mode; } static int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t mode) { - char num[32]; + char num[32]; - udev_device->devnode_mode = mode; - snprintf(num, sizeof(num), "%#o", mode); - udev_device_add_property(udev_device, "DEVMODE", num); - return 0; + udev_device->devnode_mode = mode; + snprintf(num, sizeof(num), "%#o", mode); + udev_device_add_property(udev_device, "DEVMODE", num); + return 0; } struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value) { - udev_device->envp_uptodate = false; - if (value == NULL) { - struct udev_list_entry *list_entry; + udev_device->envp_uptodate = false; + if (value == NULL) { + struct udev_list_entry *list_entry; - list_entry = udev_device_get_properties_list_entry(udev_device); - list_entry = udev_list_entry_get_by_name(list_entry, key); - if (list_entry != NULL) - udev_list_entry_delete(list_entry); - return NULL; - } - return udev_list_entry_add(&udev_device->properties_list, key, value); + list_entry = udev_device_get_properties_list_entry(udev_device); + list_entry = udev_list_entry_get_by_name(list_entry, key); + if (list_entry != NULL) + udev_list_entry_delete(list_entry); + return NULL; + } + return udev_list_entry_add(&udev_device->properties_list, key, value); } static struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property) { - char name[UTIL_LINE_SIZE]; - char *val; + char name[UTIL_LINE_SIZE]; + char *val; - util_strscpy(name, sizeof(name), property); - val = strchr(name, '='); - if (val == NULL) - return NULL; - val[0] = '\0'; - val = &val[1]; - if (val[0] == '\0') - val = NULL; - return udev_device_add_property(udev_device, name, val); + util_strscpy(name, sizeof(name), property); + val = strchr(name, '='); + if (val == NULL) + return NULL; + val[0] = '\0'; + val = &val[1]; + if (val[0] == '\0') + val = NULL; + return udev_device_add_property(udev_device, name, val); } /* @@ -353,86 +353,86 @@ static struct udev_list_entry *udev_device_add_property_from_string(struct udev_ */ void udev_device_add_property_from_string_parse(struct udev_device *udev_device, const char *property) { - if (strncmp(property, "DEVPATH=", 8) == 0) { - char path[UTIL_PATH_SIZE]; - - util_strscpyl(path, sizeof(path), udev_get_sys_path(udev_device->udev), &property[8], NULL); - udev_device_set_syspath(udev_device, path); - } else if (strncmp(property, "SUBSYSTEM=", 10) == 0) { - udev_device_set_subsystem(udev_device, &property[10]); - } else if (strncmp(property, "DEVTYPE=", 8) == 0) { - udev_device_set_devtype(udev_device, &property[8]); - } else if (strncmp(property, "DEVNAME=", 8) == 0) { - udev_device_set_devnode(udev_device, &property[8]); - } else if (strncmp(property, "DEVLINKS=", 9) == 0) { - char devlinks[UTIL_PATH_SIZE]; - char *slink; - char *next; - - util_strscpy(devlinks, sizeof(devlinks), &property[9]); - slink = devlinks; - next = strchr(slink, ' '); - while (next != NULL) { - next[0] = '\0'; - udev_device_add_devlink(udev_device, slink, 0); - slink = &next[1]; - next = strchr(slink, ' '); - } - if (slink[0] != '\0') - udev_device_add_devlink(udev_device, slink, 0); - } else if (strncmp(property, "TAGS=", 5) == 0) { - char tags[UTIL_PATH_SIZE]; - char *next; - - util_strscpy(tags, sizeof(tags), &property[5]); - next = strchr(tags, ':'); - if (next != NULL) { - next++; - while (next[0] != '\0') { - char *tag; - - tag = next; - next = strchr(tag, ':'); - if (next == NULL) - break; - next[0] = '\0'; - next++; - udev_device_add_tag(udev_device, tag); - } - } - } else if (strncmp(property, "USEC_INITIALIZED=", 19) == 0) { - udev_device_set_usec_initialized(udev_device, strtoull(&property[19], NULL, 10)); - } else if (strncmp(property, "DRIVER=", 7) == 0) { - udev_device_set_driver(udev_device, &property[7]); - } else if (strncmp(property, "ACTION=", 7) == 0) { - udev_device_set_action(udev_device, &property[7]); - } else if (strncmp(property, "MAJOR=", 6) == 0) { - udev_device->maj = strtoull(&property[6], NULL, 10); - } else if (strncmp(property, "MINOR=", 6) == 0) { - udev_device->min = strtoull(&property[6], NULL, 10); - } else if (strncmp(property, "DEVPATH_OLD=", 12) == 0) { - udev_device_set_devpath_old(udev_device, &property[12]); - } else if (strncmp(property, "SEQNUM=", 7) == 0) { - udev_device_set_seqnum(udev_device, strtoull(&property[7], NULL, 10)); - } else if (strncmp(property, "IFINDEX=", 8) == 0) { - udev_device_set_ifindex(udev_device, strtoull(&property[8], NULL, 10)); - } else if (strncmp(property, "DEVMODE=", 8) == 0) { - udev_device_set_devnode_mode(udev_device, strtoul(&property[8], NULL, 8)); - } else { - udev_device_add_property_from_string(udev_device, property); - } + if (strncmp(property, "DEVPATH=", 8) == 0) { + char path[UTIL_PATH_SIZE]; + + util_strscpyl(path, sizeof(path), udev_get_sys_path(udev_device->udev), &property[8], NULL); + udev_device_set_syspath(udev_device, path); + } else if (strncmp(property, "SUBSYSTEM=", 10) == 0) { + udev_device_set_subsystem(udev_device, &property[10]); + } else if (strncmp(property, "DEVTYPE=", 8) == 0) { + udev_device_set_devtype(udev_device, &property[8]); + } else if (strncmp(property, "DEVNAME=", 8) == 0) { + udev_device_set_devnode(udev_device, &property[8]); + } else if (strncmp(property, "DEVLINKS=", 9) == 0) { + char devlinks[UTIL_PATH_SIZE]; + char *slink; + char *next; + + util_strscpy(devlinks, sizeof(devlinks), &property[9]); + slink = devlinks; + next = strchr(slink, ' '); + while (next != NULL) { + next[0] = '\0'; + udev_device_add_devlink(udev_device, slink, 0); + slink = &next[1]; + next = strchr(slink, ' '); + } + if (slink[0] != '\0') + udev_device_add_devlink(udev_device, slink, 0); + } else if (strncmp(property, "TAGS=", 5) == 0) { + char tags[UTIL_PATH_SIZE]; + char *next; + + util_strscpy(tags, sizeof(tags), &property[5]); + next = strchr(tags, ':'); + if (next != NULL) { + next++; + while (next[0] != '\0') { + char *tag; + + tag = next; + next = strchr(tag, ':'); + if (next == NULL) + break; + next[0] = '\0'; + next++; + udev_device_add_tag(udev_device, tag); + } + } + } else if (strncmp(property, "USEC_INITIALIZED=", 19) == 0) { + udev_device_set_usec_initialized(udev_device, strtoull(&property[19], NULL, 10)); + } else if (strncmp(property, "DRIVER=", 7) == 0) { + udev_device_set_driver(udev_device, &property[7]); + } else if (strncmp(property, "ACTION=", 7) == 0) { + udev_device_set_action(udev_device, &property[7]); + } else if (strncmp(property, "MAJOR=", 6) == 0) { + udev_device->maj = strtoull(&property[6], NULL, 10); + } else if (strncmp(property, "MINOR=", 6) == 0) { + udev_device->min = strtoull(&property[6], NULL, 10); + } else if (strncmp(property, "DEVPATH_OLD=", 12) == 0) { + udev_device_set_devpath_old(udev_device, &property[12]); + } else if (strncmp(property, "SEQNUM=", 7) == 0) { + udev_device_set_seqnum(udev_device, strtoull(&property[7], NULL, 10)); + } else if (strncmp(property, "IFINDEX=", 8) == 0) { + udev_device_set_ifindex(udev_device, strtoull(&property[8], NULL, 10)); + } else if (strncmp(property, "DEVMODE=", 8) == 0) { + udev_device_set_devnode_mode(udev_device, strtoul(&property[8], NULL, 8)); + } else { + udev_device_add_property_from_string(udev_device, property); + } } int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_device) { - if (udev_device->maj > 0) - udev_device_set_devnum(udev_device, makedev(udev_device->maj, udev_device->min)); - udev_device->maj = 0; - udev_device->min = 0; + if (udev_device->maj > 0) + udev_device_set_devnum(udev_device, makedev(udev_device->maj, udev_device->min)); + udev_device->maj = 0; + udev_device->min = 0; - if (udev_device->devpath == NULL || udev_device->subsystem == NULL) - return -EINVAL; - return 0; + if (udev_device->devpath == NULL || udev_device->subsystem == NULL) + return -EINVAL; + return 0; } /** @@ -444,162 +444,169 @@ int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_d **/ UDEV_EXPORT const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key) { - struct udev_list_entry *list_entry; + struct udev_list_entry *list_entry; - if (udev_device == NULL) - return NULL; - if (key == NULL) - return NULL; + if (udev_device == NULL) + return NULL; + if (key == NULL) + return NULL; - list_entry = udev_device_get_properties_list_entry(udev_device); - list_entry = udev_list_entry_get_by_name(list_entry, key); - return udev_list_entry_get_value(list_entry); + list_entry = udev_device_get_properties_list_entry(udev_device); + list_entry = udev_list_entry_get_by_name(list_entry, key); + return udev_list_entry_get_value(list_entry); } int udev_device_read_db(struct udev_device *udev_device, const char *dbfile) { - char filename[UTIL_PATH_SIZE]; - char line[UTIL_LINE_SIZE]; - FILE *f; - - /* providing a database file will always force-load it */ - if (dbfile == NULL) { - const char *id; - - if (udev_device->db_loaded) - return 0; - udev_device->db_loaded = true; - - id = udev_device_get_id_filename(udev_device); - if (id == NULL) - return -1; - util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_device->udev), "/data/", id, NULL); - dbfile = filename; - } - - f = fopen(dbfile, "re"); - if (f == NULL) { - info(udev_device->udev, "no db file to read %s: %m\n", dbfile); - return -1; - } - udev_device->is_initialized = true; - - while (fgets(line, sizeof(line), f)) { - ssize_t len; - const char *val; - struct udev_list_entry *entry; - - len = strlen(line); - if (len < 4) - break; - line[len-1] = '\0'; - val = &line[2]; - switch(line[0]) { - case 'S': - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/", val, NULL); - udev_device_add_devlink(udev_device, filename, 0); - break; - case 'L': - udev_device_set_devlink_priority(udev_device, atoi(val)); - break; - case 'E': - entry = udev_device_add_property_from_string(udev_device, val); - udev_list_entry_set_num(entry, true); - break; - case 'G': - udev_device_add_tag(udev_device, val); - break; - case 'W': - udev_device_set_watch_handle(udev_device, atoi(val)); - break; - case 'I': - udev_device_set_usec_initialized(udev_device, strtoull(val, NULL, 10)); - break; - } - } - fclose(f); - - info(udev_device->udev, "device %p filled with db file data\n", udev_device); - return 0; + char filename[UTIL_PATH_SIZE]; + char line[UTIL_LINE_SIZE]; + FILE *f; + + /* providing a database file will always force-load it */ + if (dbfile == NULL) { + const char *id; + + if (udev_device->db_loaded) + return 0; + udev_device->db_loaded = true; + + id = udev_device_get_id_filename(udev_device); + if (id == NULL) + return -1; + util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_device->udev), "/data/", id, NULL); + dbfile = filename; + } + + f = fopen(dbfile, "re"); + if (f == NULL) { + info(udev_device->udev, "no db file to read %s: %m\n", dbfile); + return -1; + } + udev_device->is_initialized = true; + + while (fgets(line, sizeof(line), f)) { + ssize_t len; + const char *val; + struct udev_list_entry *entry; + + len = strlen(line); + if (len < 4) + break; + line[len-1] = '\0'; + val = &line[2]; + switch(line[0]) { + case 'S': + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/", val, NULL); + udev_device_add_devlink(udev_device, filename, 0); + break; + case 'L': + udev_device_set_devlink_priority(udev_device, atoi(val)); + break; + case 'E': + entry = udev_device_add_property_from_string(udev_device, val); + udev_list_entry_set_num(entry, true); + break; + case 'G': + udev_device_add_tag(udev_device, val); + break; + case 'W': + udev_device_set_watch_handle(udev_device, atoi(val)); + break; + case 'I': + udev_device_set_usec_initialized(udev_device, strtoull(val, NULL, 10)); + break; + } + } + fclose(f); + + info(udev_device->udev, "device %p filled with db file data\n", udev_device); + return 0; } int udev_device_read_uevent_file(struct udev_device *udev_device) { - char filename[UTIL_PATH_SIZE]; - FILE *f; - char line[UTIL_LINE_SIZE]; - int maj = 0; - int min = 0; - - if (udev_device->uevent_loaded) - return 0; - - util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL); - f = fopen(filename, "re"); - if (f == NULL) - return -1; - udev_device->uevent_loaded = true; - - while (fgets(line, sizeof(line), f)) { - char *pos; - - pos = strchr(line, '\n'); - if (pos == NULL) - continue; - pos[0] = '\0'; - - if (strncmp(line, "DEVTYPE=", 8) == 0) - udev_device_set_devtype(udev_device, &line[8]); - else if (strncmp(line, "MAJOR=", 6) == 0) - maj = strtoull(&line[6], NULL, 10); - else if (strncmp(line, "MINOR=", 6) == 0) - min = strtoull(&line[6], NULL, 10); - else if (strncmp(line, "IFINDEX=", 8) == 0) - udev_device_set_ifindex(udev_device, strtoull(&line[8], NULL, 10)); - else if (strncmp(line, "DEVNAME=", 8) == 0) - udev_device_set_devnode(udev_device, &line[8]); - else if (strncmp(line, "DEVMODE=", 8) == 0) - udev_device->devnode_mode = strtoul(&line[8], NULL, 8); - - udev_device_add_property_from_string(udev_device, line); - } - - udev_device->devnum = makedev(maj, min); - fclose(f); - return 0; + char filename[UTIL_PATH_SIZE]; + FILE *f; + char line[UTIL_LINE_SIZE]; + int maj = 0; + int min = 0; + + if (udev_device->uevent_loaded) + return 0; + + util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL); + f = fopen(filename, "re"); + if (f == NULL) + return -1; + udev_device->uevent_loaded = true; + + while (fgets(line, sizeof(line), f)) { + char *pos; + + pos = strchr(line, '\n'); + if (pos == NULL) + continue; + pos[0] = '\0'; + + if (strncmp(line, "DEVTYPE=", 8) == 0) { + udev_device_set_devtype(udev_device, &line[8]); + continue; + } + if (strncmp(line, "IFINDEX=", 8) == 0) { + udev_device_set_ifindex(udev_device, strtoull(&line[8], NULL, 10)); + continue; + } + if (strncmp(line, "DEVNAME=", 8) == 0) { + udev_device_set_devnode(udev_device, &line[8]); + continue; + } + + if (strncmp(line, "MAJOR=", 6) == 0) + maj = strtoull(&line[6], NULL, 10); + else if (strncmp(line, "MINOR=", 6) == 0) + min = strtoull(&line[6], NULL, 10); + else if (strncmp(line, "DEVMODE=", 8) == 0) + udev_device->devnode_mode = strtoul(&line[8], NULL, 8); + + udev_device_add_property_from_string(udev_device, line); + } + + udev_device->devnum = makedev(maj, min); + fclose(f); + return 0; } void udev_device_set_info_loaded(struct udev_device *device) { - device->info_loaded = true; + device->info_loaded = true; } struct udev_device *udev_device_new(struct udev *udev) { - struct udev_device *udev_device; - struct udev_list_entry *list_entry; - - if (udev == NULL) - return NULL; - - udev_device = calloc(1, sizeof(struct udev_device)); - if (udev_device == NULL) - return NULL; - udev_device->refcount = 1; - udev_device->udev = udev; - udev_list_init(udev, &udev_device->devlinks_list, true); - udev_list_init(udev, &udev_device->properties_list, true); - udev_list_init(udev, &udev_device->sysattr_value_list, true); - udev_list_init(udev, &udev_device->sysattr_list, false); - udev_list_init(udev, &udev_device->tags_list, true); - udev_device->watch_handle = -1; - /* copy global properties */ - udev_list_entry_foreach(list_entry, udev_get_properties_list_entry(udev)) - udev_device_add_property(udev_device, - udev_list_entry_get_name(list_entry), - udev_list_entry_get_value(list_entry)); - dbg(udev_device->udev, "udev_device: %p created\n", udev_device); - return udev_device; + struct udev_device *udev_device; + struct udev_list_entry *list_entry; + + if (udev == NULL) + return NULL; + + udev_device = calloc(1, sizeof(struct udev_device)); + if (udev_device == NULL) + return NULL; + udev_device->refcount = 1; + udev_device->udev = udev; + udev_list_init(udev, &udev_device->devlinks_list, true); + udev_list_init(udev, &udev_device->properties_list, true); + udev_list_init(udev, &udev_device->sysattr_value_list, true); + udev_list_init(udev, &udev_device->sysattr_list, false); + udev_list_init(udev, &udev_device->tags_list, true); + udev_device->watch_handle = -1; + /* copy global properties */ + udev_list_entry_foreach(list_entry, udev_get_properties_list_entry(udev)) + udev_device_add_property(udev_device, + udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry)); + dbg(udev_device->udev, "udev_device: %p created\n", udev_device); + return udev_device; } /** @@ -618,62 +625,62 @@ struct udev_device *udev_device_new(struct udev *udev) **/ UDEV_EXPORT struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath) { - size_t len; - const char *subdir; - char path[UTIL_PATH_SIZE]; - char *pos; - struct stat statbuf; - struct udev_device *udev_device; - - if (udev == NULL) - return NULL; - if (syspath == NULL) - return NULL; - - /* path starts in sys */ - len = strlen(udev_get_sys_path(udev)); - if (strncmp(syspath, udev_get_sys_path(udev), len) != 0) { - info(udev, "not in sys :%s\n", syspath); - return NULL; - } - - /* path is not a root directory */ - subdir = &syspath[len+1]; - pos = strrchr(subdir, '/'); - if (pos == NULL || pos[1] == '\0' || pos < &subdir[2]) { - dbg(udev, "not a subdir :%s\n", syspath); - return NULL; - } - - /* resolve possible symlink to real path */ - util_strscpy(path, sizeof(path), syspath); - util_resolve_sys_link(udev, path, sizeof(path)); - - if (strncmp(&path[len], "/devices/", 9) == 0) { - char file[UTIL_PATH_SIZE]; - - /* all "devices" require a "uevent" file */ - util_strscpyl(file, sizeof(file), path, "/uevent", NULL); - if (stat(file, &statbuf) != 0) { - dbg(udev, "not a device: %s\n", syspath); - return NULL; - } - } else { - /* everything else just needs to be a directory */ - if (stat(path, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) { - dbg(udev, "directory not found: %s\n", syspath); - return NULL; - } - } - - udev_device = udev_device_new(udev); - if (udev_device == NULL) - return NULL; - - udev_device_set_syspath(udev_device, path); - info(udev, "device %p has devpath '%s'\n", udev_device, udev_device_get_devpath(udev_device)); - - return udev_device; + size_t len; + const char *subdir; + char path[UTIL_PATH_SIZE]; + char *pos; + struct stat statbuf; + struct udev_device *udev_device; + + if (udev == NULL) + return NULL; + if (syspath == NULL) + return NULL; + + /* path starts in sys */ + len = strlen(udev_get_sys_path(udev)); + if (strncmp(syspath, udev_get_sys_path(udev), len) != 0) { + info(udev, "not in sys :%s\n", syspath); + return NULL; + } + + /* path is not a root directory */ + subdir = &syspath[len+1]; + pos = strrchr(subdir, '/'); + if (pos == NULL || pos[1] == '\0' || pos < &subdir[2]) { + dbg(udev, "not a subdir :%s\n", syspath); + return NULL; + } + + /* resolve possible symlink to real path */ + util_strscpy(path, sizeof(path), syspath); + util_resolve_sys_link(udev, path, sizeof(path)); + + if (strncmp(&path[len], "/devices/", 9) == 0) { + char file[UTIL_PATH_SIZE]; + + /* all "devices" require a "uevent" file */ + util_strscpyl(file, sizeof(file), path, "/uevent", NULL); + if (stat(file, &statbuf) != 0) { + dbg(udev, "not a device: %s\n", syspath); + return NULL; + } + } else { + /* everything else just needs to be a directory */ + if (stat(path, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) { + dbg(udev, "directory not found: %s\n", syspath); + return NULL; + } + } + + udev_device = udev_device_new(udev); + if (udev_device == NULL) + return NULL; + + udev_device_set_syspath(udev_device, path); + info(udev, "device %p has devpath '%s'\n", udev_device, udev_device_get_devpath(udev_device)); + + return udev_device; } /** @@ -694,75 +701,75 @@ UDEV_EXPORT struct udev_device *udev_device_new_from_syspath(struct udev *udev, **/ UDEV_EXPORT struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) { - char path[UTIL_PATH_SIZE]; - const char *type_str; + char path[UTIL_PATH_SIZE]; + const char *type_str; - if (type == 'b') - type_str = "block"; - else if (type == 'c') - type_str = "char"; - else - return NULL; + if (type == 'b') + type_str = "block"; + else if (type == 'c') + type_str = "char"; + else + return NULL; - /* use /sys/dev/{block,char}/: link */ - snprintf(path, sizeof(path), "%s/dev/%s/%u:%u", - udev_get_sys_path(udev), type_str, major(devnum), minor(devnum)); - return udev_device_new_from_syspath(udev, path); + /* use /sys/dev/{block,char}/: link */ + snprintf(path, sizeof(path), "%s/dev/%s/%u:%u", + udev_get_sys_path(udev), type_str, major(devnum), minor(devnum)); + return udev_device_new_from_syspath(udev, path); } struct udev_device *udev_device_new_from_id_filename(struct udev *udev, char *id) { - char type; - int maj, min; - char subsys[UTIL_PATH_SIZE]; - char *sysname; - - switch(id[0]) { - case 'b': - case 'c': - if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3) - return NULL; - return udev_device_new_from_devnum(udev, type, makedev(maj, min)); - case 'n': { - int sk; - struct ifreq ifr; - struct udev_device *dev; - int ifindex; - - ifindex = strtoul(&id[1], NULL, 10); - if (ifindex <= 0) - return NULL; - - sk = socket(PF_INET, SOCK_DGRAM, 0); - if (sk < 0) - return NULL; - memset(&ifr, 0x00, sizeof(struct ifreq)); - ifr.ifr_ifindex = ifindex; - if (ioctl(sk, SIOCGIFNAME, &ifr) != 0) { - close(sk); - return NULL; - } - close(sk); - - dev = udev_device_new_from_subsystem_sysname(udev, "net", ifr.ifr_name); - if (dev == NULL) - return NULL; - if (udev_device_get_ifindex(dev) == ifindex) - return dev; - udev_device_unref(dev); - return NULL; - } - case '+': - util_strscpy(subsys, sizeof(subsys), &id[1]); - sysname = strchr(subsys, ':'); - if (sysname == NULL) - return NULL; - sysname[0] = '\0'; - sysname = &sysname[1]; - return udev_device_new_from_subsystem_sysname(udev, subsys, sysname); - default: - return NULL; - } + char type; + int maj, min; + char subsys[UTIL_PATH_SIZE]; + char *sysname; + + switch(id[0]) { + case 'b': + case 'c': + if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3) + return NULL; + return udev_device_new_from_devnum(udev, type, makedev(maj, min)); + case 'n': { + int sk; + struct ifreq ifr; + struct udev_device *dev; + int ifindex; + + ifindex = strtoul(&id[1], NULL, 10); + if (ifindex <= 0) + return NULL; + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return NULL; + memset(&ifr, 0x00, sizeof(struct ifreq)); + ifr.ifr_ifindex = ifindex; + if (ioctl(sk, SIOCGIFNAME, &ifr) != 0) { + close(sk); + return NULL; + } + close(sk); + + dev = udev_device_new_from_subsystem_sysname(udev, "net", ifr.ifr_name); + if (dev == NULL) + return NULL; + if (udev_device_get_ifindex(dev) == ifindex) + return dev; + udev_device_unref(dev); + return NULL; + } + case '+': + util_strscpy(subsys, sizeof(subsys), &id[1]); + sysname = strchr(subsys, ':'); + if (sysname == NULL) + return NULL; + sysname[0] = '\0'; + sysname = &sysname[1]; + return udev_device_new_from_subsystem_sysname(udev, subsys, sysname); + default: + return NULL; + } } /** @@ -782,72 +789,72 @@ struct udev_device *udev_device_new_from_id_filename(struct udev *udev, char *id **/ UDEV_EXPORT struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) { - char path_full[UTIL_PATH_SIZE]; - char *path; - size_t l; - struct stat statbuf; - - path = path_full; - l = util_strpcpyl(&path, sizeof(path_full), udev_get_sys_path(udev), NULL); - - if (strcmp(subsystem, "subsystem") == 0) { - util_strscpyl(path, l, "/subsystem/", sysname, NULL); - if (stat(path_full, &statbuf) == 0) - goto found; - - util_strscpyl(path, l, "/bus/", sysname, NULL); - if (stat(path_full, &statbuf) == 0) - goto found; - - util_strscpyl(path, l, "/class/", sysname, NULL); - if (stat(path_full, &statbuf) == 0) - goto found; - goto out; - } - - if (strcmp(subsystem, "module") == 0) { - util_strscpyl(path, l, "/module/", sysname, NULL); - if (stat(path_full, &statbuf) == 0) - goto found; - goto out; - } - - if (strcmp(subsystem, "drivers") == 0) { - char subsys[UTIL_NAME_SIZE]; - char *driver; - - util_strscpy(subsys, sizeof(subsys), sysname); - driver = strchr(subsys, ':'); - if (driver != NULL) { - driver[0] = '\0'; - driver = &driver[1]; - - util_strscpyl(path, l, "/subsystem/", subsys, "/drivers/", driver, NULL); - if (stat(path_full, &statbuf) == 0) - goto found; - - util_strscpyl(path, l, "/bus/", subsys, "/drivers/", driver, NULL); - if (stat(path_full, &statbuf) == 0) - goto found; - } - goto out; - } - - util_strscpyl(path, l, "/subsystem/", subsystem, "/devices/", sysname, NULL); - if (stat(path_full, &statbuf) == 0) - goto found; - - util_strscpyl(path, l, "/bus/", subsystem, "/devices/", sysname, NULL); - if (stat(path_full, &statbuf) == 0) - goto found; - - util_strscpyl(path, l, "/class/", subsystem, "/", sysname, NULL); - if (stat(path_full, &statbuf) == 0) - goto found; + char path_full[UTIL_PATH_SIZE]; + char *path; + size_t l; + struct stat statbuf; + + path = path_full; + l = util_strpcpyl(&path, sizeof(path_full), udev_get_sys_path(udev), NULL); + + if (strcmp(subsystem, "subsystem") == 0) { + util_strscpyl(path, l, "/subsystem/", sysname, NULL); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strscpyl(path, l, "/bus/", sysname, NULL); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strscpyl(path, l, "/class/", sysname, NULL); + if (stat(path_full, &statbuf) == 0) + goto found; + goto out; + } + + if (strcmp(subsystem, "module") == 0) { + util_strscpyl(path, l, "/module/", sysname, NULL); + if (stat(path_full, &statbuf) == 0) + goto found; + goto out; + } + + if (strcmp(subsystem, "drivers") == 0) { + char subsys[UTIL_NAME_SIZE]; + char *driver; + + util_strscpy(subsys, sizeof(subsys), sysname); + driver = strchr(subsys, ':'); + if (driver != NULL) { + driver[0] = '\0'; + driver = &driver[1]; + + util_strscpyl(path, l, "/subsystem/", subsys, "/drivers/", driver, NULL); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strscpyl(path, l, "/bus/", subsys, "/drivers/", driver, NULL); + if (stat(path_full, &statbuf) == 0) + goto found; + } + goto out; + } + + util_strscpyl(path, l, "/subsystem/", subsystem, "/devices/", sysname, NULL); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strscpyl(path, l, "/bus/", subsystem, "/devices/", sysname, NULL); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strscpyl(path, l, "/class/", subsystem, "/", sysname, NULL); + if (stat(path_full, &statbuf) == 0) + goto found; out: - return NULL; + return NULL; found: - return udev_device_new_from_syspath(udev, path_full); + return udev_device_new_from_syspath(udev, path_full); } /** @@ -866,46 +873,46 @@ found: **/ UDEV_EXPORT struct udev_device *udev_device_new_from_environment(struct udev *udev) { - int i; - struct udev_device *udev_device; + int i; + struct udev_device *udev_device; - udev_device = udev_device_new(udev); - if (udev_device == NULL) - return NULL; - udev_device_set_info_loaded(udev_device); + udev_device = udev_device_new(udev); + if (udev_device == NULL) + return NULL; + udev_device_set_info_loaded(udev_device); - for (i = 0; environ[i] != NULL; i++) - udev_device_add_property_from_string_parse(udev_device, environ[i]); + for (i = 0; environ[i] != NULL; i++) + udev_device_add_property_from_string_parse(udev_device, environ[i]); - if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) { - info(udev, "missing values, invalid device\n"); - udev_device_unref(udev_device); - udev_device = NULL; - } + if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) { + info(udev, "missing values, invalid device\n"); + udev_device_unref(udev_device); + udev_device = NULL; + } - return udev_device; + return udev_device; } static struct udev_device *device_new_from_parent(struct udev_device *udev_device) { - struct udev_device *udev_device_parent = NULL; - char path[UTIL_PATH_SIZE]; - const char *subdir; + struct udev_device *udev_device_parent = NULL; + char path[UTIL_PATH_SIZE]; + const char *subdir; - util_strscpy(path, sizeof(path), udev_device->syspath); - subdir = &path[strlen(udev_get_sys_path(udev_device->udev))+1]; - for (;;) { - char *pos; + util_strscpy(path, sizeof(path), udev_device->syspath); + subdir = &path[strlen(udev_get_sys_path(udev_device->udev))+1]; + for (;;) { + char *pos; - pos = strrchr(subdir, '/'); - if (pos == NULL || pos < &subdir[2]) - break; - pos[0] = '\0'; - udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path); - if (udev_device_parent != NULL) - return udev_device_parent; - } - return NULL; + pos = strrchr(subdir, '/'); + if (pos == NULL || pos < &subdir[2]) + break; + pos[0] = '\0'; + udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path); + if (udev_device_parent != NULL) + return udev_device_parent; + } + return NULL; } /** @@ -929,15 +936,15 @@ static struct udev_device *device_new_from_parent(struct udev_device *udev_devic **/ UDEV_EXPORT struct udev_device *udev_device_get_parent(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - if (!udev_device->parent_set) { - udev_device->parent_set = true; - udev_device->parent_device = device_new_from_parent(udev_device); - } - if (udev_device->parent_device != NULL) - dbg(udev_device->udev, "returning existing parent %p\n", udev_device->parent_device); - return udev_device->parent_device; + if (udev_device == NULL) + return NULL; + if (!udev_device->parent_set) { + udev_device->parent_set = true; + udev_device->parent_device = device_new_from_parent(udev_device); + } + if (udev_device->parent_device != NULL) + dbg(udev_device->udev, "returning existing parent %p\n", udev_device->parent_device); + return udev_device->parent_device; } /** @@ -964,27 +971,27 @@ UDEV_EXPORT struct udev_device *udev_device_get_parent(struct udev_device *udev_ **/ UDEV_EXPORT struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype) { - struct udev_device *parent; + struct udev_device *parent; - if (subsystem == NULL) - return NULL; + if (subsystem == NULL) + return NULL; - parent = udev_device_get_parent(udev_device); - while (parent != NULL) { - const char *parent_subsystem; - const char *parent_devtype; + parent = udev_device_get_parent(udev_device); + while (parent != NULL) { + const char *parent_subsystem; + const char *parent_devtype; - parent_subsystem = udev_device_get_subsystem(parent); - if (parent_subsystem != NULL && strcmp(parent_subsystem, subsystem) == 0) { - if (devtype == NULL) - break; - parent_devtype = udev_device_get_devtype(parent); - if (parent_devtype != NULL && strcmp(parent_devtype, devtype) == 0) - break; - } - parent = udev_device_get_parent(parent); - } - return parent; + parent_subsystem = udev_device_get_subsystem(parent); + if (parent_subsystem != NULL && strcmp(parent_subsystem, subsystem) == 0) { + if (devtype == NULL) + break; + parent_devtype = udev_device_get_devtype(parent); + if (parent_devtype != NULL && strcmp(parent_devtype, devtype) == 0) + break; + } + parent = udev_device_get_parent(parent); + } + return parent; } /** @@ -997,9 +1004,9 @@ UDEV_EXPORT struct udev_device *udev_device_get_parent_with_subsystem_devtype(st **/ UDEV_EXPORT struct udev *udev_device_get_udev(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - return udev_device->udev; + if (udev_device == NULL) + return NULL; + return udev_device->udev; } /** @@ -1012,10 +1019,10 @@ UDEV_EXPORT struct udev *udev_device_get_udev(struct udev_device *udev_device) **/ UDEV_EXPORT struct udev_device *udev_device_ref(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - udev_device->refcount++; - return udev_device; + if (udev_device == NULL) + return NULL; + udev_device->refcount++; + return udev_device; } /** @@ -1028,31 +1035,31 @@ UDEV_EXPORT struct udev_device *udev_device_ref(struct udev_device *udev_device) **/ UDEV_EXPORT void udev_device_unref(struct udev_device *udev_device) { - if (udev_device == NULL) - return; - udev_device->refcount--; - if (udev_device->refcount > 0) - return; - if (udev_device->parent_device != NULL) - udev_device_unref(udev_device->parent_device); - free(udev_device->syspath); - free(udev_device->sysname); - free(udev_device->devnode); - free(udev_device->subsystem); - free(udev_device->devtype); - udev_list_cleanup(&udev_device->devlinks_list); - udev_list_cleanup(&udev_device->properties_list); - udev_list_cleanup(&udev_device->sysattr_value_list); - udev_list_cleanup(&udev_device->sysattr_list); - udev_list_cleanup(&udev_device->tags_list); - free(udev_device->action); - free(udev_device->driver); - free(udev_device->devpath_old); - free(udev_device->id_filename); - free(udev_device->envp); - free(udev_device->monitor_buf); - dbg(udev_device->udev, "udev_device: %p released\n", udev_device); - free(udev_device); + if (udev_device == NULL) + return; + udev_device->refcount--; + if (udev_device->refcount > 0) + return; + if (udev_device->parent_device != NULL) + udev_device_unref(udev_device->parent_device); + free(udev_device->syspath); + free(udev_device->sysname); + free(udev_device->devnode); + free(udev_device->subsystem); + free(udev_device->devtype); + udev_list_cleanup(&udev_device->devlinks_list); + udev_list_cleanup(&udev_device->properties_list); + udev_list_cleanup(&udev_device->sysattr_value_list); + udev_list_cleanup(&udev_device->sysattr_list); + udev_list_cleanup(&udev_device->tags_list); + free(udev_device->action); + free(udev_device->driver); + free(udev_device->devpath_old); + free(udev_device->id_filename); + free(udev_device->envp); + free(udev_device->monitor_buf); + dbg(udev_device->udev, "udev_device: %p released\n", udev_device); + free(udev_device); } /** @@ -1066,9 +1073,9 @@ UDEV_EXPORT void udev_device_unref(struct udev_device *udev_device) **/ UDEV_EXPORT const char *udev_device_get_devpath(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - return udev_device->devpath; + if (udev_device == NULL) + return NULL; + return udev_device->devpath; } /** @@ -1082,9 +1089,9 @@ UDEV_EXPORT const char *udev_device_get_devpath(struct udev_device *udev_device) **/ UDEV_EXPORT const char *udev_device_get_syspath(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - return udev_device->syspath; + if (udev_device == NULL) + return NULL; + return udev_device->syspath; } /** @@ -1095,9 +1102,9 @@ UDEV_EXPORT const char *udev_device_get_syspath(struct udev_device *udev_device) **/ UDEV_EXPORT const char *udev_device_get_sysname(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - return udev_device->sysname; + if (udev_device == NULL) + return NULL; + return udev_device->sysname; } /** @@ -1108,9 +1115,9 @@ UDEV_EXPORT const char *udev_device_get_sysname(struct udev_device *udev_device) **/ UDEV_EXPORT const char *udev_device_get_sysnum(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - return udev_device->sysnum; + if (udev_device == NULL) + return NULL; + return udev_device->sysnum; } /** @@ -1124,13 +1131,13 @@ UDEV_EXPORT const char *udev_device_get_sysnum(struct udev_device *udev_device) **/ UDEV_EXPORT const char *udev_device_get_devnode(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - if (udev_device->devnode != NULL) - return udev_device->devnode; - if (!udev_device->info_loaded) - udev_device_read_uevent_file(udev_device); - return udev_device->devnode; + if (udev_device == NULL) + return NULL; + if (udev_device->devnode != NULL) + return udev_device->devnode; + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnode; } /** @@ -1148,17 +1155,17 @@ UDEV_EXPORT const char *udev_device_get_devnode(struct udev_device *udev_device) **/ UDEV_EXPORT struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - if (!udev_device->info_loaded) - udev_device_read_db(udev_device, NULL); - return udev_list_get_entry(&udev_device->devlinks_list); + if (udev_device == NULL) + return NULL; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_list_get_entry(&udev_device->devlinks_list); } void udev_device_cleanup_devlinks_list(struct udev_device *udev_device) { - udev_device->devlinks_uptodate = false; - udev_list_cleanup(&udev_device->devlinks_list); + udev_device->devlinks_uptodate = false; + udev_list_cleanup(&udev_device->devlinks_list); } /** @@ -1175,45 +1182,45 @@ void udev_device_cleanup_devlinks_list(struct udev_device *udev_device) **/ UDEV_EXPORT struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - if (!udev_device->info_loaded) { - udev_device_read_uevent_file(udev_device); - udev_device_read_db(udev_device, NULL); - } - if (!udev_device->devlinks_uptodate) { - char symlinks[UTIL_PATH_SIZE]; - struct udev_list_entry *list_entry; - - udev_device->devlinks_uptodate = true; - list_entry = udev_device_get_devlinks_list_entry(udev_device); - if (list_entry != NULL) { - char *s; - size_t l; - - s = symlinks; - l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL); - udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry)) - l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL); - udev_device_add_property(udev_device, "DEVLINKS", symlinks); - } - } - if (!udev_device->tags_uptodate) { - udev_device->tags_uptodate = true; - if (udev_device_get_tags_list_entry(udev_device) != NULL) { - char tags[UTIL_PATH_SIZE]; - struct udev_list_entry *list_entry; - char *s; - size_t l; - - s = tags; - l = util_strpcpyl(&s, sizeof(tags), ":", NULL); - udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device)) - l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL); - udev_device_add_property(udev_device, "TAGS", tags); - } - } - return udev_list_get_entry(&udev_device->properties_list); + if (udev_device == NULL) + return NULL; + if (!udev_device->info_loaded) { + udev_device_read_uevent_file(udev_device); + udev_device_read_db(udev_device, NULL); + } + if (!udev_device->devlinks_uptodate) { + char symlinks[UTIL_PATH_SIZE]; + struct udev_list_entry *list_entry; + + udev_device->devlinks_uptodate = true; + list_entry = udev_device_get_devlinks_list_entry(udev_device); + if (list_entry != NULL) { + char *s; + size_t l; + + s = symlinks; + l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL); + udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry)) + l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL); + udev_device_add_property(udev_device, "DEVLINKS", symlinks); + } + } + if (!udev_device->tags_uptodate) { + udev_device->tags_uptodate = true; + if (udev_device_get_tags_list_entry(udev_device) != NULL) { + char tags[UTIL_PATH_SIZE]; + struct udev_list_entry *list_entry; + char *s; + size_t l; + + s = tags; + l = util_strpcpyl(&s, sizeof(tags), ":", NULL); + udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device)) + l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL); + udev_device_add_property(udev_device, "TAGS", tags); + } + } + return udev_list_get_entry(&udev_device->properties_list); } /** @@ -1228,9 +1235,9 @@ UDEV_EXPORT struct udev_list_entry *udev_device_get_properties_list_entry(struct **/ UDEV_EXPORT const char *udev_device_get_action(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - return udev_device->action; + if (udev_device == NULL) + return NULL; + return udev_device->action; } /** @@ -1247,32 +1254,32 @@ UDEV_EXPORT const char *udev_device_get_action(struct udev_device *udev_device) **/ UDEV_EXPORT unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device) { - unsigned long long now; + unsigned long long now; - if (udev_device == NULL) - return 0; - if (!udev_device->info_loaded) - udev_device_read_db(udev_device, NULL); - if (udev_device->usec_initialized == 0) - return 0; - now = now_usec(); - if (now == 0) - return 0; - return now - udev_device->usec_initialized; + if (udev_device == NULL) + return 0; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + if (udev_device->usec_initialized == 0) + return 0; + now = now_usec(); + if (now == 0) + return 0; + return now - udev_device->usec_initialized; } unsigned long long udev_device_get_usec_initialized(struct udev_device *udev_device) { - return udev_device->usec_initialized; + return udev_device->usec_initialized; } void udev_device_set_usec_initialized(struct udev_device *udev_device, unsigned long long usec_initialized) { - char num[32]; + char num[32]; - udev_device->usec_initialized = usec_initialized; - snprintf(num, sizeof(num), "%llu", usec_initialized); - udev_device_add_property(udev_device, "USEC_INITIALIZED", num); + udev_device->usec_initialized = usec_initialized; + snprintf(num, sizeof(num), "%llu", usec_initialized); + udev_device_add_property(udev_device, "USEC_INITIALIZED", num); } /** @@ -1287,139 +1294,139 @@ void udev_device_set_usec_initialized(struct udev_device *udev_device, unsigned **/ UDEV_EXPORT const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr) { - struct udev_list_entry *list_entry; - char path[UTIL_PATH_SIZE]; - char value[4096]; - struct stat statbuf; - int fd; - ssize_t size; - const char *val = NULL; - - if (udev_device == NULL) - return NULL; - if (sysattr == NULL) - return NULL; - - /* look for possibly already cached result */ - list_entry = udev_list_get_entry(&udev_device->sysattr_value_list); - list_entry = udev_list_entry_get_by_name(list_entry, sysattr); - if (list_entry != NULL) { - dbg(udev_device->udev, "got '%s' (%s) from cache\n", - sysattr, udev_list_entry_get_value(list_entry)); - return udev_list_entry_get_value(list_entry); - } - - util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL); - if (lstat(path, &statbuf) != 0) { - dbg(udev_device->udev, "no attribute '%s', keep negative entry\n", path); - udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, NULL); - goto out; - } - - if (S_ISLNK(statbuf.st_mode)) { - struct udev_device *dev; - - /* - * Some core links return only the last element of the target path, - * these are just values, the paths should not be exposed. - */ - if (strcmp(sysattr, "driver") == 0 || - strcmp(sysattr, "subsystem") == 0 || - strcmp(sysattr, "module") == 0) { - if (util_get_sys_core_link_value(udev_device->udev, sysattr, - udev_device->syspath, value, sizeof(value)) < 0) - return NULL; - dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, value); - list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value); - val = udev_list_entry_get_value(list_entry); - goto out; - } - - /* resolve link to a device and return its syspath */ - util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL); - dev = udev_device_new_from_syspath(udev_device->udev, path); - if (dev != NULL) { - list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, - udev_device_get_syspath(dev)); - val = udev_list_entry_get_value(list_entry); - udev_device_unref(dev); - } - - goto out; - } - - /* skip directories */ - if (S_ISDIR(statbuf.st_mode)) - goto out; - - /* skip non-readable files */ - if ((statbuf.st_mode & S_IRUSR) == 0) - goto out; - - /* read attribute value */ - fd = open(path, O_RDONLY|O_CLOEXEC); - if (fd < 0) { - dbg(udev_device->udev, "attribute '%s' can not be opened\n", path); - goto out; - } - size = read(fd, value, sizeof(value)); - close(fd); - if (size < 0) - goto out; - if (size == sizeof(value)) - goto out; - - /* got a valid value, store it in cache and return it */ - value[size] = '\0'; - util_remove_trailing_chars(value, '\n'); - dbg(udev_device->udev, "'%s' has attribute value '%s'\n", path, value); - list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value); - val = udev_list_entry_get_value(list_entry); + struct udev_list_entry *list_entry; + char path[UTIL_PATH_SIZE]; + char value[4096]; + struct stat statbuf; + int fd; + ssize_t size; + const char *val = NULL; + + if (udev_device == NULL) + return NULL; + if (sysattr == NULL) + return NULL; + + /* look for possibly already cached result */ + list_entry = udev_list_get_entry(&udev_device->sysattr_value_list); + list_entry = udev_list_entry_get_by_name(list_entry, sysattr); + if (list_entry != NULL) { + dbg(udev_device->udev, "got '%s' (%s) from cache\n", + sysattr, udev_list_entry_get_value(list_entry)); + return udev_list_entry_get_value(list_entry); + } + + util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL); + if (lstat(path, &statbuf) != 0) { + dbg(udev_device->udev, "no attribute '%s', keep negative entry\n", path); + udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, NULL); + goto out; + } + + if (S_ISLNK(statbuf.st_mode)) { + struct udev_device *dev; + + /* + * Some core links return only the last element of the target path, + * these are just values, the paths should not be exposed. + */ + if (strcmp(sysattr, "driver") == 0 || + strcmp(sysattr, "subsystem") == 0 || + strcmp(sysattr, "module") == 0) { + if (util_get_sys_core_link_value(udev_device->udev, sysattr, + udev_device->syspath, value, sizeof(value)) < 0) + return NULL; + dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, value); + list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value); + val = udev_list_entry_get_value(list_entry); + goto out; + } + + /* resolve link to a device and return its syspath */ + util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL); + dev = udev_device_new_from_syspath(udev_device->udev, path); + if (dev != NULL) { + list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, + udev_device_get_syspath(dev)); + val = udev_list_entry_get_value(list_entry); + udev_device_unref(dev); + } + + goto out; + } + + /* skip directories */ + if (S_ISDIR(statbuf.st_mode)) + goto out; + + /* skip non-readable files */ + if ((statbuf.st_mode & S_IRUSR) == 0) + goto out; + + /* read attribute value */ + fd = open(path, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + dbg(udev_device->udev, "attribute '%s' can not be opened\n", path); + goto out; + } + size = read(fd, value, sizeof(value)); + close(fd); + if (size < 0) + goto out; + if (size == sizeof(value)) + goto out; + + /* got a valid value, store it in cache and return it */ + value[size] = '\0'; + util_remove_trailing_chars(value, '\n'); + dbg(udev_device->udev, "'%s' has attribute value '%s'\n", path, value); + list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value); + val = udev_list_entry_get_value(list_entry); out: - return val; + return val; } static int udev_device_sysattr_list_read(struct udev_device *udev_device) { - struct dirent *dent; - DIR *dir; - int num = 0; + struct dirent *dent; + DIR *dir; + int num = 0; - if (udev_device == NULL) - return -1; - if (udev_device->sysattr_list_read) - return 0; + if (udev_device == NULL) + return -1; + if (udev_device->sysattr_list_read) + return 0; - dir = opendir(udev_device_get_syspath(udev_device)); - if (!dir) { - dbg(udev_device->udev, "sysfs dir '%s' can not be opened\n", - udev_device_get_syspath(udev_device)); - return -1; - } + dir = opendir(udev_device_get_syspath(udev_device)); + if (!dir) { + dbg(udev_device->udev, "sysfs dir '%s' can not be opened\n", + udev_device_get_syspath(udev_device)); + return -1; + } - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char path[UTIL_PATH_SIZE]; - struct stat statbuf; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char path[UTIL_PATH_SIZE]; + struct stat statbuf; - /* only handle symlinks and regular files */ - if (dent->d_type != DT_LNK && dent->d_type != DT_REG) - continue; + /* only handle symlinks and regular files */ + if (dent->d_type != DT_LNK && dent->d_type != DT_REG) + continue; - util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL); - if (lstat(path, &statbuf) != 0) - continue; - if ((statbuf.st_mode & S_IRUSR) == 0) - continue; + util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL); + if (lstat(path, &statbuf) != 0) + continue; + if ((statbuf.st_mode & S_IRUSR) == 0) + continue; - udev_list_entry_add(&udev_device->sysattr_list, dent->d_name, NULL); - num++; - } + udev_list_entry_add(&udev_device->sysattr_list, dent->d_name, NULL); + num++; + } - closedir(dir); - dbg(udev_device->udev, "found %d sysattrs for '%s'\n", num, udev_device_get_syspath(udev_device)); - udev_device->sysattr_list_read = true; + closedir(dir); + dbg(udev_device->udev, "found %d sysattrs for '%s'\n", num, udev_device_get_syspath(udev_device)); + udev_device->sysattr_list_read = true; - return num; + return num; } /** @@ -1434,114 +1441,114 @@ static int udev_device_sysattr_list_read(struct udev_device *udev_device) **/ UDEV_EXPORT struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device) { - if (!udev_device->sysattr_list_read) { - int ret; - ret = udev_device_sysattr_list_read(udev_device); - if (0 > ret) - return NULL; - } + if (!udev_device->sysattr_list_read) { + int ret; + ret = udev_device_sysattr_list_read(udev_device); + if (0 > ret) + return NULL; + } - return udev_list_get_entry(&udev_device->sysattr_list); + return udev_list_get_entry(&udev_device->sysattr_list); } int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath) { - const char *pos; - size_t len; + const char *pos; + size_t len; - free(udev_device->syspath); - udev_device->syspath = strdup(syspath); - if (udev_device->syspath == NULL) - return -ENOMEM; - udev_device->devpath = &udev_device->syspath[strlen(udev_get_sys_path(udev_device->udev))]; - udev_device_add_property(udev_device, "DEVPATH", udev_device->devpath); + free(udev_device->syspath); + udev_device->syspath = strdup(syspath); + if (udev_device->syspath == NULL) + return -ENOMEM; + udev_device->devpath = &udev_device->syspath[strlen(udev_get_sys_path(udev_device->udev))]; + udev_device_add_property(udev_device, "DEVPATH", udev_device->devpath); - pos = strrchr(udev_device->syspath, '/'); - if (pos == NULL) - return -EINVAL; - udev_device->sysname = strdup(&pos[1]); - if (udev_device->sysname == NULL) - return -ENOMEM; + pos = strrchr(udev_device->syspath, '/'); + if (pos == NULL) + return -EINVAL; + udev_device->sysname = strdup(&pos[1]); + if (udev_device->sysname == NULL) + return -ENOMEM; - /* some devices have '!' in their name, change that to '/' */ - len = 0; - while (udev_device->sysname[len] != '\0') { - if (udev_device->sysname[len] == '!') - udev_device->sysname[len] = '/'; - len++; - } + /* some devices have '!' in their name, change that to '/' */ + len = 0; + while (udev_device->sysname[len] != '\0') { + if (udev_device->sysname[len] == '!') + udev_device->sysname[len] = '/'; + len++; + } - /* trailing number */ - while (len > 0 && isdigit(udev_device->sysname[--len])) - udev_device->sysnum = &udev_device->sysname[len]; + /* trailing number */ + while (len > 0 && isdigit(udev_device->sysname[--len])) + udev_device->sysnum = &udev_device->sysname[len]; - /* sysname is completely numeric */ - if (len == 0) - udev_device->sysnum = NULL; + /* sysname is completely numeric */ + if (len == 0) + udev_device->sysnum = NULL; - return 0; + return 0; } int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode) { - free(udev_device->devnode); - if (devnode[0] != '/') { - if (asprintf(&udev_device->devnode, "%s/%s", udev_get_dev_path(udev_device->udev), devnode) < 0) - udev_device->devnode = NULL; - } else { - udev_device->devnode = strdup(devnode); - } - if (udev_device->devnode == NULL) - return -ENOMEM; - udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode); - return 0; + free(udev_device->devnode); + if (devnode[0] != '/') { + if (asprintf(&udev_device->devnode, "%s/%s", udev_get_dev_path(udev_device->udev), devnode) < 0) + udev_device->devnode = NULL; + } else { + udev_device->devnode = strdup(devnode); + } + if (udev_device->devnode == NULL) + return -ENOMEM; + udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode); + return 0; } int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink, int unique) { - struct udev_list_entry *list_entry; + struct udev_list_entry *list_entry; - udev_device->devlinks_uptodate = false; - list_entry = udev_list_entry_add(&udev_device->devlinks_list, devlink, NULL); - if (list_entry == NULL) - return -ENOMEM; - if (unique) - udev_list_entry_set_num(list_entry, true); - return 0; + udev_device->devlinks_uptodate = false; + list_entry = udev_list_entry_add(&udev_device->devlinks_list, devlink, NULL); + if (list_entry == NULL) + return -ENOMEM; + if (unique) + udev_list_entry_set_num(list_entry, true); + return 0; } const char *udev_device_get_id_filename(struct udev_device *udev_device) { - if (udev_device->id_filename == NULL) { - if (udev_device_get_subsystem(udev_device) == NULL) - return NULL; - - if (major(udev_device_get_devnum(udev_device)) > 0) { - /* use dev_t -- b259:131072, c254:0 */ - if (asprintf(&udev_device->id_filename, "%c%u:%u", - strcmp(udev_device_get_subsystem(udev_device), "block") == 0 ? 'b' : 'c', - major(udev_device_get_devnum(udev_device)), - minor(udev_device_get_devnum(udev_device))) < 0) - udev_device->id_filename = NULL; - } else if (udev_device_get_ifindex(udev_device) > 0) { - /* use netdev ifindex -- n3 */ - if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0) - udev_device->id_filename = NULL; - } else { - /* - * use $subsys:$syname -- pci:0000:00:1f.2 - * sysname() has '!' translated, get it from devpath - */ - const char *sysname; - sysname = strrchr(udev_device->devpath, '/'); - if (sysname == NULL) - return NULL; - sysname = &sysname[1]; - if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0) - udev_device->id_filename = NULL; - } - } - return udev_device->id_filename; + if (udev_device->id_filename == NULL) { + if (udev_device_get_subsystem(udev_device) == NULL) + return NULL; + + if (major(udev_device_get_devnum(udev_device)) > 0) { + /* use dev_t -- b259:131072, c254:0 */ + if (asprintf(&udev_device->id_filename, "%c%u:%u", + strcmp(udev_device_get_subsystem(udev_device), "block") == 0 ? 'b' : 'c', + major(udev_device_get_devnum(udev_device)), + minor(udev_device_get_devnum(udev_device))) < 0) + udev_device->id_filename = NULL; + } else if (udev_device_get_ifindex(udev_device) > 0) { + /* use netdev ifindex -- n3 */ + if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0) + udev_device->id_filename = NULL; + } else { + /* + * use $subsys:$syname -- pci:0000:00:1f.2 + * sysname() has '!' translated, get it from devpath + */ + const char *sysname; + sysname = strrchr(udev_device->devpath, '/'); + if (sysname == NULL) + return NULL; + sysname = &sysname[1]; + if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0) + udev_device->id_filename = NULL; + } + } + return udev_device->id_filename; } /** @@ -1559,30 +1566,30 @@ const char *udev_device_get_id_filename(struct udev_device *udev_device) **/ UDEV_EXPORT int udev_device_get_is_initialized(struct udev_device *udev_device) { - if (!udev_device->info_loaded) - udev_device_read_db(udev_device, NULL); - return udev_device->is_initialized; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_device->is_initialized; } void udev_device_set_is_initialized(struct udev_device *udev_device) { - udev_device->is_initialized = true; + udev_device->is_initialized = true; } int udev_device_add_tag(struct udev_device *udev_device, const char *tag) { - if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL) - return -EINVAL; - udev_device->tags_uptodate = false; - if (udev_list_entry_add(&udev_device->tags_list, tag, NULL) != NULL) - return 0; - return -ENOMEM; + if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL) + return -EINVAL; + udev_device->tags_uptodate = false; + if (udev_list_entry_add(&udev_device->tags_list, tag, NULL) != NULL) + return 0; + return -ENOMEM; } void udev_device_cleanup_tags_list(struct udev_device *udev_device) { - udev_device->tags_uptodate = false; - udev_list_cleanup(&udev_device->tags_list); + udev_device->tags_uptodate = false; + udev_list_cleanup(&udev_device->tags_list); } /** @@ -1598,140 +1605,140 @@ void udev_device_cleanup_tags_list(struct udev_device *udev_device) **/ UDEV_EXPORT struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; - if (!udev_device->info_loaded) - udev_device_read_db(udev_device, NULL); - return udev_list_get_entry(&udev_device->tags_list); + if (udev_device == NULL) + return NULL; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_list_get_entry(&udev_device->tags_list); } UDEV_EXPORT int udev_device_has_tag(struct udev_device *udev_device, const char *tag) { - struct udev_list_entry *list_entry; + struct udev_list_entry *list_entry; - if (udev_device == NULL) - return false; - if (!udev_device->info_loaded) - udev_device_read_db(udev_device, NULL); - list_entry = udev_device_get_tags_list_entry(udev_device); - if (udev_list_entry_get_by_name(list_entry, tag) != NULL) - return true; - return false; + if (udev_device == NULL) + return false; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + list_entry = udev_device_get_tags_list_entry(udev_device); + if (udev_list_entry_get_by_name(list_entry, tag) != NULL) + return true; + return false; } -#define ENVP_SIZE 128 -#define MONITOR_BUF_SIZE 4096 +#define ENVP_SIZE 128 +#define MONITOR_BUF_SIZE 4096 static int update_envp_monitor_buf(struct udev_device *udev_device) { - struct udev_list_entry *list_entry; - char *s; - size_t l; - unsigned int i; - - /* monitor buffer of property strings */ - free(udev_device->monitor_buf); - udev_device->monitor_buf_len = 0; - udev_device->monitor_buf = malloc(MONITOR_BUF_SIZE); - if (udev_device->monitor_buf == NULL) - return -ENOMEM; - - /* envp array, strings will point into monitor buffer */ - if (udev_device->envp == NULL) - udev_device->envp = malloc(sizeof(char *) * ENVP_SIZE); - if (udev_device->envp == NULL) - return -ENOMEM; - - i = 0; - s = udev_device->monitor_buf; - l = MONITOR_BUF_SIZE; - udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) { - const char *key; - - key = udev_list_entry_get_name(list_entry); - /* skip private variables */ - if (key[0] == '.') - continue; - - /* add string to envp array */ - udev_device->envp[i++] = s; - if (i+1 >= ENVP_SIZE) - return -EINVAL; - - /* add property string to monitor buffer */ - l = util_strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL); - if (l == 0) - return -EINVAL; - /* advance past the trailing '\0' that util_strpcpyl() guarantees */ - s++; - l--; - } - udev_device->envp[i] = NULL; - udev_device->monitor_buf_len = s - udev_device->monitor_buf; - udev_device->envp_uptodate = true; - dbg(udev_device->udev, "filled envp/monitor buffer, %u properties, %zu bytes\n", - i, udev_device->monitor_buf_len); - return 0; + struct udev_list_entry *list_entry; + char *s; + size_t l; + unsigned int i; + + /* monitor buffer of property strings */ + free(udev_device->monitor_buf); + udev_device->monitor_buf_len = 0; + udev_device->monitor_buf = malloc(MONITOR_BUF_SIZE); + if (udev_device->monitor_buf == NULL) + return -ENOMEM; + + /* envp array, strings will point into monitor buffer */ + if (udev_device->envp == NULL) + udev_device->envp = malloc(sizeof(char *) * ENVP_SIZE); + if (udev_device->envp == NULL) + return -ENOMEM; + + i = 0; + s = udev_device->monitor_buf; + l = MONITOR_BUF_SIZE; + udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) { + const char *key; + + key = udev_list_entry_get_name(list_entry); + /* skip private variables */ + if (key[0] == '.') + continue; + + /* add string to envp array */ + udev_device->envp[i++] = s; + if (i+1 >= ENVP_SIZE) + return -EINVAL; + + /* add property string to monitor buffer */ + l = util_strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL); + if (l == 0) + return -EINVAL; + /* advance past the trailing '\0' that util_strpcpyl() guarantees */ + s++; + l--; + } + udev_device->envp[i] = NULL; + udev_device->monitor_buf_len = s - udev_device->monitor_buf; + udev_device->envp_uptodate = true; + dbg(udev_device->udev, "filled envp/monitor buffer, %u properties, %zu bytes\n", + i, udev_device->monitor_buf_len); + return 0; } char **udev_device_get_properties_envp(struct udev_device *udev_device) { - if (!udev_device->envp_uptodate) - if (update_envp_monitor_buf(udev_device) != 0) - return NULL; - return udev_device->envp; + if (!udev_device->envp_uptodate) + if (update_envp_monitor_buf(udev_device) != 0) + return NULL; + return udev_device->envp; } ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf) { - if (!udev_device->envp_uptodate) - if (update_envp_monitor_buf(udev_device) != 0) - return -EINVAL; - *buf = udev_device->monitor_buf; - return udev_device->monitor_buf_len; + if (!udev_device->envp_uptodate) + if (update_envp_monitor_buf(udev_device) != 0) + return -EINVAL; + *buf = udev_device->monitor_buf; + return udev_device->monitor_buf_len; } int udev_device_set_action(struct udev_device *udev_device, const char *action) { - free(udev_device->action); - udev_device->action = strdup(action); - if (udev_device->action == NULL) - return -ENOMEM; - udev_device_add_property(udev_device, "ACTION", udev_device->action); - return 0; + free(udev_device->action); + udev_device->action = strdup(action); + if (udev_device->action == NULL) + return -ENOMEM; + udev_device_add_property(udev_device, "ACTION", udev_device->action); + return 0; } int udev_device_get_devlink_priority(struct udev_device *udev_device) { - if (!udev_device->info_loaded) - udev_device_read_db(udev_device, NULL); - return udev_device->devlink_priority; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_device->devlink_priority; } int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio) { - udev_device->devlink_priority = prio; - return 0; + udev_device->devlink_priority = prio; + return 0; } int udev_device_get_watch_handle(struct udev_device *udev_device) { - if (!udev_device->info_loaded) - udev_device_read_db(udev_device, NULL); - return udev_device->watch_handle; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_device->watch_handle; } int udev_device_set_watch_handle(struct udev_device *udev_device, int handle) { - udev_device->watch_handle = handle; - return 0; + udev_device->watch_handle = handle; + return 0; } bool udev_device_get_db_persist(struct udev_device *udev_device) { - return udev_device->db_persist; + return udev_device->db_persist; } void udev_device_set_db_persist(struct udev_device *udev_device) { - udev_device->db_persist = true; + udev_device->db_persist = true; }