diff --git a/meson.build b/meson.build index e0a3c53529..82c6de900c 100644 --- a/meson.build +++ b/meson.build @@ -1577,7 +1577,6 @@ includes = include_directories('src/basic', 'src/libsystemd/sd-netlink', 'src/libsystemd/sd-network', 'src/libsystemd/sd-resolve', - 'src/libudev', 'src/login', 'src/nspawn', 'src/resolve', @@ -3162,7 +3161,7 @@ if conf.get('ENABLE_HWDB') == 1 'src/hwdb/hwdb.c', 'src/libsystemd/sd-hwdb/hwdb-internal.h', include_directories : includes, - link_with : [libudev_static], + link_with : udev_link_with, install_rpath : udev_rpath, install : true, install_dir : rootbindir) @@ -3194,8 +3193,7 @@ public_programs += executable( udevadm_sources, c_args : '-DLOG_REALM=LOG_REALM_UDEV', include_directories : includes, - link_with : [libudev_core, - libudev_static], + link_with : [libudevd_core], dependencies : [versiondep, threads, libkmod, @@ -3274,7 +3272,6 @@ if conf.get('ENABLE_NETWORKD') == 1 include_directories : network_include_dir, link_with : [libnetworkd_core, libsystemd_network, - libudev_static, networkd_link_with], dependencies : [threads], install_rpath : rootlibexecdir, @@ -3412,7 +3409,7 @@ endif exe = executable( 'test-libudev-sym', test_libudev_sym_c, - include_directories : includes, + include_directories : libudev_includes, c_args : '-Wno-deprecated-declarations', link_with : [libudev], build_by_default : want_tests != 'false', @@ -3425,7 +3422,7 @@ endif exe = executable( 'test-libudev-static-sym', test_libudev_sym_c, - include_directories : includes, + include_directories : libudev_includes, c_args : '-Wno-deprecated-declarations', link_with : [install_libudev_static], build_by_default : want_tests != 'false' and static_libudev_pic, diff --git a/rules.d/99-systemd.rules.in b/rules.d/99-systemd.rules.in index 7c22eefdb7..cf2f9935d9 100644 --- a/rules.d/99-systemd.rules.in +++ b/rules.d/99-systemd.rules.in @@ -42,8 +42,6 @@ SUBSYSTEM=="block", KERNEL=="nbd*", ENV{DEVTYPE}=="disk", TEST!="pid", ENV{SYSTE # just an identification string for systemd, so whether the path actually is # accessible or not does not matter as long as it is unique and in the # filesystem namespace. -# -# http://cgit.freedesktop.org/systemd/systemd/tree/src/libudev/libudev-enumerate.c#n955 SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/net/devices/$name" SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k", \ diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build index f8f0c386b3..80fa0f6fcc 100644 --- a/src/fuzz/meson.build +++ b/src/fuzz/meson.build @@ -106,8 +106,7 @@ fuzzers += [ []], [['src/fuzz/fuzz-udev-rules.c'], - [libudev_core, - libudev_static, + [libudevd_core, libshared], [threads, libacl]], diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c index 01b237fde4..7ca17fa6c3 100644 --- a/src/libudev/libudev-queue.c +++ b/src/libudev/libudev-queue.c @@ -4,9 +4,6 @@ ***/ #include -#include -#include -#include #include #include "libudev.h" @@ -14,6 +11,7 @@ #include "alloc-util.h" #include "fd-util.h" #include "io-util.h" +#include "udev-util.h" /** * SECTION:libudev-queue @@ -144,7 +142,7 @@ _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) { * Returns: a flag indicating if udev is currently handling events. **/ _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) { - return access("/run/udev/queue", F_OK) < 0; + return udev_queue_is_empty() > 0; } /** @@ -153,14 +151,13 @@ _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) { * @start: first event sequence number * @end: last event sequence number * - * This function is deprecated, it just returns the result of - * udev_queue_get_queue_is_empty(). + * This function is deprecated, and equivalent to udev_queue_get_queue_is_empty(). * * Returns: a flag indicating if udev is currently handling events. **/ _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue, unsigned long long int start, unsigned long long int end) { - return udev_queue_get_queue_is_empty(udev_queue); + return udev_queue_is_empty() > 0; } /** @@ -168,13 +165,12 @@ _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_ * @udev_queue: udev queue context * @seqnum: sequence number * - * This function is deprecated, it just returns the result of - * udev_queue_get_queue_is_empty(). + * This function is deprecated, and equivalent to udev_queue_get_queue_is_empty(). * * Returns: a flag indicating if udev is currently handling events. **/ _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) { - return udev_queue_get_queue_is_empty(udev_queue); + return udev_queue_is_empty() > 0; } /** @@ -196,22 +192,18 @@ _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_qu * Returns: a file descriptor to watch for a queue to become empty. */ _public_ int udev_queue_get_fd(struct udev_queue *udev_queue) { - _cleanup_close_ int fd = -1; + int r; assert_return(udev_queue, -EINVAL); if (udev_queue->fd >= 0) return udev_queue->fd; - fd = inotify_init1(IN_CLOEXEC); - if (fd < 0) - return -errno; + r = udev_queue_init(); + if (r < 0) + return r; - if (inotify_add_watch(fd, "/run/udev" , IN_DELETE) < 0) - return -errno; - - udev_queue->fd = TAKE_FD(fd); - return udev_queue->fd; + return udev_queue->fd = r; } /** diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c index bbb2879764..8c51877662 100644 --- a/src/libudev/libudev-util.c +++ b/src/libudev/libudev-util.c @@ -1,15 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include -#include - -#include "sd-device.h" - #include "device-nodes.h" #include "libudev-util.h" -#include "string-util.h" -#include "strxcpyx.h" -#include "utf8.h" /** * SECTION:libudev-util @@ -18,185 +10,6 @@ * Utilities useful when dealing with devices and device node names. */ -/* handle "[/]" format */ -int util_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value) { - char temp[UTIL_PATH_SIZE], *subsys, *sysname, *attr; - _cleanup_(sd_device_unrefp) sd_device *dev = NULL; - const char *val; - int r; - - if (string[0] != '[') - return -EINVAL; - - strscpy(temp, sizeof(temp), string); - - subsys = &temp[1]; - - sysname = strchr(subsys, '/'); - if (!sysname) - return -EINVAL; - sysname[0] = '\0'; - sysname = &sysname[1]; - - attr = strchr(sysname, ']'); - if (!attr) - return -EINVAL; - attr[0] = '\0'; - attr = &attr[1]; - if (attr[0] == '/') - attr = &attr[1]; - if (attr[0] == '\0') - attr = NULL; - - if (read_value && !attr) - return -EINVAL; - - r = sd_device_new_from_subsystem_sysname(&dev, subsys, sysname); - if (r < 0) - return r; - - if (read_value) { - r = sd_device_get_sysattr_value(dev, attr, &val); - if (r < 0 && r != -ENOENT) - return r; - if (r == -ENOENT) - result[0] = '\0'; - else - strscpy(result, maxsize, val); - log_debug("value '[%s/%s]%s' is '%s'", subsys, sysname, attr, result); - } else { - r = sd_device_get_syspath(dev, &val); - if (r < 0) - return r; - - strscpyl(result, maxsize, val, attr ? "/" : NULL, attr ?: NULL, NULL); - log_debug("path '[%s/%s]%s' is '%s'", subsys, sysname, strempty(attr), result); - } - return 0; -} - -size_t util_path_encode(const char *src, char *dest, size_t size) { - size_t i, j; - - assert(src); - assert(dest); - - 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 (src[i] == '\\') { - if (j+4 >= size) { - j = 0; - break; - } - memcpy(&dest[j], "\\x5c", 4); - j += 4; - } else { - if (j+1 >= size) { - j = 0; - break; - } - dest[j] = src[i]; - j++; - } - } - dest[j] = '\0'; - return j; -} - -/* - * Copy from 'str' to 'to', while removing all leading and trailing whitespace, - * and replacing each run of consecutive whitespace with a single underscore. - * The chars from 'str' are copied up to the \0 at the end of the string, or - * at most 'len' chars. This appends \0 to 'to', at the end of the copied - * characters. - * - * If 'len' chars are copied into 'to', the final \0 is placed at len+1 - * (i.e. 'to[len] = \0'), so the 'to' buffer must have at least len+1 - * chars available. - * - * Note this may be called with 'str' == 'to', i.e. to replace whitespace - * in-place in a buffer. This function can handle that situation. - * - * Note that only 'len' characters are read from 'str'. - */ -size_t util_replace_whitespace(const char *str, char *to, size_t len) { - bool is_space = false; - size_t i, j; - - assert(str); - assert(to); - - i = strspn(str, WHITESPACE); - - for (j = 0; j < len && i < len && str[i] != '\0'; i++) { - if (isspace(str[i])) { - is_space = true; - continue; - } - - if (is_space) { - if (j + 1 >= len) - break; - - to[j++] = '_'; - is_space = false; - } - to[j++] = str[i]; - } - - to[j] = '\0'; - return j; -} - -/* allow chars in allow list, plain ascii, hex-escaping and valid utf8 */ -size_t util_replace_chars(char *str, const char *allow) { - size_t i = 0, replaced = 0; - - assert(str); - - while (str[i] != '\0') { - int len; - - if (allow_listed_char_for_devnode(str[i], allow)) { - i++; - continue; - } - - /* accept hex encoding */ - if (str[i] == '\\' && str[i+1] == 'x') { - i += 2; - continue; - } - - /* accept valid utf8 */ - len = utf8_encoded_valid_unichar(str + i, (size_t) -1); - if (len > 1) { - i += len; - continue; - } - - /* if space is allowed, replace whitespace with ordinary space */ - if (isspace(str[i]) && allow && strchr(allow, ' ')) { - str[i] = ' '; - i++; - replaced++; - continue; - } - - /* everything else is replaced with '_' */ - str[i] = '_'; - i++; - replaced++; - } - return replaced; -} - /** * udev_util_encode_string: * @str: input string to be encoded diff --git a/src/libudev/libudev-util.h b/src/libudev/libudev-util.h index 15e6214b0d..0dc18d44be 100644 --- a/src/libudev/libudev-util.h +++ b/src/libudev/libudev-util.h @@ -5,16 +5,6 @@ #include "macro.h" -/* libudev-util.c */ -#define UTIL_PATH_SIZE 1024 -#define UTIL_NAME_SIZE 512 -#define UTIL_LINE_SIZE 16384 -#define UDEV_ALLOWED_CHARS_INPUT "/ $%?," -size_t util_path_encode(const char *src, char *dest, size_t size); -size_t util_replace_whitespace(const char *str, char *to, size_t len); -size_t util_replace_chars(char *str, const char *white); -int util_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value); - /* Cleanup functions */ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev*, udev_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_device*, udev_device_unref); diff --git a/src/libudev/libudev.h b/src/libudev/libudev.h index 55036de867..aef4a55a8c 100644 --- a/src/libudev/libudev.h +++ b/src/libudev/libudev.h @@ -156,7 +156,7 @@ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue); struct udev *udev_queue_get_udev(struct udev_queue *udev_queue); struct udev_queue *udev_queue_new(struct udev *udev); unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) __attribute__((__deprecated__)); - unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) __attribute__((__deprecated__)); +unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) __attribute__((__deprecated__)); int udev_queue_get_udev_is_active(struct udev_queue *udev_queue); int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue); int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) __attribute__((__deprecated__)); diff --git a/src/network/meson.build b/src/network/meson.build index 4123873c60..805007782c 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -244,7 +244,6 @@ if conf.get('ENABLE_NETWORKD') == 1 [['src/network/fuzz-netdev-parser.c', 'src/fuzz/fuzz.h'], [libnetworkd_core, - libudev_static, libsystemd_network, networkd_link_with], [threads], @@ -254,7 +253,6 @@ if conf.get('ENABLE_NETWORKD') == 1 [['src/network/fuzz-network-parser.c', 'src/fuzz/fuzz.h'], [libnetworkd_core, - libudev_static, libsystemd_network, networkd_link_with], [threads], @@ -265,13 +263,11 @@ if conf.get('ENABLE_NETWORKD') == 1 tests += [ [['src/network/test-networkd-conf.c'], [libnetworkd_core, - libsystemd_network, - libudev], + libsystemd_network], [], '', '', [], network_include_dir], [['src/network/test-network.c'], [libnetworkd_core, - libudev_static, libsystemd_network, networkd_link_with], [threads], @@ -279,14 +275,12 @@ if conf.get('ENABLE_NETWORKD') == 1 [['src/network/test-routing-policy-rule.c'], [libnetworkd_core, - libsystemd_network, - libudev], + libsystemd_network], [], '', '', [], network_include_dir], [['src/network/test-network-tables.c', test_tables_h], [libnetworkd_core, - libudev_static, libsystemd_network, networkd_link_with], [threads], diff --git a/src/shared/meson.build b/src/shared/meson.build index cc9501f5b2..b43fe9c6d9 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -383,7 +383,6 @@ libshared_static = static_library( libshared = shared_library( libshared_name, - libudev_sources, include_directories : includes, link_args : ['-shared', '-Wl,--version-script=' + libshared_sym_path], diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c index 411b1f704b..df08e3a40e 100644 --- a/src/shared/udev-util.c +++ b/src/shared/udev-util.c @@ -1,12 +1,16 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include #include +#include #include #include "alloc-util.h" +#include "device-nodes.h" #include "device-util.h" #include "env-file.h" #include "escape.h" +#include "fd-util.h" #include "log.h" #include "macro.h" #include "parse-util.h" @@ -14,6 +18,7 @@ #include "signal-util.h" #include "string-table.h" #include "string-util.h" +#include "strxcpyx.h" #include "udev-util.h" #include "utf8.h" @@ -383,3 +388,171 @@ int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) { *ret_endpos = i + 1; return 0; } + +size_t udev_replace_whitespace(const char *str, char *to, size_t len) { + bool is_space = false; + size_t i, j; + + assert(str); + assert(to); + + /* Copy from 'str' to 'to', while removing all leading and trailing whitespace, and replacing + * each run of consecutive whitespace with a single underscore. The chars from 'str' are copied + * up to the \0 at the end of the string, or at most 'len' chars. This appends \0 to 'to', at + * the end of the copied characters. + * + * If 'len' chars are copied into 'to', the final \0 is placed at len+1 (i.e. 'to[len] = \0'), + * so the 'to' buffer must have at least len+1 chars available. + * + * Note this may be called with 'str' == 'to', i.e. to replace whitespace in-place in a buffer. + * This function can handle that situation. + * + * Note that only 'len' characters are read from 'str'. */ + + i = strspn(str, WHITESPACE); + + for (j = 0; j < len && i < len && str[i] != '\0'; i++) { + if (isspace(str[i])) { + is_space = true; + continue; + } + + if (is_space) { + if (j + 1 >= len) + break; + + to[j++] = '_'; + is_space = false; + } + to[j++] = str[i]; + } + + to[j] = '\0'; + return j; +} + +size_t udev_replace_chars(char *str, const char *allow) { + size_t i = 0, replaced = 0; + + assert(str); + + /* allow chars in allow list, plain ascii, hex-escaping and valid utf8. */ + + while (str[i] != '\0') { + int len; + + if (allow_listed_char_for_devnode(str[i], allow)) { + i++; + continue; + } + + /* accept hex encoding */ + if (str[i] == '\\' && str[i+1] == 'x') { + i += 2; + continue; + } + + /* accept valid utf8 */ + len = utf8_encoded_valid_unichar(str + i, (size_t) -1); + if (len > 1) { + i += len; + continue; + } + + /* if space is allowed, replace whitespace with ordinary space */ + if (isspace(str[i]) && allow && strchr(allow, ' ')) { + str[i] = ' '; + i++; + replaced++; + continue; + } + + /* everything else is replaced with '_' */ + str[i] = '_'; + i++; + replaced++; + } + return replaced; +} + +int udev_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value) { + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + _cleanup_free_ char *temp = NULL; + char *subsys, *sysname, *attr; + const char *val; + int r; + + assert(string); + assert(result); + + /* handle "[/]" format */ + + if (string[0] != '[') + return -EINVAL; + + temp = strdup(string); + if (!temp) + return -ENOMEM; + + subsys = &temp[1]; + + sysname = strchr(subsys, '/'); + if (!sysname) + return -EINVAL; + sysname[0] = '\0'; + sysname = &sysname[1]; + + attr = strchr(sysname, ']'); + if (!attr) + return -EINVAL; + attr[0] = '\0'; + attr = &attr[1]; + if (attr[0] == '/') + attr = &attr[1]; + if (attr[0] == '\0') + attr = NULL; + + if (read_value && !attr) + return -EINVAL; + + r = sd_device_new_from_subsystem_sysname(&dev, subsys, sysname); + if (r < 0) + return r; + + if (read_value) { + r = sd_device_get_sysattr_value(dev, attr, &val); + if (r < 0 && r != -ENOENT) + return r; + if (r == -ENOENT) + result[0] = '\0'; + else + strscpy(result, maxsize, val); + log_debug("value '[%s/%s]%s' is '%s'", subsys, sysname, attr, result); + } else { + r = sd_device_get_syspath(dev, &val); + if (r < 0) + return r; + + strscpyl(result, maxsize, val, attr ? "/" : NULL, attr ?: NULL, NULL); + log_debug("path '[%s/%s]%s' is '%s'", subsys, sysname, strempty(attr), result); + } + return 0; +} + +int udev_queue_is_empty(void) { + return access("/run/udev/queue", F_OK) < 0 ? + (errno == ENOENT ? true : -errno) : false; +} + +int udev_queue_init(void) { + _cleanup_close_ int fd = -1; + + fd = inotify_init1(IN_CLOEXEC); + if (fd < 0) + return -errno; + + if (inotify_add_watch(fd, "/run/udev" , IN_DELETE) < 0) + return -errno; + + return TAKE_FD(fd); +} diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h index 4e512cf754..4e6e903ddd 100644 --- a/src/shared/udev-util.h +++ b/src/shared/udev-util.h @@ -6,6 +6,10 @@ #include "device-private.h" #include "time-util.h" +#define UDEV_NAME_SIZE 512 +#define UDEV_PATH_SIZE 1024 +#define UDEV_LINE_SIZE 16384 + typedef enum ResolveNameTiming { RESOLVE_NAME_NEVER, RESOLVE_NAME_LATE, @@ -36,3 +40,9 @@ bool device_for_action(sd_device *dev, DeviceAction action); void log_device_uevent(sd_device *device, const char *str); int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos); +size_t udev_replace_whitespace(const char *str, char *to, size_t len); +size_t udev_replace_chars(char *str, const char *allow); +int udev_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value); + +int udev_queue_is_empty(void); +int udev_queue_init(void); diff --git a/src/test/meson.build b/src/test/meson.build index 3afe5d58cb..0cfc709f44 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -52,7 +52,6 @@ tests += [ [['src/test/test-engine.c'], [libcore, - libudev, libshared], [threads, librt, @@ -520,8 +519,7 @@ tests += [ 'src/journal/journald-server.h'], [libcore, libjournal_core, - libudev_core, - libudev_static, + libudevd_core, libshared], [threads, libseccomp, @@ -529,7 +527,7 @@ tests += [ libxz, liblz4, libblkid], - '', '', [], libudev_core_includes], + '', '', [], libudevd_core_includes], [['src/test/test-prioq.c'], [], @@ -751,12 +749,13 @@ tests += [ []], [['src/test/test-libudev.c'], - [libshared], - []], + [libshared, + libudev_static], + [], + '', '', [], libudev_includes], [['src/test/test-udev.c'], - [libudev_core, - libudev_static, + [libudevd_core, libshared], [threads, librt, @@ -1067,7 +1066,8 @@ tests += [ [libbasic, libshared_static, libudev], - [threads]], + [threads], + '', '', [], libudev_includes], [['src/libsystemd/sd-device/test-sd-device-monitor.c'], [], diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c index d162abaea0..12bd0d6299 100644 --- a/src/test/test-libudev.c +++ b/src/test/test-libudev.c @@ -345,92 +345,6 @@ static void test_hwdb(struct udev *udev, const char *modalias) { assert_se(hwdb == NULL); } -static void test_util_replace_whitespace_one_len(const char *str, size_t len, const char *expected) { - _cleanup_free_ char *result = NULL; - int r; - - result = new(char, len + 1); - assert_se(result); - r = util_replace_whitespace(str, result, len); - assert_se((size_t) r == strlen(expected)); - assert_se(streq(result, expected)); -} - -static void test_util_replace_whitespace_one(const char *str, const char *expected) { - test_util_replace_whitespace_one_len(str, strlen(str), expected); -} - -static void test_util_replace_whitespace(void) { - log_info("/* %s */", __func__); - - test_util_replace_whitespace_one("hogehoge", "hogehoge"); - test_util_replace_whitespace_one("hoge hoge", "hoge_hoge"); - test_util_replace_whitespace_one(" hoge hoge ", "hoge_hoge"); - test_util_replace_whitespace_one(" ", ""); - test_util_replace_whitespace_one("hoge ", "hoge"); - - test_util_replace_whitespace_one_len("hoge hoge ", 9, "hoge_hoge"); - test_util_replace_whitespace_one_len("hoge hoge ", 8, "hoge_hog"); - test_util_replace_whitespace_one_len("hoge hoge ", 7, "hoge_ho"); - test_util_replace_whitespace_one_len("hoge hoge ", 6, "hoge_h"); - test_util_replace_whitespace_one_len("hoge hoge ", 5, "hoge"); - test_util_replace_whitespace_one_len("hoge hoge ", 4, "hoge"); - test_util_replace_whitespace_one_len("hoge hoge ", 3, "hog"); - test_util_replace_whitespace_one_len("hoge hoge ", 2, "ho"); - test_util_replace_whitespace_one_len("hoge hoge ", 1, "h"); - test_util_replace_whitespace_one_len("hoge hoge ", 0, ""); - - test_util_replace_whitespace_one_len(" hoge hoge ", 16, "hoge_hoge"); - test_util_replace_whitespace_one_len(" hoge hoge ", 15, "hoge_hoge"); - test_util_replace_whitespace_one_len(" hoge hoge ", 14, "hoge_hog"); - test_util_replace_whitespace_one_len(" hoge hoge ", 13, "hoge_ho"); - test_util_replace_whitespace_one_len(" hoge hoge ", 12, "hoge_h"); - test_util_replace_whitespace_one_len(" hoge hoge ", 11, "hoge"); - test_util_replace_whitespace_one_len(" hoge hoge ", 10, "hoge"); - test_util_replace_whitespace_one_len(" hoge hoge ", 9, "hoge"); - test_util_replace_whitespace_one_len(" hoge hoge ", 8, "hoge"); - test_util_replace_whitespace_one_len(" hoge hoge ", 7, "hog"); - test_util_replace_whitespace_one_len(" hoge hoge ", 6, "ho"); - test_util_replace_whitespace_one_len(" hoge hoge ", 5, "h"); - test_util_replace_whitespace_one_len(" hoge hoge ", 4, ""); - test_util_replace_whitespace_one_len(" hoge hoge ", 3, ""); - test_util_replace_whitespace_one_len(" hoge hoge ", 2, ""); - test_util_replace_whitespace_one_len(" hoge hoge ", 1, ""); - test_util_replace_whitespace_one_len(" hoge hoge ", 0, ""); -} - -static void test_util_resolve_subsys_kernel_one(const char *str, bool read_value, int retval, const char *expected) { - char result[UTIL_PATH_SIZE] = ""; - int r; - - r = util_resolve_subsys_kernel(str, result, sizeof(result), read_value); - log_info("\"%s\" → expect: \"%s\", %d, actual: \"%s\", %d", str, strnull(expected), retval, result, r); - assert_se(r == retval); - if (r >= 0) - assert_se(streq(result, expected)); -} - -static void test_util_resolve_subsys_kernel(void) { - log_info("/* %s */", __func__); - - test_util_resolve_subsys_kernel_one("hoge", false, -EINVAL, NULL); - test_util_resolve_subsys_kernel_one("[hoge", false, -EINVAL, NULL); - test_util_resolve_subsys_kernel_one("[hoge/foo", false, -EINVAL, NULL); - test_util_resolve_subsys_kernel_one("[hoge/]", false, -ENODEV, NULL); - - test_util_resolve_subsys_kernel_one("[net/lo]", false, 0, "/sys/devices/virtual/net/lo"); - test_util_resolve_subsys_kernel_one("[net/lo]/", false, 0, "/sys/devices/virtual/net/lo"); - test_util_resolve_subsys_kernel_one("[net/lo]hoge", false, 0, "/sys/devices/virtual/net/lo/hoge"); - test_util_resolve_subsys_kernel_one("[net/lo]/hoge", false, 0, "/sys/devices/virtual/net/lo/hoge"); - - test_util_resolve_subsys_kernel_one("[net/lo]", true, -EINVAL, NULL); - test_util_resolve_subsys_kernel_one("[net/lo]/", true, -EINVAL, NULL); - test_util_resolve_subsys_kernel_one("[net/lo]hoge", true, 0, ""); - test_util_resolve_subsys_kernel_one("[net/lo]/hoge", true, 0, ""); - test_util_resolve_subsys_kernel_one("[net/lo]address", true, 0, "00:00:00:00:00:00"); - test_util_resolve_subsys_kernel_one("[net/lo]/address", true, 0, "00:00:00:00:00:00"); -} - static void test_list(void) { _cleanup_(udev_list_freep) struct udev_list *list = NULL; struct udev_list_entry *e; @@ -573,9 +487,6 @@ static int run(int argc, char *argv[]) { if (arg_monitor) test_monitor(udev); - test_util_replace_whitespace(); - test_util_resolve_subsys_kernel(); - test_list(); return 0; diff --git a/src/test/test-udev-util.c b/src/test/test-udev-util.c index b0213f8c39..f34c5c27d3 100644 --- a/src/test/test-udev-util.c +++ b/src/test/test-udev-util.c @@ -181,6 +181,92 @@ static void test_parse_value_unicode(void) { ); } +static void test_udev_replace_whitespace_one_len(const char *str, size_t len, const char *expected) { + _cleanup_free_ char *result = NULL; + int r; + + result = new(char, len + 1); + assert_se(result); + r = udev_replace_whitespace(str, result, len); + assert_se((size_t) r == strlen(expected)); + assert_se(streq(result, expected)); +} + +static void test_udev_replace_whitespace_one(const char *str, const char *expected) { + test_udev_replace_whitespace_one_len(str, strlen(str), expected); +} + +static void test_udev_replace_whitespace(void) { + log_info("/* %s */", __func__); + + test_udev_replace_whitespace_one("hogehoge", "hogehoge"); + test_udev_replace_whitespace_one("hoge hoge", "hoge_hoge"); + test_udev_replace_whitespace_one(" hoge hoge ", "hoge_hoge"); + test_udev_replace_whitespace_one(" ", ""); + test_udev_replace_whitespace_one("hoge ", "hoge"); + + test_udev_replace_whitespace_one_len("hoge hoge ", 9, "hoge_hoge"); + test_udev_replace_whitespace_one_len("hoge hoge ", 8, "hoge_hog"); + test_udev_replace_whitespace_one_len("hoge hoge ", 7, "hoge_ho"); + test_udev_replace_whitespace_one_len("hoge hoge ", 6, "hoge_h"); + test_udev_replace_whitespace_one_len("hoge hoge ", 5, "hoge"); + test_udev_replace_whitespace_one_len("hoge hoge ", 4, "hoge"); + test_udev_replace_whitespace_one_len("hoge hoge ", 3, "hog"); + test_udev_replace_whitespace_one_len("hoge hoge ", 2, "ho"); + test_udev_replace_whitespace_one_len("hoge hoge ", 1, "h"); + test_udev_replace_whitespace_one_len("hoge hoge ", 0, ""); + + test_udev_replace_whitespace_one_len(" hoge hoge ", 16, "hoge_hoge"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 15, "hoge_hoge"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 14, "hoge_hog"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 13, "hoge_ho"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 12, "hoge_h"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 11, "hoge"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 10, "hoge"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 9, "hoge"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 8, "hoge"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 7, "hog"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 6, "ho"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 5, "h"); + test_udev_replace_whitespace_one_len(" hoge hoge ", 4, ""); + test_udev_replace_whitespace_one_len(" hoge hoge ", 3, ""); + test_udev_replace_whitespace_one_len(" hoge hoge ", 2, ""); + test_udev_replace_whitespace_one_len(" hoge hoge ", 1, ""); + test_udev_replace_whitespace_one_len(" hoge hoge ", 0, ""); +} + +static void test_udev_resolve_subsys_kernel_one(const char *str, bool read_value, int retval, const char *expected) { + char result[PATH_MAX] = ""; + int r; + + r = udev_resolve_subsys_kernel(str, result, sizeof(result), read_value); + log_info("\"%s\" → expect: \"%s\", %d, actual: \"%s\", %d", str, strnull(expected), retval, result, r); + assert_se(r == retval); + if (r >= 0) + assert_se(streq(result, expected)); +} + +static void test_udev_resolve_subsys_kernel(void) { + log_info("/* %s */", __func__); + + test_udev_resolve_subsys_kernel_one("hoge", false, -EINVAL, NULL); + test_udev_resolve_subsys_kernel_one("[hoge", false, -EINVAL, NULL); + test_udev_resolve_subsys_kernel_one("[hoge/foo", false, -EINVAL, NULL); + test_udev_resolve_subsys_kernel_one("[hoge/]", false, -ENODEV, NULL); + + test_udev_resolve_subsys_kernel_one("[net/lo]", false, 0, "/sys/devices/virtual/net/lo"); + test_udev_resolve_subsys_kernel_one("[net/lo]/", false, 0, "/sys/devices/virtual/net/lo"); + test_udev_resolve_subsys_kernel_one("[net/lo]hoge", false, 0, "/sys/devices/virtual/net/lo/hoge"); + test_udev_resolve_subsys_kernel_one("[net/lo]/hoge", false, 0, "/sys/devices/virtual/net/lo/hoge"); + + test_udev_resolve_subsys_kernel_one("[net/lo]", true, -EINVAL, NULL); + test_udev_resolve_subsys_kernel_one("[net/lo]/", true, -EINVAL, NULL); + test_udev_resolve_subsys_kernel_one("[net/lo]hoge", true, 0, ""); + test_udev_resolve_subsys_kernel_one("[net/lo]/hoge", true, 0, ""); + test_udev_resolve_subsys_kernel_one("[net/lo]address", true, 0, "00:00:00:00:00:00"); + test_udev_resolve_subsys_kernel_one("[net/lo]/address", true, 0, "00:00:00:00:00:00"); +} + int main(int argc, char **argv) { test_parse_value(); test_parse_value_with_backslashes(); @@ -198,5 +284,8 @@ int main(int argc, char **argv) { test_parse_value_invalid_termination(); test_parse_value_unicode(); + test_udev_replace_whitespace(); + test_udev_resolve_subsys_kernel(); + return EXIT_SUCCESS; } diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c index ce0bf5d24b..0284630fa0 100644 --- a/src/udev/ata_id/ata_id.c +++ b/src/udev/ata_id/ata_id.c @@ -23,8 +23,8 @@ #include #include +#include "device-nodes.h" #include "fd-util.h" -#include "libudev-util.h" #include "log.h" #include "memory-util.h" #include "udev-util.h" @@ -483,13 +483,13 @@ int main(int argc, char *argv[]) { memcpy(model, id.model, 40); model[40] = '\0'; - udev_util_encode_string(model, model_enc, sizeof(model_enc)); - util_replace_whitespace((char *) id.model, model, 40); - util_replace_chars(model, NULL); - util_replace_whitespace((char *) id.serial_no, serial, 20); - util_replace_chars(serial, NULL); - util_replace_whitespace((char *) id.fw_rev, revision, 8); - util_replace_chars(revision, NULL); + encode_devnode_name(model, model_enc, sizeof(model_enc)); + udev_replace_whitespace((char *) id.model, model, 40); + udev_replace_chars(model, NULL); + udev_replace_whitespace((char *) id.serial_no, serial, 20); + udev_replace_chars(serial, NULL); + udev_replace_whitespace((char *) id.fw_rev, revision, 8); + udev_replace_chars(revision, NULL); if (export) { /* Set this to convey the disk speaks the ATA protocol */ diff --git a/src/udev/meson.build b/src/udev/meson.build index d67b459388..9170b58a8a 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -16,7 +16,7 @@ udevadm_sources = files(''' udevd.c '''.split()) -libudev_core_sources = ''' +libudevd_core_sources = ''' udev-ctrl.c udev-ctrl.h udev-event.c @@ -42,17 +42,17 @@ libudev_core_sources = ''' '''.split() if conf.get('HAVE_KMOD') == 1 - libudev_core_sources += ['udev-builtin-kmod.c'] + libudevd_core_sources += ['udev-builtin-kmod.c'] endif if conf.get('HAVE_BLKID') == 1 - libudev_core_sources += ['udev-builtin-blkid.c'] + libudevd_core_sources += ['udev-builtin-blkid.c'] endif if conf.get('HAVE_ACL') == 1 - libudev_core_sources += ['udev-builtin-uaccess.c', - logind_acl_c, - sd_login_sources] + libudevd_core_sources += ['udev-builtin-uaccess.c', + logind_acl_c, + sd_login_sources] endif ############################################################ @@ -105,15 +105,17 @@ else udev_rpath = '' endif +libudev_includes = [includes, include_directories('../libudev')] + libudev_basic = static_library( 'udev-basic', libudev_sources, - include_directories : includes, + include_directories : libudev_includes, c_args : ['-fvisibility=default']) libudev_static = static_library( 'udev_static', - include_directories : includes, + include_directories : libudev_includes, link_with : udev_link_with, link_whole : libudev_basic) @@ -126,7 +128,7 @@ install_libudev_static = static_library( libsystemd_sources, libudev_sources, disable_mempool_c, - include_directories : includes, + include_directories : libudev_includes, build_by_default : static_libudev != 'false', install : static_libudev != 'false', install_dir : rootlibdir, @@ -139,7 +141,7 @@ libudev = shared_library( 'udev', disable_mempool_c, version : libudev_version, - include_directories : includes, + include_directories : libudev_includes, link_args : ['-shared', '-Wl,--version-script=' + libudev_sym_path], link_with : [libsystemd_static, libshared_static], @@ -149,13 +151,15 @@ libudev = shared_library( install : true, install_dir : rootlibdir) -libudev_core_includes = [includes, include_directories('net')] -libudev_core = static_library( +############################################################ + +libudevd_core_includes = [includes, include_directories('net')] +libudevd_core = static_library( 'udev-core', - libudev_core_sources, + libudevd_core_sources, link_config_gperf_c, keyboard_keys_from_name_h, - include_directories : libudev_core_includes, + include_directories : libudevd_core_includes, c_args : ['-DLOG_REALM=LOG_REALM_UDEV'], link_with : udev_link_with, dependencies : [libblkid, libkmod]) @@ -179,7 +183,7 @@ foreach prog : [['ata_id/ata_id.c'], include_directories : includes, c_args : ['-DLOG_REALM=LOG_REALM_UDEV'], dependencies : [versiondep], - link_with : [libudev_static], + link_with : udev_link_with, install_rpath : udev_rpath, install : true, install_dir : udevlibexecdir) @@ -204,8 +208,7 @@ endif fuzzers += [ [['src/udev/net/fuzz-link-parser.c', 'src/fuzz/fuzz.h'], - [libudev_core, - libudev_static, + [libudevd_core, libshared], [threads, libacl]], diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c index 57202564da..bce8b4c69f 100644 --- a/src/udev/scsi_id/scsi_id.c +++ b/src/udev/scsi_id/scsi_id.c @@ -18,8 +18,8 @@ #include "alloc-util.h" #include "build.h" +#include "device-nodes.h" #include "fd-util.h" -#include "libudev-util.h" #include "scsi_id.h" #include "string-util.h" #include "strxcpyx.h" @@ -453,16 +453,16 @@ static int set_inq_values(struct scsi_id_device *dev_scsi, const char *path) { if (retval) return retval; - udev_util_encode_string(dev_scsi->vendor, vendor_enc_str, sizeof(vendor_enc_str)); - udev_util_encode_string(dev_scsi->model, model_enc_str, sizeof(model_enc_str)); + encode_devnode_name(dev_scsi->vendor, vendor_enc_str, sizeof(vendor_enc_str)); + encode_devnode_name(dev_scsi->model, model_enc_str, sizeof(model_enc_str)); - util_replace_whitespace(dev_scsi->vendor, vendor_str, sizeof(vendor_str)-1); - util_replace_chars(vendor_str, NULL); - util_replace_whitespace(dev_scsi->model, model_str, sizeof(model_str)-1); - util_replace_chars(model_str, NULL); + udev_replace_whitespace(dev_scsi->vendor, vendor_str, sizeof(vendor_str)-1); + udev_replace_chars(vendor_str, NULL); + udev_replace_whitespace(dev_scsi->model, model_str, sizeof(model_str)-1); + udev_replace_chars(model_str, NULL); set_type(dev_scsi->type, type_str, sizeof(type_str)); - util_replace_whitespace(dev_scsi->revision, revision_str, sizeof(revision_str)-1); - util_replace_chars(revision_str, NULL); + udev_replace_whitespace(dev_scsi->revision, revision_str, sizeof(revision_str)-1); + udev_replace_chars(revision_str, NULL); return 0; } @@ -502,11 +502,11 @@ static int scsi_id(char *maj_min_dev) { printf("ID_REVISION=%s\n", revision_str); printf("ID_TYPE=%s\n", type_str); if (dev_scsi.serial[0] != '\0') { - util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)-1); - util_replace_chars(serial_str, NULL); + udev_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)-1); + udev_replace_chars(serial_str, NULL); printf("ID_SERIAL=%s\n", serial_str); - util_replace_whitespace(dev_scsi.serial_short, serial_str, sizeof(serial_str)-1); - util_replace_chars(serial_str, NULL); + udev_replace_whitespace(dev_scsi.serial_short, serial_str, sizeof(serial_str)-1); + udev_replace_chars(serial_str, NULL); printf("ID_SERIAL_SHORT=%s\n", serial_str); } if (dev_scsi.wwn[0] != '\0') { @@ -532,8 +532,8 @@ static int scsi_id(char *maj_min_dev) { if (reformat_serial) { char serial_str[MAX_SERIAL_LEN]; - util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)-1); - util_replace_chars(serial_str, NULL); + udev_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)-1); + udev_replace_chars(serial_str, NULL); printf("%s\n", serial_str); goto out; } diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index 0da59e2c75..09cc1c3bd8 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -17,11 +17,11 @@ #include "alloc-util.h" #include "dirent-util.h" #include "fd-util.h" -#include "libudev-util.h" #include "string-util.h" #include "strv.h" #include "sysexits.h" #include "udev-builtin.h" +#include "udev-util.h" _printf_(2,3) static void path_prepend(char **path, const char *fmt, ...) { @@ -680,7 +680,7 @@ static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) { return -ENOENT; { - char tag[UTIL_NAME_SIZE]; + char tag[UDEV_NAME_SIZE]; size_t i; const char *p; diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c index fa554e740f..7d94c6b0a3 100644 --- a/src/udev/udev-builtin-usb_id.c +++ b/src/udev/udev-builtin-usb_id.c @@ -15,12 +15,13 @@ #include #include "alloc-util.h" +#include "device-nodes.h" #include "device-util.h" #include "fd-util.h" -#include "libudev-util.h" #include "string-util.h" #include "strxcpyx.h" #include "udev-builtin.h" +#include "udev-util.h" static void set_usb_iftype(char *to, int if_class_num, size_t len) { const char *type = "generic"; @@ -234,8 +235,8 @@ static int builtin_usb_id(sd_device *dev, int argc, char *argv[], bool test) { char model_str[64] = ""; char model_str_enc[256]; const char *product_id; - char serial_str[UTIL_NAME_SIZE] = ""; - char packed_if_str[UTIL_NAME_SIZE] = ""; + char serial_str[UDEV_NAME_SIZE] = ""; + char packed_if_str[UDEV_NAME_SIZE] = ""; char revision_str[64] = ""; char type_str[64] = ""; char instance_str[64] = ""; @@ -328,18 +329,18 @@ static int builtin_usb_id(sd_device *dev, int argc, char *argv[], bool test) { log_device_debug_errno(dev_scsi, r, "Failed to get SCSI vendor attribute: %m"); goto fallback; } - udev_util_encode_string(scsi_vendor, vendor_str_enc, sizeof(vendor_str_enc)); - util_replace_whitespace(scsi_vendor, vendor_str, sizeof(vendor_str)-1); - util_replace_chars(vendor_str, NULL); + encode_devnode_name(scsi_vendor, vendor_str_enc, sizeof(vendor_str_enc)); + udev_replace_whitespace(scsi_vendor, vendor_str, sizeof(vendor_str)-1); + udev_replace_chars(vendor_str, NULL); r = sd_device_get_sysattr_value(dev_scsi, "model", &scsi_model); if (r < 0) { log_device_debug_errno(dev_scsi, r, "Failed to get SCSI model attribute: %m"); goto fallback; } - udev_util_encode_string(scsi_model, model_str_enc, sizeof(model_str_enc)); - util_replace_whitespace(scsi_model, model_str, sizeof(model_str)-1); - util_replace_chars(model_str, NULL); + encode_devnode_name(scsi_model, model_str_enc, sizeof(model_str_enc)); + udev_replace_whitespace(scsi_model, model_str, sizeof(model_str)-1); + udev_replace_chars(model_str, NULL); r = sd_device_get_sysattr_value(dev_scsi, "type", &scsi_type); if (r < 0) { @@ -353,8 +354,8 @@ static int builtin_usb_id(sd_device *dev, int argc, char *argv[], bool test) { log_device_debug_errno(dev_scsi, r, "Failed to get SCSI revision attribute: %m"); goto fallback; } - util_replace_whitespace(scsi_rev, revision_str, sizeof(revision_str)-1); - util_replace_chars(revision_str, NULL); + udev_replace_whitespace(scsi_rev, revision_str, sizeof(revision_str)-1); + udev_replace_chars(revision_str, NULL); /* * some broken devices have the same identifiers @@ -378,9 +379,9 @@ fallback: if (sd_device_get_sysattr_value(dev_usb, "manufacturer", &usb_vendor) < 0) usb_vendor = vendor_id; - udev_util_encode_string(usb_vendor, vendor_str_enc, sizeof(vendor_str_enc)); - util_replace_whitespace(usb_vendor, vendor_str, sizeof(vendor_str)-1); - util_replace_chars(vendor_str, NULL); + encode_devnode_name(usb_vendor, vendor_str_enc, sizeof(vendor_str_enc)); + udev_replace_whitespace(usb_vendor, vendor_str, sizeof(vendor_str)-1); + udev_replace_chars(vendor_str, NULL); } if (model_str[0] == '\0') { @@ -388,17 +389,17 @@ fallback: if (sd_device_get_sysattr_value(dev_usb, "product", &usb_model) < 0) usb_model = product_id; - udev_util_encode_string(usb_model, model_str_enc, sizeof(model_str_enc)); - util_replace_whitespace(usb_model, model_str, sizeof(model_str)-1); - util_replace_chars(model_str, NULL); + encode_devnode_name(usb_model, model_str_enc, sizeof(model_str_enc)); + udev_replace_whitespace(usb_model, model_str, sizeof(model_str)-1); + udev_replace_chars(model_str, NULL); } if (revision_str[0] == '\0') { const char *usb_rev; if (sd_device_get_sysattr_value(dev_usb, "bcdDevice", &usb_rev) >= 0) { - util_replace_whitespace(usb_rev, revision_str, sizeof(revision_str)-1); - util_replace_chars(revision_str, NULL); + udev_replace_whitespace(usb_rev, revision_str, sizeof(revision_str)-1); + udev_replace_chars(revision_str, NULL); } } @@ -416,8 +417,8 @@ fallback: } if (usb_serial) { - util_replace_whitespace(usb_serial, serial_str, sizeof(serial_str)-1); - util_replace_chars(serial_str, NULL); + udev_replace_whitespace(usb_serial, serial_str, sizeof(serial_str)-1); + udev_replace_chars(serial_str, NULL); } } } diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c index 64051d0aa8..c65f8772ea 100644 --- a/src/udev/udev-ctrl.c +++ b/src/udev/udev-ctrl.c @@ -1,12 +1,4 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later - * - * libudev - interface to udev device information - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - */ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 307f949fde..cd1a926602 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -17,7 +17,6 @@ #include "fd-util.h" #include "fs-util.h" #include "format-util.h" -#include "libudev-util.h" #include "netlink-util.h" #include "parse-util.h" #include "path-util.h" @@ -152,7 +151,7 @@ static char format_type_to_char(FormatSubstitutionType t) { return '\0'; } -static int get_subst_type(const char **str, bool strict, FormatSubstitutionType *ret_type, char ret_attr[static UTIL_PATH_SIZE]) { +static int get_subst_type(const char **str, bool strict, FormatSubstitutionType *ret_type, char ret_attr[static UDEV_PATH_SIZE]) { const char *p = *str, *q = NULL; size_t i; @@ -198,10 +197,10 @@ static int get_subst_type(const char **str, bool strict, FormatSubstitutionType return -EINVAL; len = end - start; - if (len == 0 || len >= UTIL_PATH_SIZE) + if (len == 0 || len >= UDEV_PATH_SIZE) return -EINVAL; - strnscpy(ret_attr, UTIL_PATH_SIZE, start, len); + strnscpy(ret_attr, UDEV_PATH_SIZE, start, len); q = end + 1; } else *ret_attr = '\0'; @@ -339,14 +338,14 @@ static ssize_t udev_event_subst_format( break; } case FORMAT_SUBST_ATTR: { - char vbuf[UTIL_NAME_SIZE]; + char vbuf[UDEV_NAME_SIZE]; int count; if (isempty(attr)) return -EINVAL; /* try to read the value specified by "[dmi/id]product_name" */ - if (util_resolve_subsys_kernel(attr, vbuf, sizeof(vbuf), true) == 0) + if (udev_resolve_subsys_kernel(attr, vbuf, sizeof(vbuf), true) == 0) val = vbuf; /* try to read the attribute the device */ @@ -364,7 +363,7 @@ static ssize_t udev_event_subst_format( if (val != vbuf) strscpy(vbuf, sizeof(vbuf), val); delete_trailing_chars(vbuf, NULL); - count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT); + count = udev_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT); if (count > 0) log_device_debug(dev, "%i character(s) replaced", count); l = strpcpy(&s, l, vbuf); @@ -453,7 +452,7 @@ size_t udev_event_apply_format(UdevEvent *event, while (*s) { FormatSubstitutionType type; - char attr[UTIL_PATH_SIZE]; + char attr[UDEV_PATH_SIZE]; ssize_t subst_len; r = get_subst_type(&s, false, &type, attr); @@ -478,9 +477,9 @@ size_t udev_event_apply_format(UdevEvent *event, /* FORMAT_SUBST_RESULT handles spaces itself */ if (replace_whitespace && type != FORMAT_SUBST_RESULT) - /* util_replace_whitespace can replace in-place, + /* udev_replace_whitespace can replace in-place, * and does nothing if subst_len == 0 */ - subst_len = util_replace_whitespace(dest, dest, subst_len); + subst_len = udev_replace_whitespace(dest, dest, subst_len); dest += subst_len; size -= subst_len; @@ -494,7 +493,7 @@ size_t udev_event_apply_format(UdevEvent *event, int udev_check_format(const char *value, size_t *offset, const char **hint) { FormatSubstitutionType type; const char *s = value; - char attr[UTIL_PATH_SIZE]; + char attr[UDEV_PATH_SIZE]; int r; while (*s) { diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h index 27bf8f9372..ecbe957b4f 100644 --- a/src/udev/udev-event.h +++ b/src/udev/udev-event.h @@ -16,6 +16,7 @@ #define READ_END 0 #define WRITE_END 1 +#define UDEV_ALLOWED_CHARS_INPUT "/ $%?," typedef struct UdevEvent { sd_device *dev; diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 2cc78c9e2f..d21be61ae5 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -15,7 +15,6 @@ #include "fd-util.h" #include "format-util.h" #include "fs-util.h" -#include "libudev-util.h" #include "mkdir.h" #include "path-util.h" #include "selinux-util.h" @@ -192,6 +191,40 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, return 0; } +static size_t escape_path(const char *src, char *dest, size_t size) { + size_t i, j; + + assert(src); + assert(dest); + + 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 (src[i] == '\\') { + if (j+4 >= size) { + j = 0; + break; + } + memcpy(&dest[j], "\\x5c", 4); + j += 4; + } else { + if (j+1 >= size) { + j = 0; + break; + } + dest[j] = src[i]; + j++; + } + } + dest[j] = '\0'; + return j; +} + /* manage "stack of names" with possibly specified device priorities */ static int link_update(sd_device *dev, const char *slink, bool add) { _cleanup_free_ char *target = NULL, *filename = NULL, *dirname = NULL; @@ -206,7 +239,7 @@ static int link_update(sd_device *dev, const char *slink, bool add) { if (r < 0) return log_device_debug_errno(dev, r, "Failed to get id_filename: %m"); - util_path_encode(slink + STRLEN("/dev"), name_enc, sizeof(name_enc)); + escape_path(slink + STRLEN("/dev"), name_enc, sizeof(name_enc)); dirname = path_join("/run/udev/links/", name_enc); if (!dirname) return log_oom(); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 48fd33fded..56d680c12f 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -14,7 +14,6 @@ #include "format-util.h" #include "fs-util.h" #include "glob-util.h" -#include "libudev-util.h" #include "list.h" #include "mkdir.h" #include "nulstr-util.h" @@ -76,7 +75,7 @@ typedef enum { TK_M_TAG, /* strv, sd_device_get_tag_first(), sd_device_get_tag_next() */ TK_M_SUBSYSTEM, /* string, sd_device_get_subsystem() */ TK_M_DRIVER, /* string, sd_device_get_driver() */ - TK_M_ATTR, /* string, takes filename through attribute, sd_device_get_sysattr_value(), util_resolve_subsys_kernel(), etc. */ + TK_M_ATTR, /* string, takes filename through attribute, sd_device_get_sysattr_value(), udev_resolve_subsys_kernel(), etc. */ TK_M_SYSCTL, /* string, takes kernel parameter through attribute */ /* matches parent parameters */ @@ -1224,7 +1223,7 @@ int udev_rules_parse_file(UdevRules *rules, const char *filename) { size_t len; char *line; - r = read_line(f, UTIL_LINE_SIZE, &buf); + r = read_line(f, UDEV_LINE_SIZE, &buf); if (r < 0) return r; if (r == 0) @@ -1239,7 +1238,7 @@ int udev_rules_parse_file(UdevRules *rules, const char *filename) { len = strlen(line); if (continuation && !ignore_line) { - if (strlen(continuation) + len >= UTIL_LINE_SIZE) + if (strlen(continuation) + len >= UDEV_LINE_SIZE) ignore_line = true; if (!strextend(&continuation, line, NULL)) @@ -1377,7 +1376,7 @@ static bool token_match_string(UdevRuleToken *token, const char *str) { } static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *event) { - char nbuf[UTIL_NAME_SIZE], vbuf[UTIL_NAME_SIZE]; + char nbuf[UDEV_NAME_SIZE], vbuf[UDEV_NAME_SIZE]; const char *name, *value; assert(token); @@ -1396,7 +1395,7 @@ static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *ev return false; break; case SUBST_TYPE_SUBSYS: - if (util_resolve_subsys_kernel(name, vbuf, sizeof(vbuf), true) < 0) + if (udev_resolve_subsys_kernel(name, vbuf, sizeof(vbuf), true) < 0) return false; value = vbuf; break; @@ -1487,10 +1486,10 @@ static int import_parent_into_properties(sd_device *dev, const char *filter) { return 1; } -static int attr_subst_subdir(char attr[static UTIL_PATH_SIZE]) { +static int attr_subst_subdir(char attr[static UDEV_PATH_SIZE]) { _cleanup_closedir_ DIR *dir = NULL; struct dirent *dent; - char buf[UTIL_PATH_SIZE], *p; + char buf[UDEV_PATH_SIZE], *p; const char *tail; size_t len, size; @@ -1535,7 +1534,7 @@ static int udev_rule_apply_token_to_event( Hashmap *properties_list) { UdevRuleToken *token; - char buf[UTIL_PATH_SIZE]; + char buf[UDEV_PATH_SIZE]; const char *val; size_t count; bool match; @@ -1641,8 +1640,8 @@ static int udev_rule_apply_token_to_event( (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false); if (!path_is_absolute(buf) && - util_resolve_subsys_kernel(buf, buf, sizeof(buf), false) < 0) { - char tmp[UTIL_PATH_SIZE]; + udev_resolve_subsys_kernel(buf, buf, sizeof(buf), false) < 0) { + char tmp[UDEV_PATH_SIZE]; r = sd_device_get_syspath(dev, &val); if (r < 0) @@ -1668,7 +1667,7 @@ static int udev_rule_apply_token_to_event( return token->op == (match ? OP_MATCH : OP_NOMATCH); } case TK_M_PROGRAM: { - char result[UTIL_LINE_SIZE]; + char result[UDEV_LINE_SIZE]; event->program_result = mfree(event->program_result); (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false); @@ -1684,7 +1683,7 @@ static int udev_rule_apply_token_to_event( } delete_trailing_chars(result, "\n"); - count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT); + count = udev_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT); if (count > 0) log_rule_debug(dev, rules, "Replaced %zu character(s) in result of \"%s\"", count, buf); @@ -1739,7 +1738,7 @@ static int udev_rule_apply_token_to_event( return token->op == OP_MATCH; } case TK_M_IMPORT_PROGRAM: { - char result[UTIL_LINE_SIZE], *line, *pos; + char result[UDEV_LINE_SIZE], *line, *pos; (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false); log_rule_debug(dev, rules, "Importing properties from results of '%s'", buf); @@ -1888,7 +1887,7 @@ static int udev_rule_apply_token_to_event( break; } case TK_A_OWNER: { - char owner[UTIL_NAME_SIZE]; + char owner[UDEV_NAME_SIZE]; const char *ow = owner; if (event->owner_final) @@ -1905,7 +1904,7 @@ static int udev_rule_apply_token_to_event( break; } case TK_A_GROUP: { - char group[UTIL_NAME_SIZE]; + char group[UDEV_NAME_SIZE]; const char *gr = group; if (event->group_final) @@ -1922,7 +1921,7 @@ static int udev_rule_apply_token_to_event( break; } case TK_A_MODE: { - char mode_str[UTIL_NAME_SIZE]; + char mode_str[UDEV_NAME_SIZE]; if (event->mode_final) break; @@ -1969,7 +1968,7 @@ static int udev_rule_apply_token_to_event( break; case TK_A_SECLABEL: { _cleanup_free_ char *name = NULL, *label = NULL; - char label_str[UTIL_LINE_SIZE] = {}; + char label_str[UDEV_LINE_SIZE] = {}; name = strdup(token->data); if (!name) @@ -1999,7 +1998,7 @@ static int udev_rule_apply_token_to_event( } case TK_A_ENV: { const char *name = token->data; - char value_new[UTIL_NAME_SIZE], *p = value_new; + char value_new[UDEV_NAME_SIZE], *p = value_new; size_t l = sizeof(value_new); if (isempty(token->value)) { @@ -2048,7 +2047,7 @@ static int udev_rule_apply_token_to_event( (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false); if (IN_SET(event->esc, ESCAPE_UNSET, ESCAPE_REPLACE)) { - count = util_replace_chars(buf, "/"); + count = udev_replace_chars(buf, "/"); if (count > 0) log_rule_debug(dev, rules, "Replaced %zu character(s) from result of NAME=\"%s\"", count, token->value); @@ -2082,9 +2081,9 @@ static int udev_rule_apply_token_to_event( /* allow multiple symlinks separated by spaces */ (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), event->esc != ESCAPE_NONE); if (event->esc == ESCAPE_UNSET) - count = util_replace_chars(buf, "/ "); + count = udev_replace_chars(buf, "/ "); else if (event->esc == ESCAPE_REPLACE) - count = util_replace_chars(buf, "/"); + count = udev_replace_chars(buf, "/"); else count = 0; if (count > 0) @@ -2092,7 +2091,7 @@ static int udev_rule_apply_token_to_event( p = skip_leading_chars(buf, NULL); while (!isempty(p)) { - char filename[UTIL_PATH_SIZE], *next; + char filename[UDEV_PATH_SIZE], *next; next = strchr(p, ' '); if (next) { @@ -2112,9 +2111,9 @@ static int udev_rule_apply_token_to_event( } case TK_A_ATTR: { const char *key_name = token->data; - char value[UTIL_NAME_SIZE]; + char value[UDEV_NAME_SIZE]; - if (util_resolve_subsys_kernel(key_name, buf, sizeof(buf), false) < 0 && + if (udev_resolve_subsys_kernel(key_name, buf, sizeof(buf), false) < 0 && sd_device_get_syspath(dev, &val) >= 0) strscpyl(buf, sizeof(buf), val, "/", key_name, NULL); @@ -2132,7 +2131,7 @@ static int udev_rule_apply_token_to_event( break; } case TK_A_SYSCTL: { - char value[UTIL_NAME_SIZE]; + char value[UDEV_NAME_SIZE]; (void) udev_event_apply_format(event, token->data, buf, sizeof(buf), false); (void) udev_event_apply_format(event, token->value, value, sizeof(value), false); @@ -2305,7 +2304,7 @@ int udev_rules_apply_to_event( } static int apply_static_dev_perms(const char *devnode, uid_t uid, gid_t gid, mode_t mode, char **tags) { - char device_node[UTIL_PATH_SIZE], tags_dir[UTIL_PATH_SIZE], tag_symlink[UTIL_PATH_SIZE]; + char device_node[UDEV_PATH_SIZE], tags_dir[UDEV_PATH_SIZE], tag_symlink[UDEV_PATH_SIZE]; _cleanup_free_ char *unescaped_filename = NULL; struct stat stats; char **t; diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c index 2bd5853553..33d7990572 100644 --- a/src/udev/udevadm-settle.c +++ b/src/udev/udevadm-settle.c @@ -17,12 +17,13 @@ #include "sd-messages.h" #include "bus-util.h" +#include "fd-util.h" #include "io-util.h" -#include "libudev-util.h" #include "string-util.h" #include "strv.h" #include "time-util.h" #include "udev-ctrl.h" +#include "udev-util.h" #include "udevadm.h" #include "unit-def.h" #include "util.h" @@ -158,9 +159,9 @@ static int emit_deprecation_warning(void) { } int settle_main(int argc, char *argv[], void *userdata) { - _cleanup_(udev_queue_unrefp) struct udev_queue *queue = NULL; + _cleanup_close_ int fd = -1; usec_t deadline; - int r, fd; + int r; r = parse_argv(argc, argv); if (r <= 0) @@ -190,11 +191,7 @@ int settle_main(int argc, char *argv[], void *userdata) { } } - queue = udev_queue_new(NULL); - if (!queue) - return log_error_errno(errno, "Failed to get udev queue: %m"); - - fd = udev_queue_get_fd(queue); + fd = udev_queue_init(); if (fd < 0) { log_debug_errno(fd, "Queue is empty, nothing to watch: %m"); return 0; @@ -207,7 +204,10 @@ int settle_main(int argc, char *argv[], void *userdata) { return 0; /* exit if queue is empty */ - if (udev_queue_get_queue_is_empty(queue)) + r = udev_queue_is_empty(); + if (r < 0) + return log_error_errno(r, "Failed to check queue is empty: %m"); + if (r > 0) return 0; if (now(CLOCK_MONOTONIC) >= deadline) @@ -218,7 +218,7 @@ int settle_main(int argc, char *argv[], void *userdata) { if (r < 0) return r; if (r & POLLIN) { - r = udev_queue_flush(queue); + r = flush_fd(fd); if (r < 0) return log_error_errno(r, "Failed to flush queue: %m"); } diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index 747047dac8..e6a5f423e5 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -16,7 +16,6 @@ #include "device-private.h" #include "device-util.h" -#include "libudev-util.h" #include "path-util.h" #include "string-util.h" #include "strxcpyx.h" @@ -26,7 +25,7 @@ static const char *arg_action = "add"; static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY; -static char arg_syspath[UTIL_PATH_SIZE] = {}; +static char arg_syspath[UDEV_PATH_SIZE] = {}; static int help(void) { @@ -149,7 +148,7 @@ int test_main(int argc, char *argv[], void *userdata) { printf("%s=%s\n", key, value); ORDERED_HASHMAP_FOREACH_KEY(val, cmd, event->run_list) { - char program[UTIL_PATH_SIZE]; + char program[UDEV_PATH_SIZE]; (void) udev_event_apply_format(event, cmd, program, sizeof(program), false); printf("run: '%s'\n", program); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 5d02a9d27c..ef344e8a4d 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -42,7 +42,6 @@ #include "fs-util.h" #include "hashmap.h" #include "io-util.h" -#include "libudev-device-internal.h" #include "limits-util.h" #include "list.h" #include "main-func.h" diff --git a/test/fuzz/fuzz-udev-rules/99-systemd.rules b/test/fuzz/fuzz-udev-rules/99-systemd.rules index b6a5c5ad55..e8a0f5a739 100644 --- a/test/fuzz/fuzz-udev-rules/99-systemd.rules +++ b/test/fuzz/fuzz-udev-rules/99-systemd.rules @@ -42,8 +42,6 @@ SUBSYSTEM=="block", KERNEL=="nbd*", ENV{DEVTYPE}=="disk", TEST!="pid", ENV{SYSTE # just an identification string for systemd, so whether the path actually is # accessible or not does not matter as long as it is unique and in the # filesystem namespace. -# -# http://cgit.freedesktop.org/systemd/systemd/tree/src/libudev/libudev-enumerate.c#n955 SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/net/devices/$name" SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k"