commit 962916a2f679f34e4029f33cb57807adb4be3340 from: Stefan Sperling date: Tue Apr 24 10:19:59 2018 UTC add got_inflate_read_fd() and got_inflate_to_fd() commit - 80f4afe898106e3eae350da9d42ecaf3a7d19124 commit + 962916a2f679f34e4029f33cb57807adb4be3340 blob - 9285ed5f1b90a4c3e4017658c8f83fb2dd3e8f2b blob + 0f06cc08df37f0ffd05fa037b55dfe84e59a9d8f --- lib/got_lib_zbuf.h +++ lib/got_lib_zbuf.h @@ -31,6 +31,9 @@ const struct got_error *got_inflate_init(struct got_zs size_t); const struct got_error *got_inflate_read(struct got_zstream_buf *, FILE *, size_t *); +const struct got_error *got_inflate_read_fd(struct got_zstream_buf *, int, + size_t *); void got_inflate_end(struct got_zstream_buf *); const struct got_error *got_inflate_to_mem(uint8_t **, size_t *, FILE *); const struct got_error *got_inflate_to_file(size_t *, FILE *, FILE *); +const struct got_error *got_inflate_to_fd(size_t *, int, int); blob - 2b3120f98279f1802f0187c4a387f17ba660f9fe blob + dcb2c9d4de8e4f38a93330772725e647ab5c2dc2 --- lib/zbuf.c +++ lib/zbuf.c @@ -105,6 +105,45 @@ got_inflate_read(struct got_zstream_buf *zb, FILE *f, return NULL; } +const struct got_error * +got_inflate_read_fd(struct got_zstream_buf *zb, int fd, size_t *outlenp) +{ + size_t last_total_out = zb->z.total_out; + z_stream *z = &zb->z; + int ret = Z_ERRNO; + + z->next_out = zb->outbuf; + z->avail_out = zb->outlen; + + *outlenp = 0; + do { + if (z->avail_in == 0) { + ssize_t n = read(fd, zb->inbuf, zb->inlen); + if (n < 0) + return got_error_from_errno(); + else if (n == 0) { + /* EOF */ + ret = Z_STREAM_END; + break; + } + z->next_in = zb->inbuf; + z->avail_in = n; + } + ret = inflate(z, Z_SYNC_FLUSH); + } while (ret == Z_OK && z->avail_out > 0); + + if (ret == Z_OK) { + zb->flags |= GOT_ZSTREAM_F_HAVE_MORE; + } else { + if (ret != Z_STREAM_END) + return got_error(GOT_ERR_DECOMPRESSION); + zb->flags &= ~GOT_ZSTREAM_F_HAVE_MORE; + } + + *outlenp = z->total_out - last_total_out; + return NULL; +} + void got_inflate_end(struct got_zstream_buf *zb) { @@ -158,6 +197,43 @@ done: } const struct got_error * +got_inflate_to_fd(size_t *outlen, int infd, int outfd) +{ + const struct got_error *err = NULL; + size_t avail; + struct got_zstream_buf zb; + + err = got_inflate_init(&zb, NULL, GOT_ZSTREAM_BUFSIZE); + if (err) + goto done; + + *outlen = 0; + + do { + err = got_inflate_read_fd(&zb, infd, &avail); + if (err) + return err; + if (avail > 0) { + ssize_t n; + n = write(outfd, zb.outbuf, avail); + if (n != avail) { + err = got_error_from_errno(); + goto done; + } + *outlen += avail; + } + } while (zb.flags & GOT_ZSTREAM_F_HAVE_MORE); + +done: + if (err == NULL) { + if (lseek(outfd, SEEK_SET, 0) == -1) + err = got_error_from_errno(); + } + got_inflate_end(&zb); + return err; +} + +const struct got_error * got_inflate_to_file(size_t *outlen, FILE *infile, FILE *outfile) { const struct got_error *err;