Skip to content

Commit 3bdee70

Browse files
committed
plistutil: Read STDIN in chunks instead of 1 byte at a time
1 parent e3d5bbd commit 3bdee70

File tree

1 file changed

+35
-31
lines changed

1 file changed

+35
-31
lines changed

tools/plistutil.c

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -246,45 +246,49 @@ int main(int argc, char *argv[])
246246
return 1;
247247
}
248248
plist_entire[read_size] = '\0';
249-
char ch;
250-
while(read(STDIN_FILENO, &ch, 1) > 0)
251-
{
252-
if (read_size >= read_capacity) {
253-
char *old = plist_entire;
254-
read_capacity += 4096;
255-
plist_entire = realloc(plist_entire, sizeof(char) * read_capacity);
256-
if (plist_entire == NULL)
257-
{
258-
fprintf(stderr, "ERROR: Failed to reallocate stdin buffer\n");
259-
free(old);
260-
free(options);
261-
return 1;
249+
char buf[4096];
250+
ssize_t n;
251+
252+
while (1) {
253+
n = read(STDIN_FILENO, buf, sizeof(buf));
254+
if (n > 0) {
255+
size_t needed = read_size + (size_t)n + 1;
256+
if (needed > read_capacity) {
257+
size_t newcap = read_capacity ? read_capacity : 4096;
258+
while (newcap < needed) {
259+
newcap *= 2;
260+
}
261+
262+
char *tmp = realloc(plist_entire, newcap);
263+
if (!tmp) {
264+
fprintf(stderr, "ERROR: Failed to reallocate stdin buffer\n");
265+
free(plist_entire);
266+
free(options);
267+
return 1;
268+
}
269+
plist_entire = tmp;
270+
read_capacity = newcap;
262271
}
272+
273+
memcpy(plist_entire + read_size, buf, (size_t)n);
274+
read_size += (size_t)n;
275+
continue;
263276
}
264-
plist_entire[read_size] = ch;
265-
read_size++;
266-
}
267-
if (read_size >= read_capacity) {
268-
char *old = plist_entire;
269-
plist_entire = realloc(plist_entire, sizeof(char) * (read_capacity+1));
270-
if (plist_entire == NULL)
271-
{
272-
fprintf(stderr, "ERROR: Failed to reallocate stdin buffer\n");
273-
free(old);
274-
free(options);
275-
return 1;
277+
278+
if (n == 0) { // EOF
279+
break;
276280
}
277-
}
278-
plist_entire[read_size] = '\0';
279281

280-
// Not positive we need this, but it doesnt seem to hurt lol
281-
if(ferror(stdin))
282-
{
283-
fprintf(stderr, "ERROR: reading from stdin.\n");
282+
// n < 0: error
283+
if (errno == EINTR)
284+
continue;
285+
286+
fprintf(stderr, "ERROR: Failed to read from stdin\n");
284287
free(plist_entire);
285288
free(options);
286289
return 1;
287290
}
291+
plist_entire[read_size] = '\0';
288292
}
289293
else
290294
{

0 commit comments

Comments
 (0)