Read an open stream fully into a heap, NUL-terminated string. Caller frees. * Returns NULL on allocation failure. Reads binary-clean (UTF-8 JSON, no shell * quoting needed). */
| 284 | * Returns NULL on allocation failure. Reads binary-clean (UTF-8 JSON, no shell |
| 285 | * quoting needed). */ |
| 286 | static char *cli_slurp_stream(FILE *f) { |
| 287 | size_t cap = CLI_SLURP_CHUNK; |
| 288 | size_t len = 0; |
| 289 | char *buf = malloc(cap); |
| 290 | if (!buf) { |
| 291 | return NULL; |
| 292 | } |
| 293 | char tmp[CLI_SLURP_CHUNK]; |
| 294 | size_t n; |
| 295 | while ((n = fread(tmp, 1, sizeof(tmp), f)) > 0) { |
| 296 | if (len + n + 1 > cap) { |
| 297 | while (len + n + 1 > cap) { |
| 298 | cap *= 2; |
| 299 | } |
| 300 | char *nb = realloc(buf, cap); |
| 301 | if (!nb) { |
| 302 | free(buf); |
| 303 | return NULL; |
| 304 | } |
| 305 | buf = nb; |
| 306 | } |
| 307 | memcpy(buf + len, tmp, n); |
| 308 | len += n; |
| 309 | } |
| 310 | buf[len] = '\0'; |
| 311 | return buf; |
| 312 | } |
| 313 | |
| 314 | /* Slurp a file path into a heap, NUL-terminated string. Caller frees. */ |
| 315 | static char *cli_slurp_file(const char *path) { |
no outgoing calls
no test coverage detected