commit - 80f4afe898106e3eae350da9d42ecaf3a7d19124
commit + 962916a2f679f34e4029f33cb57807adb4be3340
blob - 9285ed5f1b90a4c3e4017658c8f83fb2dd3e8f2b
blob + 0f06cc08df37f0ffd05fa037b55dfe84e59a9d8f
--- lib/got_lib_zbuf.h
+++ lib/got_lib_zbuf.h
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
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)
{
}
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;