diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-26 01:09:10 +0000 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-26 01:12:50 +0000 |
| commit | f45a349da414322f5753ffbcd94b30c1f44cbc2b (patch) | |
| tree | 7489143a4cd29544975ee75b3d6accc1a649ceb6 /util/libreboot-utils/lib/string.c | |
| parent | 7cd588a445d70d8cc7ed0cbae36be001ee56cae1 (diff) | |
libreboot-utils: new function, scatn()
concatenate an arbitrary number of strings,
pointed to by char **
i'll use this and the next function, dcatn,
in an upcoming feature planned for mkhtemp.
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/libreboot-utils/lib/string.c')
| -rw-r--r-- | util/libreboot-utils/lib/string.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c index 0329c6c3..b639f0a4 100644 --- a/util/libreboot-utils/lib/string.c +++ b/util/libreboot-utils/lib/string.c @@ -117,6 +117,57 @@ sdup(const char *s, return 0; } +/* concatenate N number of strings */ +/* slen already checks null/termination */ +int +scatn(ssize_t sc, const char **sv, + size_t max, char **rval) +{ + ssize_t i = 0; + + size_t ts = 0; + size_t *size = NULL; + + char *ct = NULL; + int saved_errno = errno; + + if (if_err(sc <= 0, EINVAL) || + if_err(sc > SIZE_MAX / sizeof(size_t), EOVERFLOW) || + if_err(sv == NULL, EINVAL) || + if_err((size = malloc(sizeof(size_t) * sc)) == NULL, ENOMEM)) + goto err; + + for (i = 0; i < sc; i++, ts += size[i]) + if (if_err(sv[i] == NULL, EINVAL) || + slen(sv[i], max, &size[i]) < 0 || + if_err(size[i] > max - 1, EOVERFLOW) || + if_err((size[i] + ts) < ts, EOVERFLOW)) + goto err; + + if (if_err(ts > SIZE_MAX - 1, EOVERFLOW) || + if_err(ts > max - 1, EOVERFLOW) || + if_err((ct = malloc(ts + 1)) == NULL, ENOMEM)) + goto err; + + for (ts = i = 0; i < sc; i++, ts += size[i]) + memcpy(ct + ts, sv[i], size[i]); + + *(ct + ts) = '\0'; + *rval = ct; + + errno = saved_errno; + return 0; +err: + if (ct != NULL) + free(ct); + if (size != NULL) + free(size); + if (errno == saved_errno) + errno = EFAULT; + + return -1; +} + /* strict strcat */ int scat(const char *s1, const char *s2, |
