Merge pull request #31862 from keszybz/add-strdup_to-helper

Add strdup_to() helper
This commit is contained in:
Yu Watanabe
2024-03-21 14:47:05 +09:00
committed by GitHub
53 changed files with 304 additions and 701 deletions
+21 -73
View File
@@ -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;
if (!ret_session)
return 0;
rr = strdup(start);
if (!rr)
return -ENOMEM;
*ret_session = rr;
}
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;
+1 -6
View File
@@ -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) {
+4 -7
View File
@@ -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) {
+2 -10
View File
@@ -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)
+6 -12
View File
@@ -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) {
+2 -7
View File
@@ -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) {
+5 -12
View File
@@ -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;
}
+2 -7
View File
@@ -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;
+2 -10
View File
@@ -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);
+4 -25
View File
@@ -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;
+3 -9
View File
@@ -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[] = {
+24 -27
View File
@@ -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++;
+6 -21
View File
@@ -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);
+8 -25
View File
@@ -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)
+5 -19
View File
@@ -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) {
+8 -19
View File
@@ -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;