commit - be37c2e655dc550635c6a766a9b43700482c85c1
commit + 8b2180d40ae950c447339c459dc82e4708136cbf
blob - 497c9c20139eece533dba83c6938dd6847ab1049
blob + fdc4674cc9c28b74b91e37266f1fea6402e9dc7b
--- lib/got_lib_pack.h
+++ lib/got_lib_pack.h
/* An open pack file. */
struct got_pack {
char *path_packfile;
- FILE *packfile;
+ int fd;
size_t filesize;
};
blob - 0f06cc08df37f0ffd05fa037b55dfe84e59a9d8f
blob + 55eb6bb8c0ba084834a8b92595cbbbba72818c43
--- lib/got_lib_zbuf.h
+++ lib/got_lib_zbuf.h
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_mem_fd(uint8_t **, size_t *, int);
const struct got_error *got_inflate_to_file(size_t *, FILE *, FILE *);
-const struct got_error *got_inflate_to_fd(size_t *, int, int);
+const struct got_error *got_inflate_to_file_fd(size_t *, int, FILE *);
+const struct got_error *got_inflate_to_fd(size_t *, FILE *, int);
blob - 73858c5ee156e66a6ef9dc8fc390e0542bdaf55a
blob + 070c41a421af9076bc2ee24a8adba8ba911a2a60
--- lib/object.c
+++ lib/object.c
}
static const struct got_error *
-read_blob_object(size_t *size, int outfd, int infd)
-{
- return got_inflate_to_fd(size, infd, outfd);
-}
-
-static const struct got_error *
read_blob_object_privsep_child(int outfd, int infd, int imsg_fds[2])
{
const struct got_error *err = NULL;
struct imsgbuf ibuf;
int status = 0;
size_t size;
+ FILE *infile = NULL;
setproctitle("read blob object");
close(imsg_fds[0]);
goto done;
}
- err = read_blob_object(&size, outfd, infd);
- close(infd);
+ infile = fdopen(infd, "rb");
+ if (infile == NULL) {
+ err = got_error_from_errno();
+ close(infd);
+ goto done;
+ }
+ err = got_inflate_to_fd(&size, infile, outfd);
+ fclose(infile);
if (err)
goto done;
blob - a82e6faaf749168b298617bc5c024054687df83a
blob + 79459d949b01708f338b76794511f6ac966bd6cd
--- lib/pack.c
+++ lib/pack.c
}
const struct got_error *
-read_packfile_hdr(FILE *f, struct got_packidx_v2_hdr *packidx)
+read_packfile_hdr(int fd, struct got_packidx_v2_hdr *packidx)
{
const struct got_error *err = NULL;
uint32_t totobj = betoh32(packidx->fanout_table[0xff]);
struct got_packfile_hdr hdr;
- size_t n;
+ ssize_t n;
- n = fread(&hdr, sizeof(hdr), 1, f);
- if (n != 1)
- return got_ferror(f, GOT_ERR_BAD_PACKIDX);
+ n = read(fd, &hdr, sizeof(hdr));
+ if (n < 0)
+ return got_error_from_errno();
+ if (n != sizeof(hdr))
+ return got_error(GOT_ERR_BAD_PACKFILE);
if (betoh32(hdr.signature) != GOT_PACKFILE_SIGNATURE ||
betoh32(hdr.version) != GOT_PACKFILE_VERSION ||
}
static const struct got_error *
-open_packfile(FILE **packfile, const char *path_packfile,
+open_packfile(int *fd, const char *path_packfile,
struct got_repository *repo, struct got_packidx_v2_hdr *packidx)
{
const struct got_error *err = NULL;
- *packfile = NULL;
+ *fd = open(path_packfile, O_RDONLY | O_NOFOLLOW, GOT_DEFAULT_FILE_MODE);
+ if (*fd == -1)
+ return got_error_from_errno();
- *packfile = fopen(path_packfile, "rb");
- if (*packfile == NULL) {
- err = got_error_from_errno();
- return err;
- }
-
if (packidx) {
- err = read_packfile_hdr(*packfile, packidx);
+ err = read_packfile_hdr(*fd, packidx);
if (err) {
- fclose(*packfile);
- *packfile = NULL;
+ close(*fd);
+ *fd = -1;
}
}
return err;
void
got_pack_close(struct got_pack *pack)
{
- fclose(pack->packfile);
- pack->packfile = NULL;
+ close(pack->fd);
+ pack->fd = -1;
free(pack->path_packfile);
pack->path_packfile = NULL;
pack->filesize = 0;
goto done;
}
- err = open_packfile(&pack->packfile, path_packfile, repo, packidx);
+ err = open_packfile(&pack->fd, path_packfile, repo, packidx);
if (err)
goto done;
}
static const struct got_error *
-parse_object_type_and_size(uint8_t *type, uint64_t *size, size_t *len,
- FILE *packfile)
+parse_object_type_and_size(uint8_t *type, uint64_t *size, size_t *len, int fd)
{
uint8_t t = 0;
uint64_t s = 0;
uint8_t sizeN;
- size_t n;
+ ssize_t n;
int i = 0;
do {
if (i > 9)
return got_error(GOT_ERR_NO_SPACE);
- n = fread(&sizeN, sizeof(sizeN), 1, packfile);
- if (n != 1)
- return got_ferror(packfile, GOT_ERR_BAD_PACKIDX);
+ n = read(fd, &sizeN, sizeof(sizeN));
+ if (n < 0)
+ return got_error_from_errno();
+ if (n != sizeof(sizeN))
+ return got_error(GOT_ERR_BAD_PACKFILE);
if (i == 0) {
t = (sizeN & GOT_PACK_OBJ_SIZE0_TYPE_MASK) >>
}
static const struct got_error *
-parse_negative_offset(int64_t *offset, size_t *len, FILE *packfile)
+parse_negative_offset(int64_t *offset, size_t *len, int fd)
{
int64_t o = 0;
uint8_t offN;
- size_t n;
+ ssize_t n;
int i = 0;
do {
if (i > 8)
return got_error(GOT_ERR_NO_SPACE);
- n = fread(&offN, sizeof(offN), 1, packfile);
- if (n != 1)
- return got_ferror(packfile, GOT_ERR_BAD_PACKIDX);
+ n = read(fd, &offN, sizeof(offN));
+ if (n < 0)
+ return got_error_from_errno();
+ if (n != sizeof(offN))
+ return got_error(GOT_ERR_BAD_PACKFILE);
if (i == 0)
o = (offN & GOT_PACK_OBJ_DELTA_OFF_VAL_MASK);
}
static const struct got_error *
-parse_offset_delta(off_t *base_offset, FILE *packfile, off_t offset)
+parse_offset_delta(off_t *base_offset, int fd, off_t offset)
{
const struct got_error *err;
int64_t negoffset;
size_t negofflen;
- err = parse_negative_offset(&negoffset, &negofflen, packfile);
+ err = parse_negative_offset(&negoffset, &negofflen, fd);
if (err)
return err;
static const struct got_error *
resolve_delta_chain(struct got_delta_chain *, struct got_repository *,
- FILE *, const char *, off_t, size_t, int, size_t, unsigned int);
+ int, const char *, off_t, size_t, int, size_t, unsigned int);
static const struct got_error *
add_delta(struct got_delta_chain *deltas, const char *path_packfile,
static const struct got_error *
resolve_offset_delta(struct got_delta_chain *deltas,
- struct got_repository *repo, FILE *packfile, const char *path_packfile,
+ struct got_repository *repo, int fd, const char *path_packfile,
off_t delta_offset,size_t tslen, int delta_type, size_t delta_size,
unsigned int recursion)
uint8_t *delta_buf;
size_t delta_len;
- err = parse_offset_delta(&base_offset, packfile, delta_offset);
+ err = parse_offset_delta(&base_offset, fd, delta_offset);
if (err)
return err;
- delta_data_offset = ftello(packfile);
+ delta_data_offset = lseek(fd, 0, SEEK_CUR);
if (delta_data_offset == -1)
return got_error_from_errno();
- err = got_inflate_to_mem(&delta_buf, &delta_len, packfile);
+ err = got_inflate_to_mem_fd(&delta_buf, &delta_len, fd);
if (err)
return err;
return err;
/* An offset delta must be in the same packfile. */
- if (fseeko(packfile, base_offset, SEEK_SET) != 0)
+ if (lseek(fd, base_offset, SEEK_SET) == -1)
return got_error_from_errno();
err = parse_object_type_and_size(&base_type, &base_size, &base_tslen,
- packfile);
+ fd);
if (err)
return err;
- return resolve_delta_chain(deltas, repo, packfile, path_packfile,
+ return resolve_delta_chain(deltas, repo, fd, path_packfile,
base_offset, base_tslen, base_type, base_size, recursion - 1);
}
static const struct got_error *
resolve_ref_delta(struct got_delta_chain *deltas, struct got_repository *repo,
- FILE *packfile, const char *path_packfile, off_t delta_offset,
+ int fd, const char *path_packfile, off_t delta_offset,
size_t tslen, int delta_type, size_t delta_size, unsigned int recursion)
{
const struct got_error *err;
uint8_t base_type;
uint64_t base_size;
size_t base_tslen;
- size_t n;
+ ssize_t n;
char *path_base_packfile;
struct got_pack *base_pack;
off_t delta_data_offset;
uint8_t *delta_buf;
size_t delta_len;
- n = fread(&id, sizeof(id), 1, packfile);
- if (n != 1)
- return got_ferror(packfile, GOT_ERR_IO);
+ n = read(fd, &id, sizeof(id));
+ if (n < 0)
+ return got_error_from_errno();
+ if (n != sizeof(id))
+ return got_error(GOT_ERR_BAD_PACKFILE);
- delta_data_offset = ftello(packfile);
+ delta_data_offset = lseek(fd, 0, SEEK_CUR);
if (delta_data_offset == -1)
return got_error_from_errno();
- err = got_inflate_to_mem(&delta_buf, &delta_len, packfile);
+ err = got_inflate_to_mem_fd(&delta_buf, &delta_len, fd);
if (err)
return err;
goto done;
}
- if (fseeko(base_pack->packfile, base_offset, SEEK_SET) != 0) {
+ if (lseek(base_pack->fd, base_offset, SEEK_SET) == -1) {
err = got_error_from_errno();
goto done;
}
err = parse_object_type_and_size(&base_type, &base_size, &base_tslen,
- base_pack->packfile);
+ base_pack->fd);
if (err)
goto done;
- err = resolve_delta_chain(deltas, repo, base_pack->packfile,
+ err = resolve_delta_chain(deltas, repo, base_pack->fd,
path_base_packfile, base_offset, base_tslen, base_type,
base_size, recursion - 1);
done:
static const struct got_error *
resolve_delta_chain(struct got_delta_chain *deltas, struct got_repository *repo,
- FILE *packfile, const char *path_packfile, off_t delta_offset, size_t tslen,
+ int fd, const char *path_packfile, off_t delta_offset, size_t tslen,
int delta_type, size_t delta_size, unsigned int recursion)
{
const struct got_error *err = NULL;
delta_type, delta_size, 0, NULL, 0);
break;
case GOT_OBJ_TYPE_OFFSET_DELTA:
- err = resolve_offset_delta(deltas, repo, packfile,
- path_packfile, delta_offset, tslen, delta_type,
- delta_size, recursion - 1);
+ err = resolve_offset_delta(deltas, repo, fd, path_packfile,
+ delta_offset, tslen, delta_type, delta_size, recursion - 1);
break;
case GOT_OBJ_TYPE_REF_DELTA:
- err = resolve_ref_delta(deltas, repo, packfile,
- path_packfile, delta_offset, tslen, delta_type,
- delta_size, recursion - 1);
+ err = resolve_ref_delta(deltas, repo, fd, path_packfile,
+ delta_offset, tslen, delta_type, delta_size, recursion - 1);
break;
default:
return got_error(GOT_ERR_OBJ_TYPE);
static const struct got_error *
open_delta_object(struct got_object **obj, struct got_repository *repo,
struct got_packidx_v2_hdr *packidx, const char *path_packfile,
- FILE *packfile, struct got_object_id *id, off_t offset, size_t tslen,
+ int fd, struct got_object_id *id, off_t offset, size_t tslen,
int delta_type, size_t delta_size)
{
const struct got_error *err = NULL;
SIMPLEQ_INIT(&(*obj)->deltas.entries);
(*obj)->flags |= GOT_OBJ_FLAG_DELTIFIED;
- err = resolve_delta_chain(&(*obj)->deltas, repo, packfile,
+ err = resolve_delta_chain(&(*obj)->deltas, repo, fd,
path_packfile, offset, tslen, delta_type, delta_size,
GOT_DELTA_CHAIN_RECURSION_MAX);
if (err)
goto done;
}
- if (fseeko(pack->packfile, offset, SEEK_SET) != 0) {
+ if (lseek(pack->fd, offset, SEEK_SET) == -1) {
err = got_error_from_errno();
goto done;
}
- err = parse_object_type_and_size(&type, &size, &tslen, pack->packfile);
+ err = parse_object_type_and_size(&type, &size, &tslen, pack->fd);
if (err)
goto done;
case GOT_OBJ_TYPE_OFFSET_DELTA:
case GOT_OBJ_TYPE_REF_DELTA:
err = open_delta_object(obj, repo, packidx, path_packfile,
- pack->packfile, id, offset, tslen, type, size);
+ pack->fd, id, offset, tslen, type, size);
break;
default:
goto done;
}
- if (fseeko(pack->packfile, delta->offset + delta->tslen,
- SEEK_SET) != 0) {
+ if (lseek(pack->fd, delta->offset + delta->tslen,
+ SEEK_SET) == -1) {
err = got_error_from_errno();
goto done;
}
if (base_file)
- err = got_inflate_to_file(&base_len,
- pack->packfile, base_file);
+ err = got_inflate_to_file_fd(&base_len,
+ pack->fd, base_file);
else {
- err = got_inflate_to_mem(&base_buf, &base_len,
- pack->packfile);
+ err = got_inflate_to_mem_fd(&base_buf, &base_len,
+ pack->fd);
if (base_len < max_size) {
uint8_t *p;
p = reallocarray(base_buf, 1, max_size);
goto done;
}
- if (fseeko(pack->packfile, delta->offset + delta->tslen,
- SEEK_SET) != 0) {
+ if (lseek(pack->fd, delta->offset + delta->tslen,
+ SEEK_SET) == -1) {
err = got_error_from_errno();
goto done;
}
- err = got_inflate_to_mem(&base_buf, &base_len,
- pack->packfile);
+ err = got_inflate_to_mem_fd(&base_buf, &base_len,
+ pack->fd);
if (base_len < max_size) {
uint8_t *p;
p = reallocarray(base_buf, 1, max_size);
{
const struct got_error *err = NULL;
+ *f = NULL;
+
if ((obj->flags & GOT_OBJ_FLAG_PACKED) == 0)
return got_error(GOT_ERR_OBJ_NOT_PACKED);
*f = got_opentemp();
if (*f == NULL) {
- err = got_error(GOT_ERR_FILE_OPEN);
+ err = got_error_from_errno();
goto done;
}
goto done;
}
- if (fseeko(pack->packfile, obj->pack_offset, SEEK_SET) != 0) {
+ if (lseek(pack->fd, obj->pack_offset, SEEK_SET) == -1) {
err = got_error_from_errno();
goto done;
}
- err = got_inflate_to_file(&obj->size, pack->packfile, *f);
+ err = got_inflate_to_file_fd(&obj->size, pack->fd, *f);
} else
- err = dump_delta_chain_to_file(&obj->size, &obj->deltas, *f,
- repo);
+ err = dump_delta_chain_to_file(&obj->size,
+ &obj->deltas, *f, repo);
done:
if (err && *f) {
fclose(*f);
goto done;
}
- if (fseeko(pack->packfile, obj->pack_offset, SEEK_SET) != 0) {
+ if (lseek(pack->fd, obj->pack_offset, SEEK_SET) == -1) {
err = got_error_from_errno();
goto done;
}
- err = got_inflate_to_mem(buf, len, pack->packfile);
+ err = got_inflate_to_mem_fd(buf, len, pack->fd);
} else
err = dump_delta_chain_to_mem(buf, len, &obj->deltas, repo);
done:
blob - dcb2c9d4de8e4f38a93330772725e647ab5c2dc2
blob + 90a2cab8ef89165a7eec96bcb7f6dbf99119e75b
--- lib/zbuf.c
+++ lib/zbuf.c
}
const struct got_error *
-got_inflate_to_fd(size_t *outlen, int infd, int outfd)
+got_inflate_to_mem_fd(uint8_t **outbuf, size_t *outlen, int infd)
{
+ const struct got_error *err;
+ size_t avail;
+ struct got_zstream_buf zb;
+ void *newbuf;
+
+ *outbuf = calloc(1, GOT_ZSTREAM_BUFSIZE);
+ if (*outbuf == NULL)
+ return got_error_from_errno();
+ err = got_inflate_init(&zb, *outbuf, GOT_ZSTREAM_BUFSIZE);
+ if (err)
+ return err;
+
+ *outlen = 0;
+
+ do {
+ err = got_inflate_read_fd(&zb, infd, &avail);
+ if (err)
+ return err;
+ *outlen += avail;
+ if (zb.flags & GOT_ZSTREAM_F_HAVE_MORE) {
+ newbuf = reallocarray(*outbuf, 1,
+ *outlen + GOT_ZSTREAM_BUFSIZE);
+ if (newbuf == NULL) {
+ err = got_error_from_errno();
+ free(*outbuf);
+ *outbuf = NULL;
+ *outlen = 0;
+ goto done;
+ }
+ *outbuf = newbuf;
+ zb.outbuf = newbuf + *outlen;
+ zb.outlen = GOT_ZSTREAM_BUFSIZE;
+ }
+ } while (zb.flags & GOT_ZSTREAM_F_HAVE_MORE);
+
+done:
+ got_inflate_end(&zb);
+ return err;
+}
+
+const struct got_error *
+got_inflate_to_fd(size_t *outlen, FILE *infile, int outfd)
+{
const struct got_error *err = NULL;
size_t avail;
struct got_zstream_buf zb;
*outlen = 0;
do {
- err = got_inflate_read_fd(&zb, infd, &avail);
+ err = got_inflate_read(&zb, infile, &avail);
if (err)
return err;
if (avail > 0) {
got_inflate_end(&zb);
return err;
}
+
+const struct got_error *
+got_inflate_to_file_fd(size_t *outlen, int infd, FILE *outfile)
+{
+ const struct got_error *err;
+ 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) {
+ size_t n;
+ n = fwrite(zb.outbuf, avail, 1, outfile);
+ if (n != 1) {
+ err = got_ferror(outfile, GOT_ERR_IO);
+ goto done;
+ }
+ *outlen += avail;
+ }
+ } while (zb.flags & GOT_ZSTREAM_F_HAVE_MORE);
+
+done:
+ if (err == NULL)
+ rewind(outfile);
+ got_inflate_end(&zb);
+ return err;
+}