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). */
| 613 | * Returns NULL on allocation failure. Reads binary-clean (UTF-8 JSON, no shell |
| 614 | * quoting needed). */ |
| 615 | static char *cli_slurp_stream(FILE *f) { |
| 616 | size_t cap = CLI_SLURP_CHUNK; |
| 617 | size_t len = 0; |
| 618 | char *buf = malloc(cap); |
| 619 | if (!buf) { |
| 620 | return NULL; |
| 621 | } |
| 622 | char tmp[CLI_SLURP_CHUNK]; |
| 623 | size_t n; |
| 624 | while ((n = fread(tmp, 1, sizeof(tmp), f)) > 0) { |
| 625 | if (len + n + 1 > cap) { |
| 626 | while (len + n + 1 > cap) { |
| 627 | cap *= 2; |
| 628 | } |
| 629 | char *nb = realloc(buf, cap); |
| 630 | if (!nb) { |
| 631 | free(buf); |
| 632 | return NULL; |
| 633 | } |
| 634 | buf = nb; |
| 635 | } |
| 636 | memcpy(buf + len, tmp, n); |
| 637 | len += n; |
| 638 | } |
| 639 | buf[len] = '\0'; |
| 640 | return buf; |
| 641 | } |
| 642 | |
| 643 | /* Slurp a file path into a heap, NUL-terminated string. Caller frees. */ |
| 644 | static char *cli_slurp_file(const char *path) { |
no outgoing calls
no test coverage detected