ssize_t extract_strings(const char *in, size_t inlen, char **out, size_t outlen) { const char *inp = in; const char *inend = in + inlen; char **outp = out; char **outend = out + outlen; while (inp != inend) { size_t len; char *s; if (outp == outend) { errno = ENOSPC; goto err; } len = (unsigned char)*inp; ++inp; if (len > (size_t)(inend - inp)) { errno = EINVAL; goto err; } s = malloc(len + 1); if (s == NULL) { goto err; } memcpy(s, inp, len); inp += len; s[len] = '\0'; *outp = s; ++outp; } return outp - out; err: { int errno_old = errno; while (out != outp) { free(*out); ++out; } errno = errno_old; } return -1; }