summaryrefslogtreecommitdiffstats
path: root/src/basic
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-03-21 06:47:05 +0100
committerGitHub <noreply@github.com>2024-03-21 06:47:05 +0100
commit839dce5ecb8305f68cd9436b8936ee72204cc83f (patch)
tree54d2515b1faf1e5a155940abfa4eb545fb681f58 /src/basic
parentMerge pull request #31875 from ml-/docs-fix-socket-section (diff)
parentshared/password-quality: inline iterator variable (diff)
downloadsystemd-839dce5ecb8305f68cd9436b8936ee72204cc83f.tar.xz
systemd-839dce5ecb8305f68cd9436b8936ee72204cc83f.zip
Merge pull request #31862 from keszybz/add-strdup_to-helper
Add strdup_to() helper
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/cgroup-util.c94
-rw-r--r--src/basic/chase.c7
-rw-r--r--src/basic/devnum-util.c11
-rw-r--r--src/basic/efivars.c12
-rw-r--r--src/basic/fileio.c18
-rw-r--r--src/basic/format-util.c9
-rw-r--r--src/basic/path-lookup.c17
-rw-r--r--src/basic/path-util.c9
-rw-r--r--src/basic/proc-cmdline.c12
-rw-r--r--src/basic/process-util.c29
-rw-r--r--src/basic/socket-util.c12
-rw-r--r--src/basic/string-util.c51
-rw-r--r--src/basic/string-util.h27
-rw-r--r--src/basic/terminal-util.c33
-rw-r--r--src/basic/time-util.c24
-rw-r--r--src/basic/unit-name.c27
16 files changed, 103 insertions, 289 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 68b1584629..60b4e3f226 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -135,7 +135,7 @@ int cg_read_event(
return r;
for (const char *p = content;;) {
- _cleanup_free_ char *line = NULL, *key = NULL, *val = NULL;
+ _cleanup_free_ char *line = NULL, *key = NULL;
const char *q;
r = extract_first_word(&p, &line, "\n", 0);
@@ -154,12 +154,7 @@ int cg_read_event(
if (!streq(key, event))
continue;
- val = strdup(q);
- if (!val)
- return -ENOMEM;
-
- *ret = TAKE_PTR(val);
- return 0;
+ return strdup_to(ret, q);
}
}
@@ -234,20 +229,13 @@ int cg_read_subgroup(DIR *d, char **ret) {
assert(ret);
FOREACH_DIRENT_ALL(de, d, return -errno) {
- char *b;
-
if (de->d_type != DT_DIR)
continue;
if (dot_or_dot_dot(de->d_name))
continue;
- b = strdup(de->d_name);
- if (!b)
- return -ENOMEM;
-
- *ret = b;
- return 1;
+ return strdup_to_full(ret, de->d_name);
}
*ret = NULL;
@@ -1125,44 +1113,29 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **ret_cgroup) {
if (r < 0)
return r;
- if (c == raw)
+ if (c == raw) {
*ret_cgroup = TAKE_PTR(raw);
- else {
- char *n;
-
- n = strdup(c);
- if (!n)
- return -ENOMEM;
-
- *ret_cgroup = n;
+ return 0;
}
- return 0;
+ return strdup_to(ret_cgroup, c);
}
int cg_path_decode_unit(const char *cgroup, char **ret_unit) {
- char *c, *s;
- size_t n;
-
assert(cgroup);
assert(ret_unit);
- n = strcspn(cgroup, "/");
+ size_t n = strcspn(cgroup, "/");
if (n < 3)
return -ENXIO;
- c = strndupa_safe(cgroup, n);
+ char *c = strndupa_safe(cgroup, n);
c = cg_unescape(c);
if (!unit_name_is_valid(c, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
return -ENXIO;
- s = strdup(c);
- if (!s)
- return -ENOMEM;
-
- *ret_unit = s;
- return 0;
+ return strdup_to(ret_unit, c);
}
static bool valid_slice_name(const char *p, size_t n) {
@@ -1467,17 +1440,10 @@ int cg_path_get_session(const char *path, char **ret_session) {
if (!session_id_valid(start))
return -ENXIO;
- if (ret_session) {
- char *rr;
-
- rr = strdup(start);
- if (!rr)
- return -ENOMEM;
-
- *ret_session = rr;
- }
+ if (!ret_session)
+ return 0;
- return 0;
+ return strdup_to(ret_session, start);
}
int cg_pid_get_session(pid_t pid, char **ret_session) {
@@ -1538,30 +1504,19 @@ int cg_path_get_slice(const char *p, char **ret_slice) {
* stops before we come to the first non-slice unit. */
for (;;) {
- size_t n;
-
p += strspn(p, "/");
- n = strcspn(p, "/");
- if (!valid_slice_name(p, n)) {
-
- if (!e) {
- char *s;
-
- s = strdup(SPECIAL_ROOT_SLICE);
- if (!s)
- return -ENOMEM;
-
- *ret_slice = s;
- return 0;
- }
-
- return cg_path_decode_unit(e, ret_slice);
- }
+ size_t n = strcspn(p, "/");
+ if (!valid_slice_name(p, n))
+ break;
e = p;
p += n;
}
+
+ if (e)
+ return cg_path_decode_unit(e, ret_slice);
+ return strdup_to(ret_slice, SPECIAL_ROOT_SLICE);
}
int cg_pid_get_slice(pid_t pid, char **ret_slice) {
@@ -1714,15 +1669,8 @@ int cg_slice_to_path(const char *unit, char **ret) {
assert(unit);
assert(ret);
- if (streq(unit, SPECIAL_ROOT_SLICE)) {
- char *x;
-
- x = strdup("");
- if (!x)
- return -ENOMEM;
- *ret = x;
- return 0;
- }
+ if (streq(unit, SPECIAL_ROOT_SLICE))
+ return strdup_to(ret, "");
if (!unit_name_is_valid(unit, UNIT_NAME_PLAIN))
return -EINVAL;
diff --git a/src/basic/chase.c b/src/basic/chase.c
index 9f5477e4f3..245dd0800e 100644
--- a/src/basic/chase.c
+++ b/src/basic/chase.c
@@ -741,12 +741,7 @@ int chase_extract_filename(const char *path, const char *root, char **ret) {
return r;
}
- char *fname = strdup(".");
- if (!fname)
- return -ENOMEM;
-
- *ret = fname;
- return 0;
+ return strdup_to(ret, ".");
}
int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, int open_flags, char **ret_path) {
diff --git a/src/basic/devnum-util.c b/src/basic/devnum-util.c
index f82e13bdb0..652740cea7 100644
--- a/src/basic/devnum-util.c
+++ b/src/basic/devnum-util.c
@@ -58,21 +58,18 @@ int device_path_make_major_minor(mode_t mode, dev_t devnum, char **ret) {
}
int device_path_make_inaccessible(mode_t mode, char **ret) {
- char *s;
+ const char *s;
assert(ret);
if (S_ISCHR(mode))
- s = strdup("/run/systemd/inaccessible/chr");
+ s = "/run/systemd/inaccessible/chr";
else if (S_ISBLK(mode))
- s = strdup("/run/systemd/inaccessible/blk");
+ s = "/run/systemd/inaccessible/blk";
else
return -ENODEV;
- if (!s)
- return -ENOMEM;
- *ret = s;
- return 0;
+ return strdup_to(ret, s);
}
int device_path_make_canonical(mode_t mode, dev_t devnum, char **ret) {
diff --git a/src/basic/efivars.c b/src/basic/efivars.c
index 9011ae29a3..fdc6c439bb 100644
--- a/src/basic/efivars.c
+++ b/src/basic/efivars.c
@@ -398,16 +398,8 @@ int systemd_efi_options_variable(char **ret) {
/* For testing purposes it is sometimes useful to be able to override this */
e = secure_getenv("SYSTEMD_EFI_OPTIONS");
- if (e) {
- char *m;
-
- m = strdup(e);
- if (!m)
- return -ENOMEM;
-
- *ret = m;
- return 0;
- }
+ if (e)
+ return strdup_to(ret, e);
r = read_one_line_file(EFIVAR_CACHE_PATH(EFI_SYSTEMD_VARIABLE(SystemdOptions)), ret);
if (r == -ENOENT)
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 3aadb4bfab..523378177f 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -1504,7 +1504,7 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) {
int read_stripped_line(FILE *f, size_t limit, char **ret) {
_cleanup_free_ char *s = NULL;
- int r;
+ int r, k;
assert(f);
@@ -1513,23 +1513,17 @@ int read_stripped_line(FILE *f, size_t limit, char **ret) {
return r;
if (ret) {
- const char *p;
-
- p = strstrip(s);
+ const char *p = strstrip(s);
if (p == s)
*ret = TAKE_PTR(s);
else {
- char *copy;
-
- copy = strdup(p);
- if (!copy)
- return -ENOMEM;
-
- *ret = copy;
+ k = strdup_to(ret, p);
+ if (k < 0)
+ return k;
}
}
- return r;
+ return r > 0; /* Return 1 if something was read. */
}
int safe_fgetc(FILE *f, char *ret) {
diff --git a/src/basic/format-util.c b/src/basic/format-util.c
index 94501853a1..056c990cc7 100644
--- a/src/basic/format-util.c
+++ b/src/basic/format-util.c
@@ -25,7 +25,7 @@ int format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NA
}
int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret) {
- char buf[IF_NAMESIZE], *copy;
+ char buf[IF_NAMESIZE];
int r;
assert(ret);
@@ -34,12 +34,7 @@ int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret) {
if (r < 0)
return r;
- copy = strdup(buf);
- if (!copy)
- return -ENOMEM;
-
- *ret = copy;
- return 0;
+ return strdup_to(ret, buf);
}
char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) {
diff --git a/src/basic/path-lookup.c b/src/basic/path-lookup.c
index e7fc4a7f06..540256b73b 100644
--- a/src/basic/path-lookup.c
+++ b/src/basic/path-lookup.c
@@ -92,7 +92,6 @@ int xdg_user_data_dir(char **ret, const char *suffix) {
}
int runtime_directory(char **ret, RuntimeScope scope, const char *suffix) {
- _cleanup_free_ char *d = NULL;
int r;
assert(ret);
@@ -106,26 +105,20 @@ int runtime_directory(char **ret, RuntimeScope scope, const char *suffix) {
* Return value indicates whether the suffix was applied or not */
const char *e = secure_getenv("RUNTIME_DIRECTORY");
- if (e) {
- d = strdup(e);
- if (!d)
- return -ENOMEM;
-
- *ret = TAKE_PTR(d);
- return false;
- }
+ if (e)
+ return strdup_to(ret, e);
if (scope == RUNTIME_SCOPE_USER) {
- r = xdg_user_runtime_dir(&d, suffix);
+ r = xdg_user_runtime_dir(ret, suffix);
if (r < 0)
return r;
} else {
- d = path_join("/run", suffix);
+ char *d = path_join("/run", suffix);
if (!d)
return -ENOMEM;
+ *ret = d;
}
- *ret = TAKE_PTR(d);
return true;
}
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index 05a21f8f8e..4d335c64ee 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -1094,7 +1094,6 @@ int path_extract_filename(const char *path, char **ret) {
}
int path_extract_directory(const char *path, char **ret) {
- _cleanup_free_ char *a = NULL;
const char *c, *next = NULL;
int r;
@@ -1118,14 +1117,10 @@ int path_extract_directory(const char *path, char **ret) {
if (*path != '/') /* filename only */
return -EDESTADDRREQ;
- a = strdup("/");
- if (!a)
- return -ENOMEM;
- *ret = TAKE_PTR(a);
- return 0;
+ return strdup_to(ret, "/");
}
- a = strndup(path, next - path);
+ _cleanup_free_ char *a = strndup(path, next - path);
if (!a)
return -ENOMEM;
diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c
index 522d8de1f4..ce1ba3a1ea 100644
--- a/src/basic/proc-cmdline.c
+++ b/src/basic/proc-cmdline.c
@@ -116,16 +116,8 @@ int proc_cmdline(char **ret) {
/* For testing purposes it is sometimes useful to be able to override what we consider /proc/cmdline to be */
e = secure_getenv("SYSTEMD_PROC_CMDLINE");
- if (e) {
- char *m;
-
- m = strdup(e);
- if (!m)
- return -ENOMEM;
-
- *ret = m;
- return 0;
- }
+ if (e)
+ return strdup_to(ret, e);
if (detect_container() > 0)
return pid_get_cmdline(1, SIZE_MAX, 0, ret);
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 69635e65f8..351b5e4095 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -1022,7 +1022,6 @@ int kill_and_sigcont(pid_t pid, int sig) {
int getenv_for_pid(pid_t pid, const char *field, char **ret) {
_cleanup_fclose_ FILE *f = NULL;
- char *value = NULL;
const char *path;
size_t sum = 0;
int r;
@@ -1031,22 +1030,8 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) {
assert(field);
assert(ret);
- if (pid == 0 || pid == getpid_cached()) {
- const char *e;
-
- e = getenv(field);
- if (!e) {
- *ret = NULL;
- return 0;
- }
-
- value = strdup(e);
- if (!value)
- return -ENOMEM;
-
- *ret = value;
- return 1;
- }
+ if (pid == 0 || pid == getpid_cached())
+ return strdup_to_full(ret, getenv(field));
if (!pid_is_valid(pid))
return -EINVAL;
@@ -1075,14 +1060,8 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) {
sum += r;
match = startswith(line, field);
- if (match && *match == '=') {
- value = strdup(match + 1);
- if (!value)
- return -ENOMEM;
-
- *ret = value;
- return 1;
- }
+ if (match && *match == '=')
+ return strdup_to_full(ret, match + 1);
}
*ret = NULL;
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 68e6afc67f..5eb8e4c988 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -453,6 +453,7 @@ int sockaddr_pretty(
assert(sa);
assert(salen >= sizeof(sa->sa.sa_family));
+ assert(ret);
switch (sa->sa.sa_family) {
@@ -634,6 +635,7 @@ int socknameinfo_pretty(const struct sockaddr *sa, socklen_t salen, char **ret)
assert(sa);
assert(salen > sizeof(sa_family_t));
+ assert(ret);
r = getnameinfo(sa, salen, host, sizeof(host), /* service= */ NULL, /* service_len= */ 0, IDN_FLAGS);
if (r != 0) {
@@ -647,15 +649,7 @@ int socknameinfo_pretty(const struct sockaddr *sa, socklen_t salen, char **ret)
return sockaddr_pretty(sa, salen, /* translate_ipv6= */ true, /* include_port= */ true, ret);
}
- if (ret) {
- char *copy = strdup(host);
- if (!copy)
- return -ENOMEM;
-
- *ret = copy;
- }
-
- return 0;
+ return strdup_to(ret, host);
}
static const char* const netlink_family_table[] = {
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index c1e7e6e622..7f6c87b461 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -1126,6 +1126,24 @@ int free_and_strndup(char **p, const char *s, size_t l) {
return 1;
}
+int strdup_to_full(char **ret, const char *src) {
+ if (!src) {
+ if (ret)
+ *ret = NULL;
+
+ return 0;
+ } else {
+ if (ret) {
+ char *t = strdup(src);
+ if (!t)
+ return -ENOMEM;
+ *ret = t;
+ }
+
+ return 1;
+ }
+};
+
bool string_is_safe(const char *p) {
if (!p)
return false;
@@ -1235,36 +1253,15 @@ int string_extract_line(const char *s, size_t i, char **ret) {
return -ENOMEM;
*ret = m;
- return !isempty(q + 1); /* more coming? */
- } else {
- if (p == s)
- *ret = NULL; /* Just use the input string */
- else {
- char *m;
-
- m = strdup(p);
- if (!m)
- return -ENOMEM;
-
- *ret = m;
- }
-
- return 0; /* The end */
- }
+ return !isempty(q + 1); /* More coming? */
+ } else
+ /* Tell the caller to use the input string if equal */
+ return strdup_to(ret, p != s ? p : NULL);
}
- if (!q) {
- char *m;
-
+ if (!q)
/* No more lines, return empty line */
-
- m = strdup("");
- if (!m)
- return -ENOMEM;
-
- *ret = m;
- return 0; /* The end */
- }
+ return strdup_to(ret, "");
p = q + 1;
c++;
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index e162765aa7..a68f3c94ab 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -224,6 +224,12 @@ static inline int free_and_strdup_warn(char **p, const char *s) {
}
int free_and_strndup(char **p, const char *s, size_t l);
+int strdup_to_full(char **ret, const char *src);
+static inline int strdup_to(char **ret, const char *src) {
+ int r = strdup_to_full(ASSERT_PTR(ret), src);
+ return r < 0 ? r : 0; /* Suppress return value of 1. */
+}
+
bool string_is_safe(const char *p) _pure_;
DISABLE_WARNING_STRINGOP_TRUNCATION;
@@ -297,25 +303,4 @@ bool version_is_valid_versionspec(const char *s);
ssize_t strlevenshtein(const char *x, const char *y);
-static inline int strdup_or_null(const char *s, char **ret) {
- char *c;
-
- assert(ret);
-
- /* This is a lot like strdup(), but is happy with NULL strings, and does not treat that as error, but
- * copies the NULL value. */
-
- if (!s) {
- *ret = NULL;
- return 0;
- }
-
- c = strdup(s);
- if (!c)
- return -ENOMEM;
-
- *ret = c;
- return 1;
-}
-
char *strrstr(const char *haystack, const char *needle);
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 8b5a9fa8c6..518412ec36 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -697,18 +697,10 @@ int vtnr_from_tty(const char *tty) {
tty = active;
}
- if (tty == active)
- *ret = TAKE_PTR(active);
- else {
- char *tmp;
-
- tmp = strdup(tty);
- if (!tmp)
- return -ENOMEM;
-
- *ret = tmp;
- }
+ if (tty != active)
+ return strdup_to(ret, tty);
+ *ret = TAKE_PTR(active);
return 0;
}
@@ -988,7 +980,7 @@ bool on_tty(void) {
}
int getttyname_malloc(int fd, char **ret) {
- char path[PATH_MAX], *c; /* PATH_MAX is counted *with* the trailing NUL byte */
+ char path[PATH_MAX]; /* PATH_MAX is counted *with* the trailing NUL byte */
int r;
assert(fd >= 0);
@@ -1001,12 +993,7 @@ int getttyname_malloc(int fd, char **ret) {
if (r > 0)
return -r;
- c = strdup(skip_dev_prefix(path));
- if (!c)
- return -ENOMEM;
-
- *ret = c;
- return 0;
+ return strdup_to(ret, skip_dev_prefix(path));
}
int getttyname_harder(int fd, char **ret) {
@@ -1111,13 +1098,9 @@ int get_ctty(pid_t pid, dev_t *ret_devnr, char **ret) {
return -EINVAL;
if (ret) {
- _cleanup_free_ char *b = NULL;
-
- b = strdup(w);
- if (!b)
- return -ENOMEM;
-
- *ret = TAKE_PTR(b);
+ r = strdup_to(ret, w);
+ if (r < 0)
+ return r;
}
if (ret_devnr)
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index 822d660fda..b94f37c31c 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -1606,38 +1606,24 @@ bool clock_supported(clockid_t clock) {
int get_timezone(char **ret) {
_cleanup_free_ char *t = NULL;
- const char *e;
- char *z;
int r;
assert(ret);
r = readlink_malloc("/etc/localtime", &t);
- if (r == -ENOENT) {
+ if (r == -ENOENT)
/* If the symlink does not exist, assume "UTC", like glibc does */
- z = strdup("UTC");
- if (!z)
- return -ENOMEM;
-
- *ret = z;
- return 0;
- }
+ return strdup_to(ret, "UTC");
if (r < 0)
- return r; /* returns EINVAL if not a symlink */
+ return r; /* Return EINVAL if not a symlink */
- e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/");
+ const char *e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/");
if (!e)
return -EINVAL;
-
if (!timezone_is_valid(e, LOG_DEBUG))
return -EINVAL;
- z = strdup(e);
- if (!z)
- return -ENOMEM;
-
- *ret = z;
- return 0;
+ return strdup_to(ret, e);
}
time_t mktime_or_timegm(struct tm *tm, bool utc) {
diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c
index 06ed9054d0..4e2f77c03d 100644
--- a/src/basic/unit-name.c
+++ b/src/basic/unit-name.c
@@ -793,19 +793,10 @@ int unit_name_mangle_with_suffix(
return 1;
good:
- s = strdup(name);
- if (!s)
- return -ENOMEM;
-
- *ret = TAKE_PTR(s);
- return 0;
+ return strdup_to(ret, name);
}
int slice_build_parent_slice(const char *slice, char **ret) {
- _cleanup_free_ char *s = NULL;
- char *dash;
- int r;
-
assert(slice);
assert(ret);
@@ -817,18 +808,16 @@ int slice_build_parent_slice(const char *slice, char **ret) {
return 0;
}
- s = strdup(slice);
+ _cleanup_free_ char *s = strdup(slice);
if (!s)
return -ENOMEM;
- dash = strrchr(s, '-');
- if (dash)
- strcpy(dash, ".slice");
- else {
- r = free_and_strdup(&s, SPECIAL_ROOT_SLICE);
- if (r < 0)
- return r;
- }
+ char *dash = strrchr(s, '-');
+ if (!dash)
+ return strdup_to_full(ret, SPECIAL_ROOT_SLICE);
+
+ /* We know that s ended with .slice before truncation, so we have enough space. */
+ strcpy(dash, ".slice");
*ret = TAKE_PTR(s);
return 1;