From 3bdee70a9c1490ea011c6fb65193b2c7e242d26d Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Fri, 20 Feb 2026 05:17:32 +0100 Subject: plistutil: Read STDIN in chunks instead of 1 byte at a time --- tools/plistutil.c | 66 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/tools/plistutil.c b/tools/plistutil.c index 6e697cf..bdf195e 100644 --- a/tools/plistutil.c +++ b/tools/plistutil.c @@ -246,45 +246,49 @@ int main(int argc, char *argv[]) return 1; } plist_entire[read_size] = '\0'; - char ch; - while(read(STDIN_FILENO, &ch, 1) > 0) - { - if (read_size >= read_capacity) { - char *old = plist_entire; - read_capacity += 4096; - plist_entire = realloc(plist_entire, sizeof(char) * read_capacity); - if (plist_entire == NULL) - { - fprintf(stderr, "ERROR: Failed to reallocate stdin buffer\n"); - free(old); - free(options); - return 1; + char buf[4096]; + ssize_t n; + + while (1) { + n = read(STDIN_FILENO, buf, sizeof(buf)); + if (n > 0) { + size_t needed = read_size + (size_t)n + 1; + if (needed > read_capacity) { + size_t newcap = read_capacity ? read_capacity : 4096; + while (newcap < needed) { + newcap *= 2; + } + + char *tmp = realloc(plist_entire, newcap); + if (!tmp) { + fprintf(stderr, "ERROR: Failed to reallocate stdin buffer\n"); + free(plist_entire); + free(options); + return 1; + } + plist_entire = tmp; + read_capacity = newcap; } + + memcpy(plist_entire + read_size, buf, (size_t)n); + read_size += (size_t)n; + continue; } - plist_entire[read_size] = ch; - read_size++; - } - if (read_size >= read_capacity) { - char *old = plist_entire; - plist_entire = realloc(plist_entire, sizeof(char) * (read_capacity+1)); - if (plist_entire == NULL) - { - fprintf(stderr, "ERROR: Failed to reallocate stdin buffer\n"); - free(old); - free(options); - return 1; + + if (n == 0) { // EOF + break; } - } - plist_entire[read_size] = '\0'; - // Not positive we need this, but it doesnt seem to hurt lol - if(ferror(stdin)) - { - fprintf(stderr, "ERROR: reading from stdin.\n"); + // n < 0: error + if (errno == EINTR) + continue; + + fprintf(stderr, "ERROR: Failed to read from stdin\n"); free(plist_entire); free(options); return 1; } + plist_entire[read_size] = '\0'; } else { -- cgit v1.1-32-gdbae