From 0578371f53637d42931c4f197ead05153a0dc68d Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sun, 3 Mar 2024 17:56:57 +0800 Subject: [PATCH 1/4] core/service: minor cleanup for service_add_fd_store --- src/core/service.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/service.c b/src/core/service.c index 9ba2e09a81..e575e24664 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -523,7 +523,8 @@ static int service_add_fd_store(Service *s, int fd_in, const char *name, bool do if (fstat(fd, &st) < 0) return -errno; - log_unit_debug(UNIT(s), "Trying to stash fd for dev=" DEVNUM_FORMAT_STR "/inode=%" PRIu64, DEVNUM_FORMAT_VAL(st.st_dev), (uint64_t) st.st_ino); + log_unit_debug(UNIT(s), "Trying to stash fd for dev=" DEVNUM_FORMAT_STR "/inode=%" PRIu64, + DEVNUM_FORMAT_VAL(st.st_dev), (uint64_t) st.st_ino); if (s->n_fd_store >= s->n_fd_store_max) /* Our store is full. Use this errno rather than E[NM]FILE to distinguish from the case @@ -557,17 +558,16 @@ static int service_add_fd_store(Service *s, int fd_in, const char *name, bool do r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fs->fd, 0, on_fd_store_io, fs); if (r < 0 && r != -EPERM) /* EPERM indicates fds that aren't pollable, which is OK */ return r; - else if (r >= 0) + if (r >= 0) (void) sd_event_source_set_description(fs->event_source, "service-fd-store"); } - fs->service = s; - LIST_PREPEND(fd_store, s->fd_store, fs); - s->n_fd_store++; - log_unit_debug(UNIT(s), "Added fd %i (%s) to fd store.", fs->fd, fs->fdname); - TAKE_PTR(fs); + fs->service = s; + LIST_PREPEND(fd_store, s->fd_store, TAKE_PTR(fs)); + s->n_fd_store++; + return 1; /* fd newly stored */ } From 4f49512695f8214c55c206b3c2f583dc7b309e1b Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sun, 3 Mar 2024 18:13:52 +0800 Subject: [PATCH 2/4] extract-word: modernize extract_many_words --- src/basic/extract-word.c | 35 +++++++++---------------- src/basic/extract-word.h | 5 +++- src/basic/strv.c | 2 +- src/basic/time-util.c | 4 +-- src/core/dynamic-user.c | 2 +- src/core/execute-serialize.c | 34 ++++++++++++------------ src/core/load-fragment.c | 8 +++--- src/fstab-generator/fstab-generator.c | 4 +-- src/hostname/hostnamed.c | 2 +- src/network/networkd-dhcp-common.c | 2 +- src/nspawn/nspawn-mount.c | 2 +- src/partition/repart.c | 4 +-- src/resolve/resolved-dns-trust-anchor.c | 6 ++--- src/shared/bus-unit-util.c | 10 +++---- src/shared/cgroup-setup.c | 2 +- src/shared/condition.c | 4 +-- src/shared/open-file.c | 2 +- src/sleep/battery-capacity.c | 2 +- src/systemctl/systemctl-mount.c | 2 +- src/sysusers/sysusers.c | 2 +- src/test/test-extract-word.c | 20 +++++++------- src/udev/scsi_id/scsi_id.c | 6 ++--- src/udev/udevadm-info.c | 2 +- 23 files changed, 78 insertions(+), 84 deletions(-) diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c index 160f771b22..012cee6e75 100644 --- a/src/basic/extract-word.c +++ b/src/basic/extract-word.c @@ -244,52 +244,43 @@ int extract_first_word_and_warn( * Let's make sure that ExtractFlags fits into an unsigned int. */ assert_cc(sizeof(enum ExtractFlags) <= sizeof(unsigned)); -int extract_many_words(const char **p, const char *separators, unsigned flags, ...) { +int extract_many_words_internal(const char **p, const char *separators, unsigned flags, ...) { va_list ap; - char **l; - int n = 0, i, c, r; + unsigned n = 0; + int r; - /* Parses a number of words from a string, stripping any - * quotes if necessary. */ + /* Parses a number of words from a string, stripping any quotes if necessary. */ assert(p); /* Count how many words are expected */ va_start(ap, flags); - for (;;) { - if (!va_arg(ap, char **)) - break; + while (va_arg(ap, char**)) n++; - } va_end(ap); - if (n <= 0) + if (n == 0) return 0; /* Read all words into a temporary array */ - l = newa0(char*, n); - for (c = 0; c < n; c++) { + char **l = newa0(char*, n); + unsigned c; + for (c = 0; c < n; c++) { r = extract_first_word(p, &l[c], separators, flags); if (r < 0) { free_many_charp(l, c); return r; } - if (r == 0) break; } - /* If we managed to parse all words, return them in the passed - * in parameters */ + /* If we managed to parse all words, return them in the passed in parameters */ va_start(ap, flags); - for (i = 0; i < n; i++) { - char **v; - - v = va_arg(ap, char **); - assert(v); - - *v = l[i]; + FOREACH_ARRAY(i, l, n) { + char **v = ASSERT_PTR(va_arg(ap, char**)); + *v = *i; } va_end(ap); diff --git a/src/basic/extract-word.h b/src/basic/extract-word.h index c82ad761ef..da4f6ae674 100644 --- a/src/basic/extract-word.h +++ b/src/basic/extract-word.h @@ -19,4 +19,7 @@ typedef enum ExtractFlags { int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags); int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue); -int extract_many_words(const char **p, const char *separators, unsigned flags, ...) _sentinel_; + +int extract_many_words_internal(const char **p, const char *separators, unsigned flags, ...) _sentinel_; +#define extract_many_words(p, separators, flags, ...) \ + extract_many_words_internal(p, separators, flags, ##__VA_ARGS__, NULL) diff --git a/src/basic/strv.c b/src/basic/strv.c index 72cbbfe2f4..208108d6c0 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -358,7 +358,7 @@ int strv_split_colon_pairs(char ***t, const char *s) { const char *p = tuple; r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, - &first, &second, NULL); + &first, &second); if (r < 0) return r; if (r == 0) diff --git a/src/basic/time-util.c b/src/basic/time-util.c index 02123dc591..d1736f0aa3 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -1429,7 +1429,7 @@ static int get_timezones_from_zone1970_tab(char ***ret) { /* Line format is: * 'country codes' 'coordinates' 'timezone' 'comments' */ - r = extract_many_words(&p, NULL, 0, &cc, &co, &tz, NULL); + r = extract_many_words(&p, NULL, 0, &cc, &co, &tz); if (r < 0) continue; @@ -1474,7 +1474,7 @@ static int get_timezones_from_tzdata_zi(char ***ret) { * Link line format is: * 'Link' 'target' 'alias' * See 'man zic' for more detail. */ - r = extract_many_words(&p, NULL, 0, &type, &f1, &f2, NULL); + r = extract_many_words(&p, NULL, 0, &type, &f1, &f2); if (r < 0) continue; diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index 8462a31e5b..4f8f764733 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -651,7 +651,7 @@ void dynamic_user_deserialize_one(Manager *m, const char *value, FDSet *fds, Dyn /* Parse the serialization again, after a daemon reload */ - r = extract_many_words(&value, NULL, 0, &name, &s0, &s1, NULL); + r = extract_many_words(&value, NULL, 0, &name, &s0, &s1); if (r != 3 || !isempty(value)) { log_debug("Unable to parse dynamic user line."); return; diff --git a/src/core/execute-serialize.c b/src/core/execute-serialize.c index b991dc0bc8..98ae2b0bcd 100644 --- a/src/core/execute-serialize.c +++ b/src/core/execute-serialize.c @@ -788,7 +788,7 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) { _cleanup_free_ char *path = NULL, *rwm = NULL; CGroupDevicePermissions p; - r = extract_many_words(&val, " ", 0, &path, &rwm, NULL); + r = extract_many_words(&val, " ", 0, &path, &rwm); if (r < 0) return r; if (r == 0) @@ -805,7 +805,7 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) { _cleanup_free_ char *path = NULL, *weight = NULL; CGroupIODeviceWeight *a = NULL; - r = extract_many_words(&val, " ", 0, &path, &weight, NULL); + r = extract_many_words(&val, " ", 0, &path, &weight); if (r < 0) return r; if (r != 2) @@ -834,7 +834,7 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) { _cleanup_free_ char *path = NULL, *target = NULL; CGroupIODeviceLatency *a = NULL; - r = extract_many_words(&val, " ", 0, &path, &target, NULL); + r = extract_many_words(&val, " ", 0, &path, &target); if (r < 0) return r; if (r != 2) @@ -864,7 +864,7 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) { CGroupIODeviceLimit *limit = NULL; CGroupIOLimitType t; - r = extract_many_words(&val, "= ", 0, &type, &path, &limits, NULL); + r = extract_many_words(&val, "= ", 0, &type, &path, &limits); if (r < 0) return r; if (r != 3) @@ -899,7 +899,7 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) { _cleanup_free_ char *path = NULL, *weight = NULL; CGroupBlockIODeviceWeight *a = NULL; - r = extract_many_words(&val, " ", 0, &path, &weight, NULL); + r = extract_many_words(&val, " ", 0, &path, &weight); if (r < 0) return r; if (r != 2) @@ -920,7 +920,7 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) { _cleanup_free_ char *path = NULL, *bw = NULL; CGroupBlockIODeviceBandwidth *a = NULL; - r = extract_many_words(&val, " ", 0, &path, &bw, NULL); + r = extract_many_words(&val, " ", 0, &path, &bw); if (r < 0) return r; if (r != 2) @@ -950,7 +950,7 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) { _cleanup_free_ char *path = NULL, *bw = NULL; CGroupBlockIODeviceBandwidth *a = NULL; - r = extract_many_words(&val, " ", 0, &path, &bw, NULL); + r = extract_many_words(&val, " ", 0, &path, &bw); if (r < 0) return r; if (r != 2) @@ -1018,7 +1018,7 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) { _cleanup_free_ char *type = NULL, *path = NULL; uint32_t t; - r = extract_many_words(&val, " ", 0, &type, &path, NULL); + r = extract_many_words(&val, " ", 0, &type, &path); if (r < 0) return r; if (r != 2) @@ -1521,7 +1521,7 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) { _cleanup_free_ char *type = NULL, *prefix = NULL; ExecDirectoryType dt; - r = extract_many_words(&val, "= ", 0, &type, &prefix, NULL); + r = extract_many_words(&val, "= ", 0, &type, &prefix); if (r < 0) return r; if (r == 0) @@ -2633,7 +2633,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { break; p = word; - r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options, NULL); + r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options); if (r < 0) return r; if (r == 0) @@ -2820,7 +2820,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { _cleanup_free_ char *type = NULL, *mode = NULL; ExecDirectoryType dt; - r = extract_many_words(&val, "= ", 0, &type, &mode, NULL); + r = extract_many_words(&val, "= ", 0, &type, &mode); if (r < 0) return r; if (r == 0 || !mode) @@ -2846,7 +2846,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { break; p = tuple; - r = extract_many_words(&p, ":", EXTRACT_UNESCAPE_SEPARATORS, &path, &only_create, NULL); + r = extract_many_words(&p, ":", EXTRACT_UNESCAPE_SEPARATORS, &path, &only_create); if (r < 0) return r; if (r < 2) @@ -3307,7 +3307,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { } else if ((val = startswith(l, "exec-context-temporary-filesystems="))) { _cleanup_free_ char *path = NULL, *options = NULL; - r = extract_many_words(&val, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &path, &options, NULL); + r = extract_many_words(&val, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &path, &options); if (r < 0) return r; if (r < 1) @@ -3385,7 +3385,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL; int id, errno_num; - r = extract_many_words(&val, NULL, 0, &s_id, &s_errno_num, NULL); + r = extract_many_words(&val, NULL, 0, &s_id, &s_errno_num); if (r < 0) return r; if (r != 2) @@ -3425,7 +3425,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL; int id, errno_num; - r = extract_many_words(&val, " ", 0, &s_id, &s_errno_num, NULL); + r = extract_many_words(&val, " ", 0, &s_id, &s_errno_num); if (r < 0) return r; if (r != 2) @@ -3662,7 +3662,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { _cleanup_(exec_set_credential_freep) ExecSetCredential *sc = NULL; _cleanup_free_ char *id = NULL, *encrypted = NULL, *data = NULL; - r = extract_many_words(&val, " ", 0, &id, &encrypted, &data, NULL); + r = extract_many_words(&val, " ", 0, &id, &encrypted, &data); if (r < 0) return r; if (r != 3) @@ -3694,7 +3694,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { _cleanup_(exec_load_credential_freep) ExecLoadCredential *lc = NULL; _cleanup_free_ char *id = NULL, *encrypted = NULL, *path = NULL; - r = extract_many_words(&val, " ", 0, &id, &encrypted, &path, NULL); + r = extract_many_words(&val, " ", 0, &id, &encrypted, &path); if (r < 0) return r; if (r != 3) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index c8e903d030..d751b3316c 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -4692,7 +4692,7 @@ int config_parse_exec_directories( _cleanup_free_ char *src = NULL, *dest = NULL; const char *q = tuple; - r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &src, &dest, NULL); + r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &src, &dest); if (r == -ENOMEM) return log_oom(); if (r <= 0) { @@ -5395,7 +5395,7 @@ int config_parse_mount_images( return 0; q = tuple; - r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &first, &second, NULL); + r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &first, &second); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -5444,7 +5444,7 @@ int config_parse_mount_images( MountOptions *o = NULL; PartitionDesignator partition_designator; - r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options, NULL); + r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -5586,7 +5586,7 @@ int config_parse_extension_images( MountOptions *o = NULL; PartitionDesignator partition_designator; - r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options, NULL); + r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options); if (r == -ENOMEM) return log_oom(); if (r < 0) { diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 7a235c5bf4..4d65289bef 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -159,7 +159,7 @@ static int mount_array_add(bool for_initrd, const char *str) { assert(str); r = extract_many_words(&str, ":", EXTRACT_CUNESCAPE | EXTRACT_DONT_COALESCE_SEPARATORS, - &what, &where, &fstype, &options, NULL); + &what, &where, &fstype, &options); if (r < 0) return r; if (r < 2) @@ -177,7 +177,7 @@ static int mount_array_add_swap(bool for_initrd, const char *str) { assert(str); r = extract_many_words(&str, ":", EXTRACT_CUNESCAPE | EXTRACT_DONT_COALESCE_SEPARATORS, - &what, &options, NULL); + &what, &options); if (r < 0) return r; if (r < 1) diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 9dc51a59b5..8904885c13 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -335,7 +335,7 @@ static int get_firmware_date(usec_t *ret) { } const char *p = bios_date; - r = extract_many_words(&p, "/", EXTRACT_DONT_COALESCE_SEPARATORS, &month, &day, &year, NULL); + r = extract_many_words(&p, "/", EXTRACT_DONT_COALESCE_SEPARATORS, &month, &day, &year); if (r < 0) return r; if (r != 3) /* less than three args read? */ diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index 2edd849cce..2b442aa4c1 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -447,7 +447,7 @@ int config_parse_ndisc_route_metric( _cleanup_free_ char *high = NULL, *medium = NULL, *low = NULL; const char *p = rvalue; - r = extract_many_words(&p, ":", EXTRACT_DONT_COALESCE_SEPARATORS, &high, &medium, &low, NULL); + r = extract_many_words(&p, ":", EXTRACT_DONT_COALESCE_SEPARATORS, &high, &medium, &low); if (r == -ENOMEM) return log_oom(); if (r != 3 || !isempty(p)) { diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index 71efeb8572..e94ffd799e 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -245,7 +245,7 @@ int bind_mount_parse(CustomMount **l, size_t *n, const char *s, bool read_only) assert(l); assert(n); - r = extract_many_words(&s, ":", EXTRACT_DONT_COALESCE_SEPARATORS, &source, &destination, NULL); + r = extract_many_words(&s, ":", EXTRACT_DONT_COALESCE_SEPARATORS, &source, &destination); if (r < 0) return r; if (r == 0) diff --git a/src/partition/repart.c b/src/partition/repart.c index 54ded64aee..404e1b40b4 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -1758,7 +1758,7 @@ static int config_parse_mountpoint( const char *q = rvalue; r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNQUOTE, - &where, &options, NULL); + &where, &options); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -1815,7 +1815,7 @@ static int config_parse_encrypted_volume( const char *q = rvalue; r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNQUOTE, - &volume, &keyfile, &options, NULL); + &volume, &keyfile, &options); if (r == -ENOMEM) return log_oom(); if (r < 0) { diff --git a/src/resolve/resolved-dns-trust-anchor.c b/src/resolve/resolved-dns-trust-anchor.c index 1e42cdddb1..cab2292389 100644 --- a/src/resolve/resolved-dns-trust-anchor.c +++ b/src/resolve/resolved-dns-trust-anchor.c @@ -228,7 +228,7 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u return -EINVAL; } - r = extract_many_words(&p, NULL, 0, &class, &type, NULL); + r = extract_many_words(&p, NULL, 0, &class, &type); if (r < 0) return log_warning_errno(r, "Unable to parse class and type in line %s:%u: %m", path, line); if (r != 2) { @@ -248,7 +248,7 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u int a, dt; size_t l; - r = extract_many_words(&p, NULL, 0, &key_tag, &algorithm, &digest_type, NULL); + r = extract_many_words(&p, NULL, 0, &key_tag, &algorithm, &digest_type); if (r < 0) { log_warning_errno(r, "Failed to parse DS parameters on line %s:%u: %m", path, line); return -EINVAL; @@ -302,7 +302,7 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u size_t l; int a; - r = extract_many_words(&p, NULL, 0, &flags, &protocol, &algorithm, NULL); + r = extract_many_words(&p, NULL, 0, &flags, &protocol, &algorithm); if (r < 0) return log_warning_errno(r, "Failed to parse DNSKEY parameters on line %s:%u: %m", path, line); if (r != 3) { diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 53da9bc3c2..783ce31b3d 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -497,7 +497,7 @@ static int bus_append_nft_set(sd_bus_message *m, const char *field, const char * return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse %s", field); q = tuple; - r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE, &source_str, &nfproto_str, &table, &set, NULL); + r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE, &source_str, &nfproto_str, &table, &set); if (r == -ENOMEM) return log_oom(); if (r != 4 || !isempty(q)) @@ -1894,7 +1894,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con break; q = tuple; - r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &first, &second, NULL); + r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &first, &second); if (r < 0) return log_error_errno(r, "Failed to parse MountImages= property: %s", eq); if (r == 0) @@ -1926,7 +1926,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con for (;;) { _cleanup_free_ char *partition = NULL, *mount_options = NULL; - r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options, NULL); + r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options); if (r < 0) return log_error_errno(r, "Failed to parse MountImages= property: %s", eq); if (r == 0) @@ -2027,7 +2027,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con for (;;) { _cleanup_free_ char *partition = NULL, *mount_options = NULL; - r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options, NULL); + r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options); if (r < 0) return log_error_errno(r, "Failed to parse ExtensionImages= property: %s", eq); if (r == 0) @@ -2088,7 +2088,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con break; const char *t = tuple; - r = extract_many_words(&t, ":", EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS, &source, &destination, NULL); + r = extract_many_words(&t, ":", EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS, &source, &destination); if (r <= 0) return log_error_errno(r ?: SYNTHETIC_ERRNO(EINVAL), "Failed to parse argument: %m"); diff --git a/src/shared/cgroup-setup.c b/src/shared/cgroup-setup.c index d753fd9336..d9cca6ced4 100644 --- a/src/shared/cgroup-setup.c +++ b/src/shared/cgroup-setup.c @@ -51,7 +51,7 @@ static int cg_any_controller_used_for_v1(void) { continue; const char *p = *line; - r = extract_many_words(&p, NULL, 0, &name, &hierarchy_id, &num, &enabled, NULL); + r = extract_many_words(&p, NULL, 0, &name, &hierarchy_id, &num, &enabled); if (r < 0) return log_debug_errno(r, "Error parsing /proc/cgroups line, ignoring: %m"); else if (r < 4) { diff --git a/src/shared/condition.c b/src/shared/condition.c index b7d2248b94..d8d366a44c 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -1024,7 +1024,7 @@ static int condition_test_psi(Condition *c, char **env) { "io"; p = c->parameter; - r = extract_many_words(&p, ":", 0, &first, &second, NULL); + r = extract_many_words(&p, ":", 0, &first, &second); if (r <= 0) return log_debug_errno(r < 0 ? r : SYNTHETIC_ERRNO(EINVAL), "Failed to parse condition parameter %s: %m", c->parameter); /* If only one parameter is passed, then we look at the global system pressure rather than a specific cgroup. */ @@ -1099,7 +1099,7 @@ static int condition_test_psi(Condition *c, char **env) { /* If a value including a specific timespan (in the intervals allowed by the kernel), * parse it, otherwise we assume just a plain percentage that will be checked if it is * smaller or equal to the current pressure average over 5 minutes. */ - r = extract_many_words(&value, "/", 0, &third, &fourth, NULL); + r = extract_many_words(&value, "/", 0, &third, &fourth); if (r <= 0) return log_debug_errno(r < 0 ? r : SYNTHETIC_ERRNO(EINVAL), "Failed to parse condition parameter %s: %m", c->parameter); if (r == 1) diff --git a/src/shared/open-file.c b/src/shared/open-file.c index 42772bdabe..beebb74cff 100644 --- a/src/shared/open-file.c +++ b/src/shared/open-file.c @@ -23,7 +23,7 @@ int open_file_parse(const char *v, OpenFile **ret) { if (!of) return -ENOMEM; - r = extract_many_words(&v, ":", EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_CUNESCAPE, &of->path, &of->fdname, &options, NULL); + r = extract_many_words(&v, ":", EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_CUNESCAPE, &of->path, &of->fdname, &options); if (r < 0) return r; if (r == 0) diff --git a/src/sleep/battery-capacity.c b/src/sleep/battery-capacity.c index 7627a97b28..a2bcb958a6 100644 --- a/src/sleep/battery-capacity.c +++ b/src/sleep/battery-capacity.c @@ -123,7 +123,7 @@ static int get_battery_discharge_rate(sd_device *dev, int *ret) { break; p = line; - r = extract_many_words(&p, NULL, 0, &stored_hash_id, &stored_discharge_rate, NULL); + r = extract_many_words(&p, NULL, 0, &stored_hash_id, &stored_discharge_rate); if (r < 0) return log_debug_errno(r, "Failed to parse hash_id and discharge_rate read from " DISCHARGE_RATE_FILEPATH ": %m"); if (r != 2) diff --git a/src/systemctl/systemctl-mount.c b/src/systemctl/systemctl-mount.c index d9ad332b2f..61af218a4b 100644 --- a/src/systemctl/systemctl-mount.c +++ b/src/systemctl/systemctl-mount.c @@ -86,7 +86,7 @@ int verb_mount_image(int argc, char *argv[], void *userdata) { _cleanup_free_ char *partition = NULL, *mount_options = NULL; const char *options = argv[4]; - r = extract_many_words(&options, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options, NULL); + r = extract_many_words(&options, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options); if (r < 0) return r; /* Single set of options, applying to the root partition/single filesystem */ diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 89e957822a..b071623780 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1701,7 +1701,7 @@ static int parse_line( /* Parse columns */ p = buffer; r = extract_many_words(&p, NULL, EXTRACT_UNQUOTE, - &action, &name, &id, &description, &home, &shell, NULL); + &action, &name, &id, &description, &home, &shell); if (r < 0) return log_syntax(NULL, LOG_ERR, fname, line, r, "Syntax error."); if (r < 2) diff --git a/src/test/test-extract-word.c b/src/test/test-extract-word.c index 6e12fbe2c6..32c01b99fd 100644 --- a/src/test/test-extract-word.c +++ b/src/test/test-extract-word.c @@ -684,7 +684,7 @@ TEST(extract_many_words) { char *a, *b, *c, *d, *e, *f; p = original = "foobar waldi piep"; - assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 3); + assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c) == 3); assert_se(isempty(p)); assert_se(streq_ptr(a, "foobar")); assert_se(streq_ptr(b, "waldi")); @@ -694,12 +694,12 @@ TEST(extract_many_words) { free(c); p = original = "foobar:waldi:piep ba1:ba2"; - assert_se(extract_many_words(&p, ":" WHITESPACE, 0, &a, &b, &c, NULL) == 3); + assert_se(extract_many_words(&p, ":" WHITESPACE, 0, &a, &b, &c) == 3); assert_se(!isempty(p)); assert_se(streq_ptr(a, "foobar")); assert_se(streq_ptr(b, "waldi")); assert_se(streq_ptr(c, "piep")); - assert_se(extract_many_words(&p, ":" WHITESPACE, 0, &d, &e, &f, NULL) == 2); + assert_se(extract_many_words(&p, ":" WHITESPACE, 0, &d, &e, &f) == 2); assert_se(isempty(p)); assert_se(streq_ptr(d, "ba1")); assert_se(streq_ptr(e, "ba2")); @@ -712,7 +712,7 @@ TEST(extract_many_words) { free(f); p = original = "'foobar' wa\"ld\"i "; - assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 2); + assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c) == 2); assert_se(isempty(p)); assert_se(streq_ptr(a, "'foobar'")); assert_se(streq_ptr(b, "wa\"ld\"i")); @@ -721,7 +721,7 @@ TEST(extract_many_words) { free(b); p = original = "'foobar' wa\"ld\"i "; - assert_se(extract_many_words(&p, NULL, EXTRACT_UNQUOTE, &a, &b, &c, NULL) == 2); + assert_se(extract_many_words(&p, NULL, EXTRACT_UNQUOTE, &a, &b, &c) == 2); assert_se(isempty(p)); assert_se(streq_ptr(a, "foobar")); assert_se(streq_ptr(b, "waldi")); @@ -730,31 +730,31 @@ TEST(extract_many_words) { free(b); p = original = ""; - assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0); + assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c) == 0); assert_se(isempty(p)); assert_se(streq_ptr(a, NULL)); assert_se(streq_ptr(b, NULL)); assert_se(streq_ptr(c, NULL)); p = original = " "; - assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0); + assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c) == 0); assert_se(isempty(p)); assert_se(streq_ptr(a, NULL)); assert_se(streq_ptr(b, NULL)); assert_se(streq_ptr(c, NULL)); p = original = "foobar"; - assert_se(extract_many_words(&p, NULL, 0, NULL) == 0); + assert_se(extract_many_words(&p, NULL, 0) == 0); assert_se(p == original); p = original = "foobar waldi"; - assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1); + assert_se(extract_many_words(&p, NULL, 0, &a) == 1); assert_se(p == original+7); assert_se(streq_ptr(a, "foobar")); free(a); p = original = " foobar "; - assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1); + assert_se(extract_many_words(&p, NULL, 0, &a) == 1); assert_se(isempty(p)); assert_se(streq_ptr(a, "foobar")); free(a); diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c index d7d4380851..0f7119cd70 100644 --- a/src/udev/scsi_id/scsi_id.c +++ b/src/udev/scsi_id/scsi_id.c @@ -151,7 +151,7 @@ static int get_file_options(const char *vendor, const char *model, if (*buf == '#') continue; - r = extract_many_words(&buf, "=\",\n", 0, &key, &value, NULL); + r = extract_many_words(&buf, "=\",\n", 0, &key, &value); if (r < 2) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Error parsing config file line %d '%s'", lineno, buffer); @@ -159,7 +159,7 @@ static int get_file_options(const char *vendor, const char *model, vendor_in = TAKE_PTR(value); key = mfree(key); - r = extract_many_words(&buf, "=\",\n", 0, &key, &value, NULL); + r = extract_many_words(&buf, "=\",\n", 0, &key, &value); if (r < 2) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Error parsing config file line %d '%s'", lineno, buffer); @@ -167,7 +167,7 @@ static int get_file_options(const char *vendor, const char *model, model_in = TAKE_PTR(value); key = mfree(key); - r = extract_many_words(&buf, "=\",\n", 0, &key, &value, NULL); + r = extract_many_words(&buf, "=\",\n", 0, &key, &value); if (r < 2) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Error parsing config file line %d '%s'", lineno, buffer); } diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index 4cd9ad4082..7c3c0cd202 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -759,7 +759,7 @@ static int parse_key_value_argument(const char *s, char **key, char **value) { assert(key); assert(value); - r = extract_many_words(&s, "=", EXTRACT_DONT_COALESCE_SEPARATORS, &k, &v, NULL); + r = extract_many_words(&s, "=", EXTRACT_DONT_COALESCE_SEPARATORS, &k, &v); if (r < 0) return log_error_errno(r, "Failed to parse key/value pair %s: %m", s); if (r < 2) From 9b85bf02a09dafa8fdaf2bfc8c0bb47c141a13da Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sun, 3 Mar 2024 18:28:21 +0800 Subject: [PATCH 3/4] core/service: use extract_many_words at one more place --- src/core/service.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/core/service.c b/src/core/service.c index e575e24664..f11ef0859a 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -3018,7 +3018,7 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) { if (!c) return log_oom(); - (void) serialize_item_format(f, "fd-store-fd", "%i \"%s\" %i", copy, c, fs->do_poll); + (void) serialize_item_format(f, "fd-store-fd", "%i \"%s\" %s", copy, c, one_zero(fs->do_poll)); } if (s->main_exec_status.pid > 0) { @@ -3261,9 +3261,9 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, _cleanup_close_ int fd = -EBADF; int do_poll; - r = extract_first_word(&value, &fdv, NULL, 0); - if (r <= 0) { - log_unit_debug(u, "Failed to parse fd-store-fd value, ignoring: %s", value); + r = extract_many_words(&value, " ", EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE, &fdv, &fdn, &fdp); + if (r < 2 || r > 3) { + log_unit_debug(u, "Failed to deserialize fd-store-fd, ignoring: %s", value); return 0; } @@ -3271,24 +3271,17 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, if (fd < 0) return 0; - r = extract_first_word(&value, &fdn, NULL, EXTRACT_CUNESCAPE | EXTRACT_UNQUOTE); - if (r <= 0) { - log_unit_debug(u, "Failed to parse fd-store-fd value, ignoring: %s", value); - return 0; - } - - r = extract_first_word(&value, &fdp, NULL, 0); - if (r == 0) { - /* If the value is not present, we assume the default */ - do_poll = 1; - } else if (r < 0 || (r = safe_atoi(fdp, &do_poll)) < 0) { - log_unit_debug_errno(u, r, "Failed to parse fd-store-fd value \"%s\", ignoring: %m", value); + do_poll = r == 3 ? parse_boolean(fdp) : true; + if (do_poll < 0) { + log_unit_debug_errno(u, do_poll, + "Failed to deserialize fd-store-fd do_poll, ignoring: %s", fdp); return 0; } r = service_add_fd_store(s, fd, fdn, do_poll); if (r < 0) { - log_unit_debug_errno(u, r, "Failed to store deserialized fd %i, ignoring: %m", fd); + log_unit_debug_errno(u, r, + "Failed to store deserialized fd '%s', ignoring: %m", fdn); return 0; } From 6e890fe86f5505dcd29839457469e30e3a9f1d42 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sun, 3 Mar 2024 18:37:36 +0800 Subject: [PATCH 4/4] man/sd_notify: be explicit that FDPOLL= is not a global setting "submitted" is already used in the description of FDNAME=. Let's use that instead of "stored" for FDPOLL= too, to make it more clear that it's a per-submission/per-fdset setting. --- man/sd_notify.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/sd_notify.xml b/man/sd_notify.xml index 287945a46a..a56d039468 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -420,8 +420,8 @@ FDPOLL=0 When used in combination with FDSTORE=1, disables polling of the - stored file descriptors regardless of whether or not they are pollable. As this option disables - automatic cleanup of the stored file descriptors on EPOLLERR and EPOLLHUP, care must be taken to + submitted file descriptors regardless of whether or not they are pollable. As this option disables + automatic cleanup of the submitted file descriptors on EPOLLERR and EPOLLHUP, care must be taken to ensure proper manual cleanup. Use of this option is not generally recommended except for when automatic cleanup has unwanted behavior such as prematurely discarding file descriptors from the store.