X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibudev%2Flibudev-device.c;h=9863901a33ac4f73f3584f0837c55425b1009c07;hb=ce06fdfb3de7a6591041828361f8d10c04a4677e;hp=d61a2ad8f46bbbf100be39f41bcd9d90f338c786;hpb=8e3ba3772cadf6a8292b0da533062dd4d377af67;p=elogind.git diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index d61a2ad8f..9863901a3 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -139,7 +139,7 @@ static int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex) char num[32]; udev_device->ifindex = ifindex; - snprintf(num, sizeof(num), "%u", ifindex); + snprintf(num, sizeof(num), "%d", ifindex); udev_device_add_property(udev_device, "IFINDEX", num); return 0; } @@ -258,7 +258,7 @@ static int udev_device_set_devtype(struct udev_device *udev_device, const char * return 0; } -int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem) +static int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem) { free(udev_device->subsystem); udev_device->subsystem = strdup(subsystem); @@ -392,6 +392,44 @@ static struct udev_list_entry *udev_device_add_property_from_string(struct udev_ return udev_device_add_property(udev_device, name, val); } +static int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath) +{ + 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("/sys"); + 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; + + /* 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]; + + /* sysname is completely numeric */ + if (len == 0) + udev_device->sysnum = NULL; + + return 0; +} + /* * parse property string, and if needed, update internal values accordingly * @@ -534,10 +572,8 @@ int udev_device_read_db(struct udev_device *udev_device, const char *dbfile) } f = fopen(dbfile, "re"); - if (f == NULL) { - udev_dbg(udev_device->udev, "no db file to read %s: %m\n", dbfile); - return -errno; - } + if (f == NULL) + return log_debug_errno(errno, "no db file to read %s: %m", dbfile); /* devices with a database entry are initialized */ udev_device->is_initialized = true; @@ -577,7 +613,7 @@ int udev_device_read_db(struct udev_device *udev_device, const char *dbfile) } fclose(f); - udev_dbg(udev_device->udev, "device %p filled with db file data\n", udev_device); + log_debug("device %p filled with db file data", udev_device); return 0; } @@ -639,10 +675,9 @@ void udev_device_set_info_loaded(struct udev_device *device) device->info_loaded = true; } -struct udev_device *udev_device_new(struct udev *udev) +static struct udev_device *udev_device_new(struct udev *udev) { struct udev_device *udev_device; - struct udev_list_entry *list_entry; if (udev == NULL) { errno = EINVAL; @@ -662,11 +697,7 @@ struct udev_device *udev_device_new(struct udev *udev) 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)); + return udev_device; } @@ -704,7 +735,7 @@ _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, con /* path starts in sys */ if (!startswith(syspath, "/sys")) { - udev_dbg(udev, "not in sys :%s\n", syspath); + log_debug("not in sys :%s", syspath); errno = EINVAL; return NULL; } @@ -730,8 +761,13 @@ _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, con return NULL; } else { /* everything else just needs to be a directory */ - if (stat(path, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) + if (stat(path, &statbuf) != 0) return NULL; + + if (!S_ISDIR(statbuf.st_mode)) { + errno = EISDIR; + return NULL; + } } udev_device = udev_device_new(udev); @@ -739,7 +775,7 @@ _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, con return NULL; udev_device_set_syspath(udev_device, path); - udev_dbg(udev, "device %p has devpath '%s'\n", udev_device, udev_device_get_devpath(udev_device)); + log_debug("device %p has devpath '%s'", udev_device, udev_device_get_devpath(udev_device)); return udev_device; } @@ -971,7 +1007,7 @@ _public_ struct udev_device *udev_device_new_from_environment(struct udev *udev) udev_device_add_property_from_string_parse(udev_device, environ[i]); if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) { - udev_dbg(udev, "missing values, invalid device\n"); + log_debug("missing values, invalid device"); udev_device_unref(udev_device); udev_device = NULL; } @@ -1609,44 +1645,6 @@ _public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_ 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; - - free(udev_device->syspath); - udev_device->syspath = strdup(syspath); - if (udev_device->syspath == NULL) - return -ENOMEM; - udev_device->devpath = udev_device->syspath + strlen("/sys"); - 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; - - /* 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]; - - /* sysname is completely numeric */ - if (len == 0) - udev_device->sysnum = NULL; - - return 0; -} - static int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode) { free(udev_device->devnode); @@ -1688,7 +1686,7 @@ const char *udev_device_get_id_filename(struct udev_device *udev_device) 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) + if (asprintf(&udev_device->id_filename, "n%i", udev_device_get_ifindex(udev_device)) < 0) udev_device->id_filename = NULL; } else { /* @@ -1924,3 +1922,91 @@ void udev_device_set_db_persist(struct udev_device *udev_device) { udev_device->db_persist = true; } + +int udev_device_rename(struct udev_device *udev_device, const char *name) +{ + _cleanup_free_ char *dirname = NULL; + char *new_syspath; + int r; + + if (udev_device == NULL || name == NULL) + return -EINVAL; + + dirname = dirname_malloc(udev_device->syspath); + if (!dirname) + return -ENOMEM; + + new_syspath = strjoina(dirname, "/", name); + + r = udev_device_set_syspath(udev_device, new_syspath); + if (r < 0) + return r; + + return 0; +} + +struct udev_device *udev_device_shallow_clone(struct udev_device *old_device) +{ + struct udev_device *device; + + if (old_device == NULL) + return NULL; + + device = udev_device_new(old_device->udev); + if (!device) { + errno = ENOMEM; + + return NULL; + } + + udev_device_set_syspath(device, udev_device_get_syspath(old_device)); + udev_device_set_subsystem(device, udev_device_get_subsystem(old_device)); + udev_device_set_devnum(device, udev_device_get_devnum(old_device)); + + return device; +} + +struct udev_device *udev_device_new_from_nulstr(struct udev *udev, char *nulstr, ssize_t buflen) { + struct udev_device *device; + ssize_t bufpos = 0; + + if (nulstr == NULL || buflen <= 0) { + errno = EINVAL; + + return NULL; + } + + device = udev_device_new(udev); + if (!device) { + errno = ENOMEM; + + return NULL; + } + + udev_device_set_info_loaded(device); + + while (bufpos < buflen) { + char *key; + size_t keylen; + + key = nulstr + bufpos; + keylen = strlen(key); + if (keylen == 0) + break; + + bufpos += keylen + 1; + udev_device_add_property_from_string_parse(device, key); + } + + if (udev_device_add_property_from_string_parse_finish(device) < 0) { + log_debug("missing values, invalid device"); + + udev_device_unref(device); + + errno = EINVAL; + + return NULL; + } + + return device; +}