X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udev%2Flib%2Flibudev-device.c;h=8812f1fc8432a451125f1b93e8ef250c09b040f2;hb=f6bb9e981aea06f1a7460868fb60f1a9ff14c504;hp=daf2217765ee373efc0b326696f77d7b27cd07f8;hpb=ebacd6ecc301cb4cdacd1a18f6514c4a839f5999;p=elogind.git diff --git a/udev/lib/libudev-device.c b/udev/lib/libudev-device.c index daf221776..8812f1fc8 100644 --- a/udev/lib/libudev-device.c +++ b/udev/lib/libudev-device.c @@ -31,37 +31,39 @@ #include "libudev.h" #include "libudev-private.h" +#define ENVP_SIZE 128 + struct udev_device { - int refcount; struct udev *udev; struct udev_device *parent_device; - int parent_set; char *syspath; const char *devpath; char *sysname; const char *sysnum; char *devnode; char *subsystem; - int subsystem_set; - struct udev_list_node devlinks_list; - int devlinks_uptodate; - struct udev_list_node properties_list; - char *envp[128]; - int envp_uptodate; + char **envp; char *driver; - int driver_set; - dev_t devnum; char *action; - int event_timeout; char *devpath_old; char *physdevpath; - int timeout; + struct udev_list_node devlinks_list; + struct udev_list_node properties_list; + struct udev_list_node sysattr_list; unsigned long long int seqnum; + int event_timeout; + int timeout; int num_fake_partitions; int devlink_priority; - int ignore_remove; - struct udev_list_node attr_list; - int info_loaded; + int refcount; + dev_t devnum; + unsigned int parent_set:1; + unsigned int subsystem_set:1; + unsigned int devlinks_uptodate:1; + unsigned int envp_uptodate:1; + unsigned int driver_set:1; + unsigned int info_loaded:1; + unsigned int ignore_remove:1; }; static size_t devpath_to_db_path(struct udev *udev, const char *devpath, char *filename, size_t len) @@ -75,7 +77,7 @@ static size_t devpath_to_db_path(struct udev *udev, const char *devpath, char *f return util_path_encode(&filename[start], len - start); } -static int device_read_db(struct udev_device *udev_device) +int udev_device_read_db(struct udev_device *udev_device) { struct stat stats; char filename[UTIL_PATH_SIZE]; @@ -220,7 +222,7 @@ static void device_load_info(struct udev_device *device) { device->info_loaded = 1; udev_device_read_uevent_file(device); - device_read_db(device); + udev_device_read_db(device); } void udev_device_set_info_loaded(struct udev_device *device) @@ -236,15 +238,14 @@ struct udev_device *device_new(struct udev *udev) if (udev == NULL) return NULL; - udev_device = malloc(sizeof(struct udev_device)); + udev_device = calloc(1, sizeof(struct udev_device)); if (udev_device == NULL) return NULL; - memset(udev_device, 0x00, sizeof(struct udev_device)); udev_device->refcount = 1; udev_device->udev = udev; udev_list_init(&udev_device->devlinks_list); udev_list_init(&udev_device->properties_list); - udev_list_init(&udev_device->attr_list); + udev_list_init(&udev_device->sysattr_list); udev_device->event_timeout = -1; /* copy global properties */ udev_list_entry_foreach(list_entry, udev_get_properties_list_entry(udev)) @@ -604,15 +605,18 @@ void udev_device_unref(struct udev_device *udev_device) free(udev_device->sysname); free(udev_device->devnode); free(udev_device->subsystem); - udev_list_cleanup(udev_device->udev, &udev_device->devlinks_list); - udev_list_cleanup(udev_device->udev, &udev_device->properties_list); + udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list); + udev_list_cleanup_entries(udev_device->udev, &udev_device->properties_list); free(udev_device->action); free(udev_device->driver); free(udev_device->devpath_old); free(udev_device->physdevpath); - udev_list_cleanup(udev_device->udev, &udev_device->attr_list); - for (i = 0; i < ARRAY_SIZE(udev_device->envp) && udev_device->envp[i] != NULL; i++) - free(udev_device->envp[i]); + udev_list_cleanup_entries(udev_device->udev, &udev_device->sysattr_list); + if (udev_device->envp != NULL) { + for (i = 0; i < ENVP_SIZE && udev_device->envp[i] != NULL; i++) + free(udev_device->envp[i]); + free(udev_device->envp); + } info(udev_device->udev, "udev_device: %p released\n", udev_device); free(udev_device); } @@ -747,7 +751,7 @@ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device * void udev_device_cleanup_devlinks_list(struct udev_device *udev_device) { udev_device->devlinks_uptodate = 0; - udev_list_cleanup(udev_device->udev, &udev_device->devlinks_list); + udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list); } /** @@ -823,7 +827,7 @@ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device) return udev_device->seqnum; } -const char *udev_device_get_attr_value(struct udev_device *udev_device, const char *attr) +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]; @@ -835,25 +839,25 @@ const char *udev_device_get_attr_value(struct udev_device *udev_device, const ch if (udev_device == NULL) return NULL; - if (attr == NULL) + if (sysattr == NULL) return NULL; /* look for possibly already cached result */ - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_device->attr_list)) { - if (strcmp(udev_list_entry_get_name(list_entry), attr) == 0) { + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_device->sysattr_list)) { + if (strcmp(udev_list_entry_get_name(list_entry), sysattr) == 0) { info(udev_device->udev, "got '%s' (%s) from cache\n", - attr, udev_list_entry_get_value(list_entry)); + sysattr, udev_list_entry_get_value(list_entry)); return udev_list_entry_get_value(list_entry); } } util_strlcpy(path, udev_device_get_syspath(udev_device), sizeof(path)); util_strlcat(path, "/", sizeof(path)); - util_strlcat(path, attr, sizeof(path)); + util_strlcat(path, sysattr, sizeof(path)); if (lstat(path, &statbuf) != 0) { info(udev_device->udev, "no attribute '%s', keep negative entry\n", path); - udev_list_entry_add(udev_device->udev, &udev_device->attr_list, attr, NULL, 0, 0); + udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, NULL, 0, 0); goto out; } @@ -869,8 +873,8 @@ const char *udev_device_get_attr_value(struct udev_device *udev_device, const ch pos = strrchr(target, '/'); if (pos != NULL) { pos = &pos[1]; - info(udev_device->udev, "cache '%s' with link value '%s'\n", attr, pos); - list_entry = udev_list_entry_add(udev_device->udev, &udev_device->attr_list, attr, pos, 0, 0); + info(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos); + list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, pos, 0, 0); val = udev_list_entry_get_value(list_entry); } } @@ -902,7 +906,7 @@ const char *udev_device_get_attr_value(struct udev_device *udev_device, const ch value[size] = '\0'; util_remove_trailing_chars(value, '\n'); info(udev_device->udev, "'%s' has attribute value '%s'\n", path, value); - list_entry = udev_list_entry_add(udev_device->udev, &udev_device->attr_list, attr, value, 0, 0); + list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, value, 0, 0); val = udev_list_entry_get_value(list_entry); out: return val; @@ -936,8 +940,13 @@ int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath } /* trailing number */ - while (isdigit(udev_device->sysname[--len])) + 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; + return 0; } @@ -992,7 +1001,7 @@ struct udev_list_entry *udev_device_add_property_from_string(struct udev_device char name[UTIL_PATH_SIZE]; char *val; - strncpy(name, property, sizeof(name)); + util_strlcpy(name, property, sizeof(name)); val = strchr(name, '='); if (val == NULL) return NULL; @@ -1009,14 +1018,18 @@ char **udev_device_get_properties_envp(struct udev_device *udev_device) unsigned int i; struct udev_list_entry *list_entry; - for (i = 0; i < ARRAY_SIZE(udev_device->envp) && udev_device->envp[i] != NULL; i++) - free(udev_device->envp[i]); + if (udev_device->envp) { + for (i = 0; i < ENVP_SIZE && udev_device->envp[i] != NULL; i++) + free(udev_device->envp[i]); + } else + udev_device->envp = malloc(sizeof(char *) * ENVP_SIZE); + i = 0; udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) { asprintf(&udev_device->envp[i++], "%s=%s", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry)); - if (i+1 >= ARRAY_SIZE(udev_device->envp)) + if (i+1 >= ENVP_SIZE) break; } udev_device->envp[i] = NULL;