summaryrefslogtreecommitdiff
path: root/util/libreboot-utils/lib/string.c
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-26 01:09:10 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-26 06:59:42 +0000
commit58ce1d74c0915f9a5acf6336f5707663d2bbb2da (patch)
treeef8dc1f4a9549cda04c0079c8802d0ceeeb4ef63 /util/libreboot-utils/lib/string.c
parentb84c929e64f2398e02dc4ae9575d7b616fb18528 (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.c51
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,