diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2009-05-20 17:57:52 +0200 |
---|---|---|
committer | Kay Sievers <kay.sievers@vrfy.org> | 2009-05-20 17:57:52 +0200 |
commit | 065db052211d3bf08d9b0f698a79a8798faf11d2 (patch) | |
tree | 970ac911636e2711c99ab050a7fd341e95ea08a9 /udev/lib | |
parent | f58a9099bb2b18f3f683615324a4382b95446305 (diff) |
use more efficient string copying
Diffstat (limited to 'udev/lib')
-rw-r--r-- | udev/lib/libudev-ctrl.c | 2 | ||||
-rw-r--r-- | udev/lib/libudev-device-db-write.c | 41 | ||||
-rw-r--r-- | udev/lib/libudev-device.c | 148 | ||||
-rw-r--r-- | udev/lib/libudev-enumerate.c | 40 | ||||
-rw-r--r-- | udev/lib/libudev-monitor.c | 25 | ||||
-rw-r--r-- | udev/lib/libudev-private.h | 10 | ||||
-rw-r--r-- | udev/lib/libudev-queue.c | 57 | ||||
-rw-r--r-- | udev/lib/libudev-util.c | 142 |
8 files changed, 212 insertions, 253 deletions
diff --git a/udev/lib/libudev-ctrl.c b/udev/lib/libudev-ctrl.c index 80ab0370e2..e47b2b66dc 100644 --- a/udev/lib/libudev-ctrl.c +++ b/udev/lib/libudev-ctrl.c @@ -148,7 +148,7 @@ static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int ctrl_msg_wire.type = type; if (buf != NULL) - util_strlcpy(ctrl_msg_wire.buf, buf, sizeof(ctrl_msg_wire.buf)); + util_strscpy(ctrl_msg_wire.buf, sizeof(ctrl_msg_wire.buf), buf); else ctrl_msg_wire.intval = intval; diff --git a/udev/lib/libudev-device-db-write.c b/udev/lib/libudev-device-db-write.c index fa9f520f17..d9d97d45a0 100644 --- a/udev/lib/libudev-device-db-write.c +++ b/udev/lib/libudev-device-db-write.c @@ -22,13 +22,12 @@ static size_t devpath_to_db_path(struct udev *udev, const char *devpath, char *filename, size_t len) { - size_t start; + char *s; + size_t l; - /* translate to location of db file */ - util_strlcpy(filename, udev_get_dev_path(udev), len); - start = util_strlcat(filename, "/.udev/db/", len); - util_strlcat(filename, devpath, len); - return util_path_encode(&filename[start], len - start); + s = filename; + l = util_strpcpyl(&s, len, udev_get_dev_path(udev), "/.udev/db/", NULL); + return util_path_encode(devpath, filename, l); } int udev_device_update_db(struct udev_device *udev_device) @@ -38,12 +37,12 @@ int udev_device_update_db(struct udev_device *udev_device) FILE *f; char target[232]; /* on 64bit, tmpfs inlines up to 239 bytes */ size_t devlen = strlen(udev_get_dev_path(udev))+1; + char *s; + size_t l; struct udev_list_entry *list_entry; int ret; - devpath_to_db_path(udev, - udev_device_get_devpath(udev_device), - filename, sizeof(filename)); + devpath_to_db_path(udev, udev_device_get_devpath(udev_device), filename, sizeof(filename)); util_create_path(udev, filename); unlink(filename); @@ -67,13 +66,11 @@ int udev_device_update_db(struct udev_device *udev_device) * if we have only the node and symlinks to store, try not to waste * tmpfs memory -- store values, if they fit, in a symlink target */ - util_strlcpy(target, &udev_device_get_devnode(udev_device)[devlen], sizeof(target)); + s = target; + l = util_strpcpy(&s, sizeof(target), &udev_device_get_devnode(udev_device)[devlen]); udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(udev_device)) { - size_t len; - - util_strlcat(target, " ", sizeof(target)); - len = util_strlcat(target, &udev_list_entry_get_name(list_entry)[devlen], sizeof(target)); - if (len >= sizeof(target)) { + l = util_strpcpyl(&s, l, " ", &udev_list_entry_get_name(list_entry)[devlen], NULL); + if (l == 0) { info(udev, "size of links too large, create file\n"); goto file; } @@ -121,25 +118,21 @@ out: int udev_device_delete_db(struct udev_device *udev_device) { + struct udev *udev = udev_device_get_udev(udev_device); char filename[UTIL_PATH_SIZE]; - devpath_to_db_path(udev_device_get_udev(udev_device), - udev_device_get_devpath(udev_device), - filename, sizeof(filename)); + devpath_to_db_path(udev, udev_device_get_devpath(udev_device), filename, sizeof(filename)); unlink(filename); return 0; } int udev_device_rename_db(struct udev_device *udev_device, const char *devpath_old) { + struct udev *udev = udev_device_get_udev(udev_device); char filename_old[UTIL_PATH_SIZE]; char filename[UTIL_PATH_SIZE]; - devpath_to_db_path(udev_device_get_udev(udev_device), - devpath_old, - filename_old, sizeof(filename_old)); - devpath_to_db_path(udev_device_get_udev(udev_device), - udev_device_get_devpath(udev_device), - filename, sizeof(filename)); + devpath_to_db_path(udev, devpath_old, filename_old, sizeof(filename_old)); + devpath_to_db_path(udev, udev_device_get_devpath(udev_device), filename, sizeof(filename)); return rename(filename_old, filename); } diff --git a/udev/lib/libudev-device.c b/udev/lib/libudev-device.c index ddc4b34115..37b3a3b7a2 100644 --- a/udev/lib/libudev-device.c +++ b/udev/lib/libudev-device.c @@ -1,7 +1,7 @@ /* * libudev - interface to udev device information * - * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org> + * Copyright (C) 2008-2009 Kay Sievers <kay.sievers@vrfy.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -63,13 +63,12 @@ struct udev_device { static size_t devpath_to_db_path(struct udev *udev, const char *devpath, char *filename, size_t len) { - size_t start; + char *s; + size_t l; - /* translate to location of db file */ - util_strlcpy(filename, udev_get_dev_path(udev), len); - start = util_strlcat(filename, "/.udev/db/", len); - util_strlcat(filename, devpath, len); - return util_path_encode(&filename[start], len - start); + s = filename; + l = util_strpcpyl(&s, len, udev_get_dev_path(udev), "/.udev/db/", NULL); + return util_path_encode(devpath, filename, l); } int udev_device_read_db(struct udev_device *udev_device) @@ -104,9 +103,7 @@ int udev_device_read_db(struct udev_device *udev_device) next[0] = '\0'; next = &next[1]; } - util_strlcpy(devnode, udev_get_dev_path(udev_device->udev), sizeof(devnode)); - util_strlcat(devnode, "/", sizeof(devnode)); - util_strlcat(devnode, target, sizeof(devnode)); + util_strscpyl(devnode, sizeof(devnode), udev_get_dev_path(udev_device->udev), "/", target, NULL); udev_device_set_devnode(udev_device, devnode); while (next != NULL) { char devlink[UTIL_PATH_SIZE]; @@ -118,9 +115,7 @@ int udev_device_read_db(struct udev_device *udev_device) next[0] = '\0'; next = &next[1]; } - util_strlcpy(devlink, udev_get_dev_path(udev_device->udev), sizeof(devlink)); - util_strlcat(devlink, "/", sizeof(devlink)); - util_strlcat(devlink, lnk, sizeof(devlink)); + util_strscpyl(devlink, sizeof(devlink), udev_get_dev_path(udev_device->udev), "/", lnk, NULL); udev_device_add_devlink(udev_device, devlink); } info(udev_device->udev, "device %p filled with db symlink data '%s'\n", udev_device, udev_device->devnode); @@ -143,15 +138,11 @@ int udev_device_read_db(struct udev_device *udev_device) val = &line[2]; switch(line[0]) { case 'N': - util_strlcpy(filename, udev_get_dev_path(udev_device->udev), sizeof(filename)); - util_strlcat(filename, "/", sizeof(filename)); - util_strlcat(filename, val, sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/", val, NULL); udev_device_set_devnode(udev_device, filename); break; case 'S': - util_strlcpy(filename, udev_get_dev_path(udev_device->udev), sizeof(filename)); - util_strlcat(filename, "/", sizeof(filename)); - util_strlcat(filename, val, sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/", val, NULL); udev_device_add_devlink(udev_device, filename); break; case 'L': @@ -188,8 +179,7 @@ int udev_device_read_uevent_file(struct udev_device *udev_device) int maj = 0; int min = 0; - util_strlcpy(filename, udev_device->syspath, sizeof(filename)); - util_strlcat(filename, "/uevent", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL); f = fopen(filename, "r"); if (f == NULL) return -1; @@ -303,7 +293,7 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char * } /* resolve possible symlink to real path */ - util_strlcpy(path, syspath, sizeof(path)); + util_strscpy(path, sizeof(path), syspath); util_resolve_sys_link(udev, path, sizeof(path)); /* try to resolve the silly block layout if needed */ @@ -311,16 +301,14 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char * char block[UTIL_PATH_SIZE]; char part[UTIL_PATH_SIZE]; - util_strlcpy(block, path, sizeof(block)); + util_strscpy(block, sizeof(block), path); pos = strrchr(block, '/'); if (pos == NULL) return NULL; - util_strlcpy(part, pos, sizeof(part)); + util_strscpy(part, sizeof(part), pos); pos[0] = '\0'; - if (util_resolve_sys_link(udev, block, sizeof(block)) == 0) { - util_strlcpy(path, block, sizeof(path)); - util_strlcat(path, part, sizeof(path)); - } + if (util_resolve_sys_link(udev, block, sizeof(block)) == 0) + util_strscpyl(path, sizeof(path), block, part, NULL); } /* path exists in sys */ @@ -330,8 +318,7 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char * char file[UTIL_PATH_SIZE]; /* all "devices" require a "uevent" file */ - util_strlcpy(file, path, sizeof(file)); - util_strlcat(file, "/uevent", sizeof(file)); + util_strscpyl(file, sizeof(file), path, "/uevent", NULL); if (stat(file, &statbuf) != 0) { dbg(udev, "not a device: %s\n", syspath); return NULL; @@ -407,35 +394,31 @@ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, de struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) { - size_t sys_path_len; char path_full[UTIL_PATH_SIZE]; char *path; + size_t l; struct stat statbuf; - sys_path_len = util_strlcpy(path_full, udev_get_sys_path(udev), sizeof(path_full)); - path = &path_full[sys_path_len]; + path = path_full; + l = util_strpcpyl(&path, sizeof(path_full), udev_get_sys_path(udev), NULL); if (strcmp(subsystem, "subsystem") == 0) { - util_strlcpy(path, "/subsystem/", sizeof(path_full) - sys_path_len); - util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + util_strscpyl(path, l, "/subsystem/", sysname, NULL); if (stat(path_full, &statbuf) == 0) goto found; - util_strlcpy(path, "/bus/", sizeof(path_full) - sys_path_len); - util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + util_strscpyl(path, l, "/bus/", sysname, NULL); if (stat(path_full, &statbuf) == 0) goto found; - util_strlcpy(path, "/class/", sizeof(path_full) - sys_path_len); - util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + util_strscpyl(path, l, "/class/", sysname, NULL); if (stat(path_full, &statbuf) == 0) goto found; goto out; } if (strcmp(subsystem, "module") == 0) { - util_strlcpy(path, "/module/", sizeof(path_full) - sys_path_len); - util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + util_strscpyl(path, l, "/module/", sysname, NULL); if (stat(path_full, &statbuf) == 0) goto found; goto out; @@ -445,46 +428,32 @@ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, co char subsys[UTIL_NAME_SIZE]; char *driver; - util_strlcpy(subsys, sysname, sizeof(subsys)); + util_strscpy(subsys, sizeof(subsys), sysname); driver = strchr(subsys, ':'); if (driver != NULL) { driver[0] = '\0'; driver = &driver[1]; - util_strlcpy(path, "/subsystem/", sizeof(path_full) - sys_path_len); - util_strlcat(path, subsys, sizeof(path_full) - sys_path_len); - util_strlcat(path, "/drivers/", sizeof(path_full) - sys_path_len); - util_strlcat(path, driver, sizeof(path_full) - sys_path_len); + + util_strscpyl(path, l, "/subsystem/", subsys, "/drivers/", driver, NULL); if (stat(path_full, &statbuf) == 0) goto found; - util_strlcpy(path, "/bus/", sizeof(path_full) - sys_path_len); - util_strlcat(path, subsys, sizeof(path_full) - sys_path_len); - util_strlcat(path, "/drivers/", sizeof(path_full) - sys_path_len); - util_strlcat(path, driver, sizeof(path_full) - sys_path_len); + util_strscpyl(path, l, "/bus/", subsys, "/drivers/", driver, NULL); if (stat(path_full, &statbuf) == 0) goto found; } goto out; } - util_strlcpy(path, "/subsystem/", sizeof(path_full) - sys_path_len); - util_strlcat(path, subsystem, sizeof(path_full) - sys_path_len); - util_strlcat(path, "/devices/", sizeof(path_full) - sys_path_len); - util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + util_strscpyl(path, l, "/subsystem/", subsystem, "/devices/", sysname, NULL); if (stat(path_full, &statbuf) == 0) goto found; - util_strlcpy(path, "/bus/", sizeof(path_full) - sys_path_len); - util_strlcat(path, subsystem, sizeof(path_full) - sys_path_len); - util_strlcat(path, "/devices/", sizeof(path_full) - sys_path_len); - util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + util_strscpyl(path, l, "/bus/", subsystem, "/devices/", sysname, NULL); if (stat(path_full, &statbuf) == 0) goto found; - util_strlcpy(path, "/class/", sizeof(path_full) - sys_path_len); - util_strlcat(path, subsystem, sizeof(path_full) - sys_path_len); - util_strlcat(path, "/", sizeof(path_full) - sys_path_len); - util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + util_strscpyl(path, l, "/class/", subsystem, "/", sysname, NULL); if (stat(path_full, &statbuf) == 0) goto found; out: @@ -502,8 +471,7 @@ static struct udev_device *device_new_from_parent(struct udev_device *udev_devic /* follow "device" link in deprecated sys layout */ if (strncmp(udev_device->devpath, "/class/", 7) == 0 || strncmp(udev_device->devpath, "/block/", 7) == 0) { - util_strlcpy(path, udev_device->syspath, sizeof(path)); - util_strlcat(path, "/device", sizeof(path)); + util_strscpyl(path, sizeof(path), udev_device->syspath, "/device", NULL); if (util_resolve_sys_link(udev_device->udev, path, sizeof(path)) == 0) { udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path); if (udev_device_parent != NULL) @@ -511,7 +479,7 @@ static struct udev_device *device_new_from_parent(struct udev_device *udev_devic } } - util_strlcpy(path, udev_device->syspath, sizeof(path)); + util_strscpy(path, sizeof(path), udev_device->syspath); subdir = &path[strlen(udev_get_sys_path(udev_device->udev))+1]; while (1) { char *pos; @@ -809,11 +777,13 @@ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device udev_device->devlinks_uptodate = 1; list_entry = udev_device_get_devlinks_list_entry(udev_device); if (list_entry != NULL) { - util_strlcpy(symlinks, udev_list_entry_get_name(list_entry), sizeof(symlinks)); - udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry)) { - util_strlcat(symlinks, " ", sizeof(symlinks)); - util_strlcat(symlinks, udev_list_entry_get_name(list_entry), sizeof(symlinks)); - } + 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); } } @@ -881,10 +851,7 @@ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const } } - util_strlcpy(path, udev_device_get_syspath(udev_device), sizeof(path)); - util_strlcat(path, "/", sizeof(path)); - util_strlcat(path, sysattr, sizeof(path)); - + 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->udev, &udev_device->sysattr_list, sysattr, NULL, 0, 0); @@ -1047,7 +1014,7 @@ struct udev_list_entry *udev_device_add_property_from_string(struct udev_device char name[UTIL_PATH_SIZE]; char *val; - util_strlcpy(name, property, sizeof(name)); + util_strscpy(name, sizeof(name), property); val = strchr(name, '='); if (val == NULL) return NULL; @@ -1077,8 +1044,8 @@ const char *udev_device_get_property_value(struct udev_device *udev_device, cons static int update_envp_monitor_buf(struct udev_device *udev_device) { struct udev_list_entry *list_entry; - size_t bufpos; - size_t len; + char *s; + size_t l; unsigned int i; /* monitor buffer of property strings */ @@ -1095,33 +1062,26 @@ static int update_envp_monitor_buf(struct udev_device *udev_device) return -ENOMEM; i = 0; - bufpos = 0; + s = udev_device->monitor_buf; + l = MONITOR_BUF_SIZE; udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) { /* add string to envp array */ - udev_device->envp[i++] = &udev_device->monitor_buf[bufpos]; + udev_device->envp[i++] = s; if (i+1 >= ENVP_SIZE) return -EINVAL; /* add property string to monitor buffer */ - len = util_strlcpy(&udev_device->monitor_buf[bufpos], - udev_list_entry_get_name(list_entry), MONITOR_BUF_SIZE-bufpos); - if (len >= MONITOR_BUF_SIZE-bufpos) - return -EINVAL; - bufpos += len; - len = util_strlcpy(&udev_device->monitor_buf[bufpos], "=", MONITOR_BUF_SIZE-bufpos); - if (len >= MONITOR_BUF_SIZE-bufpos) - return -EINVAL; - bufpos += len; - len = util_strlcpy(&udev_device->monitor_buf[bufpos], udev_list_entry_get_value(list_entry), - MONITOR_BUF_SIZE-bufpos); - if (len+1 >= MONITOR_BUF_SIZE-bufpos) + l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), "=", + udev_list_entry_get_value(list_entry), NULL); + if (l == 0) return -EINVAL; - bufpos += len+1; + s++; } udev_device->envp[i] = NULL; - udev_device->monitor_buf_len = bufpos; + udev_device->monitor_buf_len = s - udev_device->monitor_buf; udev_device->envp_uptodate = 1; - dbg(udev_device->udev, "filled envp/monitor buffer, %u properties, %zu bytes\n", i, bufpos); + dbg(udev_device->udev, "filled envp/monitor buffer, %u properties, %zu bytes\n", + i, udev_device->monitor_buf_len); return 0; } diff --git a/udev/lib/libudev-enumerate.c b/udev/lib/libudev-enumerate.c index a92bf0b620..c236a1c1b6 100644 --- a/udev/lib/libudev-enumerate.c +++ b/udev/lib/libudev-enumerate.c @@ -261,20 +261,17 @@ static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate, { struct udev *udev = udev_enumerate_get_udev(udev_enumerate); char path[UTIL_PATH_SIZE]; + size_t l; + char *s; DIR *dir; struct dirent *dent; - util_strlcpy(path, udev_get_sys_path(udev), sizeof(path)); - util_strlcat(path, "/", sizeof(path)); - util_strlcat(path, basedir, sizeof(path)); - if (subdir1 != NULL) { - util_strlcat(path, "/", sizeof(path)); - util_strlcat(path, subdir1, sizeof(path)); - } - if (subdir2 != NULL) { - util_strlcat(path, "/", sizeof(path)); - util_strlcat(path, subdir2, sizeof(path)); - } + s = path; + l = util_strpcpyl(&s, sizeof(path), udev_get_sys_path(udev), "/", basedir, NULL); + if (subdir1 != NULL) + l = util_strpcpyl(&s, l, "/", subdir1, NULL); + if (subdir2 != NULL) + l = util_strpcpyl(&s, l, "/", subdir2, NULL); dir = opendir(path); if (dir == NULL) return -1; @@ -285,17 +282,15 @@ static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate, if (dent->d_name[0] == '.') continue; - util_strlcpy(syspath, path, sizeof(syspath)); - util_strlcat(syspath, "/", sizeof(syspath)); - util_strlcat(syspath, dent->d_name, sizeof(syspath)); + util_strscpyl(syspath, sizeof(syspath), path, "/", dent->d_name, NULL); if (lstat(syspath, &statbuf) != 0) continue; if (S_ISREG(statbuf.st_mode)) continue; if (S_ISLNK(statbuf.st_mode)) util_resolve_sys_link(udev, syspath, sizeof(syspath)); - util_strlcpy(filename, syspath, sizeof(filename)); - util_strlcat(filename, "/uevent", sizeof(filename)); + + util_strscpyl(filename, sizeof(filename), syspath, "/uevent", NULL); if (stat(filename, &statbuf) != 0) continue; if (!match_sysattr(udev_enumerate, syspath)) @@ -334,9 +329,7 @@ static int scan_dir(struct udev_enumerate *udev_enumerate, const char *basedir, DIR *dir; struct dirent *dent; - util_strlcpy(path, udev_get_sys_path(udev), sizeof(path)); - util_strlcat(path, "/", sizeof(path)); - util_strlcat(path, basedir, sizeof(path)); + util_strscpyl(path, sizeof(path), udev_get_sys_path(udev), "/", basedir, NULL); dir = opendir(path); if (dir == NULL) return -1; @@ -428,8 +421,7 @@ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate) if (udev_enumerate == NULL) return -EINVAL; - util_strlcpy(base, udev_get_sys_path(udev), sizeof(base)); - util_strlcat(base, "/subsystem", sizeof(base)); + util_strscpyl(base, sizeof(base), udev_get_sys_path(udev), "/subsystem", NULL); if (stat(base, &statbuf) == 0) { /* we have /subsystem/, forget all the old stuff */ dbg(udev, "searching '/subsystem/*/devices/*' dir\n"); @@ -440,8 +432,7 @@ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate) dbg(udev, "searching '/class/*' dir\n"); scan_dir(udev_enumerate, "class", NULL, NULL); /* if block isn't a class, scan /block/ */ - util_strlcpy(base, udev_get_sys_path(udev), sizeof(base)); - util_strlcat(base, "/class/block", sizeof(base)); + util_strscpyl(base, sizeof(base), udev_get_sys_path(udev), "/class/block", NULL); if (stat(base, &statbuf) != 0) { if (match_subsystem(udev_enumerate, "block")) { dbg(udev, "searching '/block/*' dir\n"); @@ -471,8 +462,7 @@ int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate) if (udev_enumerate == NULL) return -EINVAL; - util_strlcpy(base, udev_get_sys_path(udev), sizeof(base)); - util_strlcat(base, "/subsystem", sizeof(base)); + util_strscpyl(base, sizeof(base), udev_get_sys_path(udev), "/subsystem", NULL); if (stat(base, &statbuf) == 0) subsysdir = "subsystem"; else diff --git a/udev/lib/libudev-monitor.c b/udev/lib/libudev-monitor.c index 2540e85c34..395a4d27e1 100644 --- a/udev/lib/libudev-monitor.c +++ b/udev/lib/libudev-monitor.c @@ -1,7 +1,7 @@ /* * libudev - interface to udev device information * - * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org> + * Copyright (C) 2008-2009 Kay Sievers <kay.sievers@vrfy.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -113,16 +113,16 @@ struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char udev_monitor->sun.sun_family = AF_LOCAL; if (socket_path[0] == '@') { /* translate leading '@' to abstract namespace */ - util_strlcpy(udev_monitor->sun.sun_path, socket_path, sizeof(udev_monitor->sun.sun_path)); + util_strscpy(udev_monitor->sun.sun_path, sizeof(udev_monitor->sun.sun_path), socket_path); udev_monitor->sun.sun_path[0] = '\0'; udev_monitor->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path); } else if (stat(socket_path, &statbuf) == 0 && S_ISSOCK(statbuf.st_mode)) { /* existing socket file */ - util_strlcpy(udev_monitor->sun.sun_path, socket_path, sizeof(udev_monitor->sun.sun_path)); + util_strscpy(udev_monitor->sun.sun_path, sizeof(udev_monitor->sun.sun_path), socket_path); udev_monitor->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path); } else { /* no socket file, assume abstract namespace socket */ - util_strlcpy(&udev_monitor->sun.sun_path[1], socket_path, sizeof(udev_monitor->sun.sun_path)-1); + util_strscpy(&udev_monitor->sun.sun_path[1], sizeof(udev_monitor->sun.sun_path)-1, socket_path); udev_monitor->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path)+1; } udev_monitor->sock = socket(AF_LOCAL, SOCK_DGRAM, 0); @@ -545,8 +545,7 @@ retry: if (strncmp(key, "DEVPATH=", 8) == 0) { char path[UTIL_PATH_SIZE]; - util_strlcpy(path, udev_get_sys_path(udev_monitor->udev), sizeof(path)); - util_strlcat(path, &key[8], sizeof(path)); + util_strscpyl(path, sizeof(path), udev_get_sys_path(udev_monitor->udev), &key[8], NULL); udev_device_set_syspath(udev_device, path); devpath_set = 1; } else if (strncmp(key, "SUBSYSTEM=", 10) == 0) { @@ -564,7 +563,7 @@ retry: char *slink; char *next; - util_strlcpy(devlinks, &key[9], sizeof(devlinks)); + util_strscpy(devlinks, sizeof(devlinks), &key[9]); slink = devlinks; next = strchr(slink, ' '); while (next != NULL) { @@ -637,19 +636,17 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor, struct udev_devi if (udev_monitor->sun.sun_family != 0) { const char *action; char header[2048]; - size_t hlen; + char *s; /* header <action>@<devpath> */ action = udev_device_get_action(udev_device); if (action == NULL) return -EINVAL; - util_strlcpy(header, action, sizeof(header)); - util_strlcat(header, "@", sizeof(header)); - hlen = util_strlcat(header, udev_device_get_devpath(udev_device), sizeof(header))+1; - if (hlen >= sizeof(header)) + s = header; + if (util_strpcpyl(&s, sizeof(header), action, "@", udev_device_get_devpath(udev_device), NULL) == 0) return -EINVAL; iov[0].iov_base = header; - iov[0].iov_len = hlen; + iov[0].iov_len = (s - header)+1; /* add properties list */ iov[1].iov_base = (char *)buf; @@ -667,7 +664,7 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor, struct udev_devi /* add versioned header */ memset(&nlh, 0x00, sizeof(struct udev_monitor_netlink_header)); - util_strlcpy(nlh.version, "udev-" VERSION, sizeof(nlh.version)); + util_strscpy(nlh.version, sizeof(nlh.version), "udev-" VERSION); nlh.magic = htonl(UDEV_MONITOR_MAGIC); val = udev_device_get_subsystem(udev_device); nlh.filter_subsystem = htonl(util_string_hash32(val)); diff --git a/udev/lib/libudev-private.h b/udev/lib/libudev-private.h index 7dd8e7dfe0..9ec5e1aae2 100644 --- a/udev/lib/libudev-private.h +++ b/udev/lib/libudev-private.h @@ -1,7 +1,7 @@ /* * libudev - interface to udev device information * - * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org> + * Copyright (C) 2008-2009 Kay Sievers <kay.sievers@vrfy.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -164,11 +164,13 @@ ssize_t util_get_sys_subsystem(struct udev *udev, const char *syspath, char *sub ssize_t util_get_sys_driver(struct udev *udev, const char *syspath, char *driver, size_t size); int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size); int util_log_priority(const char *priority); -size_t util_path_encode(char *s, size_t len); +size_t util_path_encode(const char *src, char *dest, size_t size); size_t util_path_decode(char *s); void util_remove_trailing_chars(char *path, char c); -size_t util_strlcpy(char *dst, const char *src, size_t size); -size_t util_strlcat(char *dst, const char *src, size_t size); +size_t util_strpcpy(char **dest, size_t size, const char *src); +size_t util_strpcpyl(char **dest, size_t size, const char *src, ...); +size_t util_strscpy(char *dest, size_t size, const char *src); +size_t util_strscpyl(char *dest, size_t size, const char *src, ...); int udev_util_replace_whitespace(const char *str, char *to, size_t len); int udev_util_replace_chars(char *str, const char *white); int udev_util_encode_string(const char *str, char *str_enc, size_t len); diff --git a/udev/lib/libudev-queue.c b/udev/lib/libudev-queue.c index 63229fd8fe..a2860ec8c2 100644 --- a/udev/lib/libudev-queue.c +++ b/udev/lib/libudev-queue.c @@ -84,8 +84,7 @@ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queu if (udev_queue == NULL) return -EINVAL; - util_strlcpy(filename, udev_get_sys_path(udev_queue->udev), sizeof(filename)); - util_strlcat(filename, "/kernel/uevent_seqnum", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_sys_path(udev_queue->udev), "/kernel/uevent_seqnum", NULL); fd = open(filename, O_RDONLY); if (fd < 0) return 0; @@ -109,8 +108,7 @@ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) if (udev_queue == NULL) return -EINVAL; - util_strlcpy(filename, udev_get_dev_path(udev_queue->udev), sizeof(filename)); - util_strlcat(filename, "/.udev/uevent_seqnum", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue->udev), "/.udev/uevent_seqnum", NULL); fd = open(filename, O_RDONLY); if (fd < 0) return 0; @@ -132,8 +130,7 @@ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) if (udev_queue == NULL) return 0; - util_strlcpy(filename, udev_get_dev_path(udev_queue->udev), sizeof(filename)); - util_strlcat(filename, "/.udev/uevent_seqnum", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue->udev), "/.udev/uevent_seqnum", NULL); if (stat(filename, &statbuf) == 0) return 1; return 0; @@ -147,8 +144,7 @@ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) if (udev_queue == NULL) return -EINVAL; - util_strlcpy(queuename, udev_get_dev_path(udev_queue->udev), sizeof(queuename)); - util_strlcat(queuename, "/.udev/queue", sizeof(queuename)); + util_strscpyl(queuename, sizeof(queuename), udev_get_dev_path(udev_queue->udev), "/.udev/queue", NULL); if (stat(queuename, &statbuf) == 0) { dbg(udev_queue->udev, "queue is not empty\n"); return 0; @@ -200,28 +196,26 @@ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev if (udev_queue == NULL) return NULL; udev_list_cleanup_entries(udev_queue->udev, &udev_queue->queue_list); - util_strlcpy(path, udev_get_dev_path(udev_queue->udev), sizeof(path)); - util_strlcat(path, "/.udev/queue", sizeof(path)); + util_strscpyl(path, sizeof(path), udev_get_dev_path(udev_queue->udev), "/.udev/queue", NULL); dir = opendir(path); if (dir == NULL) return NULL; for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { char filename[UTIL_PATH_SIZE]; char syspath[UTIL_PATH_SIZE]; - size_t syslen; + char *s; + size_t l; ssize_t len; if (dent->d_name[0] == '.') continue; - util_strlcpy(filename, path, sizeof(filename)); - util_strlcat(filename, "/", sizeof(filename)); - util_strlcat(filename, dent->d_name, sizeof(filename)); - - syslen = util_strlcpy(syspath, udev_get_sys_path(udev_queue->udev), sizeof(syspath)); - len = readlink(filename, &syspath[syslen], sizeof(syspath)-syslen); - if (len < 0 || len >= (ssize_t)(sizeof(syspath)-syslen)) + util_strscpyl(filename, sizeof(filename), path, "/", dent->d_name, NULL); + s = syspath; + l = util_strpcpyl(&s, sizeof(syspath), udev_get_sys_path(udev_queue->udev), NULL); + len = readlink(filename, s, l); + if (len < 0 || (size_t)len >= l) continue; - syspath[syslen + len] = '\0'; + s[len] = '\0'; dbg(udev_queue->udev, "found '%s' [%s]\n", syspath, dent->d_name); udev_list_entry_add(udev_queue->udev, &udev_queue->queue_list, syspath, dent->d_name, 0, 0); } @@ -238,32 +232,29 @@ struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev if (udev_queue == NULL) return NULL; udev_list_cleanup_entries(udev_queue->udev, &udev_queue->failed_list); - util_strlcpy(path, udev_get_dev_path(udev_queue->udev), sizeof(path)); - util_strlcat(path, "/.udev/failed", sizeof(path)); + util_strscpyl(path, sizeof(path), udev_get_dev_path(udev_queue->udev), "/.udev/failed", NULL); dir = opendir(path); if (dir == NULL) return NULL; for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { char filename[UTIL_PATH_SIZE]; char syspath[UTIL_PATH_SIZE]; - struct stat statbuf; - size_t syslen; + char *s; + size_t l; ssize_t len; + struct stat statbuf; if (dent->d_name[0] == '.') continue; - util_strlcpy(filename, path, sizeof(filename)); - util_strlcat(filename, "/", sizeof(filename)); - util_strlcat(filename, dent->d_name, sizeof(filename)); - - syslen = util_strlcpy(syspath, udev_get_sys_path(udev_queue->udev), sizeof(syspath)); - len = readlink(filename, &syspath[syslen], sizeof(syspath)-syslen); - if (len < 0 || len >= (ssize_t)(sizeof(syspath)-syslen)) + util_strscpyl(filename, sizeof(filename), path, "/", dent->d_name, NULL); + s = syspath; + l = util_strpcpyl(&s, sizeof(syspath), udev_get_sys_path(udev_queue->udev), NULL); + len = readlink(filename, s, l); + if (len < 0 || (size_t)len >= l) continue; - syspath[syslen + len] = '\0'; + s[len] = '\0'; dbg(udev_queue->udev, "found '%s' [%s]\n", syspath, dent->d_name); - util_strlcpy(filename, syspath, sizeof(filename)); - util_strlcat(filename, "/uevent", sizeof(filename)); + util_strscpyl(filename, sizeof(filename), syspath, "/uevent", NULL); if (stat(filename, &statbuf) != 0) continue; udev_list_entry_add(udev_queue->udev, &udev_queue->failed_list, syspath, NULL, 0, 0); diff --git a/udev/lib/libudev-util.c b/udev/lib/libudev-util.c index 2b8cda59f6..24ea0daa51 100644 --- a/udev/lib/libudev-util.c +++ b/udev/lib/libudev-util.c @@ -1,7 +1,7 @@ /* * libudev - interface to udev device information * - * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org> + * Copyright (C) 2008-2009 Kay Sievers <kay.sievers@vrfy.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,9 +29,7 @@ static ssize_t get_sys_link(struct udev *udev, const char *slink, const char *sy ssize_t len; const char *pos; - util_strlcpy(path, syspath, sizeof(path)); - util_strlcat(path, "/", sizeof(path)); - util_strlcat(path, slink, sizeof(path)); + util_strscpyl(path, sizeof(path), syspath, "/", slink, NULL); len = readlink(path, path, sizeof(path)); if (len < 0 || len >= (ssize_t) sizeof(path)) return -1; @@ -41,7 +39,7 @@ static ssize_t get_sys_link(struct udev *udev, const char *slink, const char *sy return -1; pos = &pos[1]; dbg(udev, "resolved link to: '%s'\n", pos); - return util_strlcpy(value, pos, size); + return util_strscpy(value, size, pos); } ssize_t util_get_sys_subsystem(struct udev *udev, const char *syspath, char *subsystem, size_t size) @@ -61,6 +59,7 @@ int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size) int len; int i; int back; + char *base; len = readlink(syspath, link_target, sizeof(link_target)); if (len <= 0) @@ -72,15 +71,13 @@ int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size) ; dbg(udev, "base '%s', tail '%s', back %i\n", syspath, &link_target[back * 3], back); for (i = 0; i <= back; i++) { - char *pos = strrchr(syspath, '/'); - - if (pos == NULL) + base = strrchr(syspath, '/'); + if (base == NULL) return -1; - pos[0] = '\0'; + base[0] = '\0'; } dbg(udev, "after moving back '%s'\n", syspath); - util_strlcat(syspath, "/", size); - util_strlcat(syspath, &link_target[back * 3], size); + util_strscpyl(base, size - (base - syspath), "/", &link_target[back * 3], NULL); return 0; } @@ -101,29 +98,35 @@ int util_log_priority(const char *priority) return 0; } -size_t util_path_encode(char *s, size_t size) +size_t util_path_encode(const char *src, char *dest, size_t size) { - char t[(size * 4)+1]; size_t i, j; - for (i = 0, j = 0; s[i] != '\0' && i < size; i++) { - if (s[i] == '/') { - memcpy(&t[j], "\\x2f", 4); + for (i = 0, j = 0; src[i] != '\0'; i++) { + if (src[i] == '/') { + if (j+4 >= size) { + j = 0; + break; + } + memcpy(&dest[j], "\\x2f", 4); j += 4; - } else if (s[i] == '\\') { - memcpy(&t[j], "\\x5c", 4); + } else if (src[i] == '\\') { + if (j+4 >= size) { + j = 0; + break; + } + memcpy(&dest[j], "\\x5c", 4); j += 4; } else { - t[j] = s[i]; + if (j+1 >= size) { + j = 0; + break; + } + dest[j] = src[i]; j++; } } - if (i >= size) - return 0; - if (j >= size) - return 0; - memcpy(s, t, j); - s[j] = '\0'; + dest[j] = '\0'; return j; } @@ -158,47 +161,70 @@ void util_remove_trailing_chars(char *path, char c) path[--len] = '\0'; } -size_t util_strlcpy(char *dst, const char *src, size_t size) +/* + * Concatenates strings. In any case, terminates in _all_ cases with '\0' + * and moves the @dest pointer forward to the added '\0'. Returns the + * remaining size, and 0 if the string was truncated. + */ +size_t util_strpcpy(char **dest, size_t size, const char *src) { - size_t bytes = 0; - char *q = dst; - const char *p = src; - char ch; - - while ((ch = *p++)) { - if (bytes+1 < size) - *q++ = ch; - bytes++; + size_t len; + + len = strlen(src); + if (len >= size) { + if (size > 1) + *dest = mempcpy(*dest, src, size-1); + size = 0; + *dest[0] = '\0'; + } else { + if (len > 0) { + *dest = mempcpy(*dest, src, len); + size -= len; + } + *dest[0] = '\0'; } + return size; +} + +/* concatenates list of strings, moves dest forward */ +size_t util_strpcpyl(char **dest, size_t size, const char *src, ...) +{ + va_list va; + + va_start(va, src); + do { + size = util_strpcpy(dest, size, src); + src = va_arg(va, char *); + } while (src != NULL); + va_end(va); - /* If size == 0 there is no space for a final null... */ - if (size) - *q = '\0'; - return bytes; + return size; } -size_t util_strlcat(char *dst, const char *src, size_t size) +/* copies string */ +size_t util_strscpy(char *dest, size_t size, const char *src) { - size_t bytes = 0; - char *q = dst; - const char *p = src; - char ch; - - while (bytes < size && *q) { - q++; - bytes++; - } - if (bytes == size) - return (bytes + strlen(src)); + char *s; - while ((ch = *p++)) { - if (bytes+1 < size) - *q++ = ch; - bytes++; - } + s = dest; + return util_strpcpy(&s, size, src); +} - *q = '\0'; - return bytes; +/* concatenates list of strings */ +size_t util_strscpyl(char *dest, size_t size, const char *src, ...) +{ + va_list va; + char *s; + + va_start(va, src); + s = dest; + do { + size = util_strpcpy(&s, size, src); + src = va_arg(va, char *); + } while (src != NULL); + va_end(va); + + return size; } /* count of characters used to encode one unicode char */ |