diff --git a/lrzip.c b/lrzip.c index 68b57d5..653891c 100644 --- a/lrzip.c +++ b/lrzip.c @@ -284,7 +284,7 @@ void flush_tmpoutbuf(rzip_control *control) fwrite_stdout(control->tmp_outbuf, control->out_len); else if (!STDOUT && !TEST_ONLY) write_fdout(control, control->tmp_outbuf, control->out_len); - control->rel_ofs += control->out_len; + control->out_relofs += control->out_len; control->out_ofs = control->out_len = 0; } @@ -369,7 +369,7 @@ static void open_tmpoutbuf(rzip_control *control) control->out_maxlen = control->maxram; /* Allocate slightly more so we can cope when the buffer overflows and * fall back to a real temporary file */ - control->tmp_outbuf = malloc(control->out_maxlen + control->page_size); + control->tmp_outbuf = malloc(control->maxram + control->page_size); if (unlikely(!control->tmp_outbuf)) fatal("Failed to malloc tmp_outbuf in open_tmpoutbuf\n"); if (!DECOMPRESS && !TEST_ONLY) @@ -382,6 +382,21 @@ void close_tmpoutbuf(rzip_control *control) free(control->tmp_outbuf); } +static void open_tmpinbuf(rzip_control *control) +{ + control->flags |= FLAG_TMP_INBUF; + control->in_maxlen = control->maxram; + control->tmp_inbuf = malloc(control->maxram + control->page_size); + if (unlikely(!control->tmp_inbuf)) + fatal("Failed to malloc tmp_inbuf in open_tmpinbuf\n"); +} + +void close_tmpinbuf(rzip_control *control) +{ + control->flags &= ~FLAG_TMP_INBUF; + free(control->tmp_inbuf); +} + /* decompress one file from the command line */ diff --git a/lrzip_private.h b/lrzip_private.h index 68cd3ea..74dd163 100644 --- a/lrzip_private.h +++ b/lrzip_private.h @@ -121,6 +121,7 @@ typedef struct md5_ctx md5_ctx; #define FLAG_KEEP_BROKEN (1 << 19) #define FLAG_THRESHOLD (1 << 20) #define FLAG_TMP_OUTBUF (1 << 21) +#define FLAG_TMP_INBUF (1 << 22) #define NO_MD5 (!(HASH_CHECK) && !(HAS_MD5)) @@ -165,7 +166,12 @@ struct rzip_control { i64 hist_ofs; // History offset i64 out_len; // Total length of tmp_outbuf i64 out_maxlen; // The largest the tmp_outbuf can be used - i64 rel_ofs; // Relative tmp_outbuf offset when stdout has been flushed + i64 out_relofs; // Relative tmp_outbuf offset when stdout has been flushed + char *tmp_inbuf; + i64 in_ofs; + i64 in_len; + i64 in_maxlen; + i64 in_relofs; FILE *msgout; //stream for output messages const char *suffix; int compression_level; diff --git a/main.c b/main.c index 1cce5e8..a2031cc 100644 --- a/main.c +++ b/main.c @@ -700,7 +700,7 @@ int main(int argc, char *argv[]) /* Use less ram when using STDOUT to store the temporary output * file. */ - if (STDOUT && !(DECOMPRESS || TEST_ONLY)) + if (STDOUT && ((STDIN && DECOMPRESS) || !(DECOMPRESS || TEST_ONLY))) control.maxram = control.ramsize * 2 / 9; else control.maxram = control.ramsize / 3; diff --git a/runzip.c b/runzip.c index 6124197..28a5f4a 100644 --- a/runzip.c +++ b/runzip.c @@ -77,19 +77,19 @@ static i64 seekcur_fdout(rzip_control *control) { if (!TMP_OUTBUF) return lseek(control->fd_out, 0, SEEK_CUR); - return (control->rel_ofs + control->out_ofs); + return (control->out_relofs + control->out_ofs); } static i64 seekto_fdout(rzip_control *control, i64 pos) { if (!TMP_OUTBUF) return lseek(control->fd_out, pos, SEEK_SET); - control->out_ofs = pos - control->rel_ofs; + control->out_ofs = pos - control->out_relofs; if (control->out_ofs > control->out_len) control->out_len = control->out_ofs; if (unlikely(control->out_ofs < 0 || control->out_ofs > control->out_maxlen)) { - print_err("out_ofs %lld out_len %lld hist_ofs %lld rel_ofs %lld\n", - control->out_ofs, control->out_len, control->hist_ofs, control->rel_ofs); + print_err("out_ofs %lld out_len %lld hist_ofs %lld out_relofs %lld\n", + control->out_ofs, control->out_len, control->hist_ofs, control->out_relofs); print_err("Trying to seek outside tmpoutbuf to %lld in seekto_fdout\n", control->out_ofs); return -1; } @@ -100,12 +100,12 @@ static i64 seekto_fdhist(rzip_control *control, i64 pos) { if (!TMP_OUTBUF) return lseek(control->fd_hist, pos, SEEK_SET); - control->hist_ofs = pos - control->rel_ofs; + control->hist_ofs = pos - control->out_relofs; if (control->hist_ofs > control->out_len) control->out_len = control->hist_ofs; if (unlikely(control->hist_ofs < 0 || control->hist_ofs > control->out_maxlen)) { - print_err("out_ofs %lld out_len %lld hist_ofs %lld rel_ofs %lld\n", - control->out_ofs, control->out_len, control->hist_ofs, control->rel_ofs); + print_err("out_ofs %lld out_len %lld hist_ofs %lld out_relofs %lld\n", + control->out_ofs, control->out_len, control->hist_ofs, control->out_relofs); print_err("Trying to seek outside tmpoutbuf to %lld in seekto_fdhist\n", control->hist_ofs); return -1; } diff --git a/stream.c b/stream.c index 1eda96a..55ff5b3 100644 --- a/stream.c +++ b/stream.c @@ -782,7 +782,7 @@ static int seekto(rzip_control *control, struct stream_info *sinfo, i64 pos) i64 spos = pos + sinfo->initial_pos; if (TMP_OUTBUF) { - spos -= control->rel_ofs; + spos -= control->out_relofs; control->out_ofs = spos; if (unlikely(spos > control->out_len || spos < 0)) { print_err("Trying to seek to %lld outside tmp outbuf in seekto\n", spos); @@ -806,7 +806,7 @@ static i64 get_seek(rzip_control *control, int fd) i64 ret; if (TMP_OUTBUF) - return control->rel_ofs + control->out_ofs; + return control->out_relofs + control->out_ofs; ret = lseek(fd, 0, SEEK_CUR); if (unlikely(ret == -1)) fatal("Failed to lseek in get_seek\n");