diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2021-12-01 15:38:02 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2021-12-15 15:04:50 -0800 |
commit | cf26200380585019e927fe3cf5c0ecb7c8b3ef14 (patch) | |
tree | 0601d06babe8944698e14b7fc3889a06bdb942f9 /util.c | |
parent | 1440bdbd16cc40f3ef3d0d91106373e29611f528 (diff) | |
download | gzip-cf26200380585019e927fe3cf5c0ecb7c8b3ef14.tar.gz |
gzip: gzip -l now outputs accurate size
gzip -l now decompresses to see how long the uncompressed file was.
This fixes what is by far the most common bug report for gzip.
It has a significant performance cost, but it’s worth it nowadays.
* gzip.c (main): -l now sets 'test' too. All uses of
'test' changed.
(treat_stdin, treat_file): Call do_list after decompressing,
so that the length is known.
(do_list): Omit arg IFD, since it is no longer needed.
All callers changed. Get the CRC and uncompressed size
from input_crc and bytes_out instead of using lseek.
* tests/list-big: New test.
* unzip.c (unzip): Set unzip_crc before returning.
* util.c (write_buf): If 'test', output nothing.
Update bytes_out with output byte count, regardless of 'test'.
All callers changed.
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 18 |
1 files changed, 8 insertions, 10 deletions
@@ -112,7 +112,6 @@ int copy(in, out) errno = 0; while (insize > inptr) { write_buf(out, (char*)inbuf + inptr, insize - inptr); - bytes_out += insize - inptr; got = read_buffer (in, (char *) inbuf, INBUFSIZ); if (got == -1) read_error(); @@ -255,9 +254,7 @@ void flush_outbuf() { if (outcnt == 0) return; - if (!test) - write_buf (ofd, outbuf, outcnt); - bytes_out += (off_t)outcnt; + write_buf (ofd, outbuf, outcnt); outcnt = 0; } @@ -270,16 +267,13 @@ void flush_window() if (outcnt == 0) return; updcrc(window, outcnt); - if (!test) { - write_buf(ofd, (char *)window, outcnt); - } - bytes_out += (off_t)outcnt; + write_buf (ofd, window, outcnt); outcnt = 0; } /* =========================================================================== - * Does the same as write(), but also handles partial pipe writes and checks - * for error return. + * Update the count of output bytes. If testing, do not do any + * output. Otherwise, write the buffer, checking for errors. */ void write_buf(fd, buf, cnt) int fd; @@ -288,6 +282,10 @@ void write_buf(fd, buf, cnt) { unsigned n; + bytes_out += cnt; + if (test) + return; + while ((n = write_buffer (fd, buf, cnt)) != cnt) { if (n == (unsigned)(-1)) { write_error(); |