Commit Diff


commit - eb46335738e5919462d311fc6dd3b9ee2c0e16e3
commit + 3840f4c96dbf09953b6c83fdc338a29817d983d4
blob - d77cc53056e356b8d086100eaa0cabc75ebe746e
blob + b427544ee597fb40d4802b61166507af2c7f124e
--- lib/got_lib_object_parse.h
+++ lib/got_lib_object_parse.h
@@ -44,5 +44,3 @@ const struct got_error *got_object_read_packed_commit_
     struct got_commit_object **, struct got_object *, struct got_pack *);
 const struct got_error *got_object_read_packed_tree_privsep(
     struct got_tree_object **, struct got_object *, struct got_pack *);
-const struct got_error *got_object_read_packed_blob_privsep(size_t *, int,
-    struct got_object *, struct got_pack *);
blob - c36360e3371cbea006d4f4cffe3cad2e726123d4
blob + 63c033d6f774a39c9e2058276608a89c1daa1342
--- lib/got_lib_pack.h
+++ lib/got_lib_pack.h
@@ -165,7 +165,7 @@ int got_packidx_get_object_idx(struct got_packidx *, s
 const struct got_error *got_packfile_open_object(struct got_object **,
     struct got_pack *, struct got_packidx *, int, struct got_object_id *);
 const struct got_error *got_packfile_extract_object(struct got_pack *,
-    struct got_object *, FILE *);
+    struct got_object *, FILE *, FILE *, FILE *);
 const struct got_error *got_packfile_extract_object_to_mem(uint8_t **, size_t *,
     struct got_object *, struct got_pack *);
 const struct got_error *got_pack_get_packfile_size(size_t *, const char *);
blob - 3620a1f18ef31e6581d44f359aba047c1430243c
blob + 91f70c774b1229a71ff2fd12276504df52656861
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
@@ -93,6 +93,9 @@ enum got_imsg_type {
 	GOT_IMSG_PACKIDX,
 	GOT_IMSG_PACK,
 	GOT_IMSG_PACKED_OBJECT_REQUEST,
+
+	/* Message sending file desciprtor to a temporary file. */
+	GOT_IMSG_TMPFD,
 };
 
 /* Structure for GOT_IMSG_ERROR. */
@@ -189,6 +192,7 @@ const struct got_error *got_privsep_send_obj_req(struc
     struct got_object *);
 const struct got_error *got_privsep_send_blob_req(struct imsgbuf *, int);
 const struct got_error *got_privsep_send_blob_outfd(struct imsgbuf *, int);
+const struct got_error *got_privsep_send_tmpfd(struct imsgbuf *, int);
 const struct got_error *got_privsep_send_obj(struct imsgbuf *,
     struct got_object *);
 const struct got_error *got_privsep_get_imsg_obj(struct got_object **,
blob - 70d904c862876bbd6a22fd646cf6c0fa9be94d6a
blob + 7c7fdf3f13ae50b44bf920389211769d3766850f
--- lib/object.c
+++ lib/object.c
@@ -442,7 +442,63 @@ got_object_tree_get_entries(struct got_tree_object *tr
 {
 	return &tree->entries;
 }
+
+static const struct got_error *
+read_packed_blob_privsep(size_t *size, int outfd, struct got_object *obj,
+    struct got_pack *pack)
+{
+	const struct got_error *err = NULL;
+	int outfd_child;
+	int basefd, accumfd; /* temporary files for delta application */
 
+	basefd = got_opentempfd();
+	if (basefd == -1)
+		return got_error_from_errno();
+	accumfd = got_opentempfd();
+	if (accumfd == -1)
+		return got_error_from_errno();
+
+	outfd_child = dup(outfd);
+	if (outfd_child == -1)
+		return got_error_from_errno();
+
+	err = got_privsep_send_obj_req(pack->privsep_child->ibuf, -1, obj);
+	if (err)
+		return err;
+
+	err = got_privsep_send_blob_outfd(pack->privsep_child->ibuf,
+	    outfd_child);
+	if (err) {
+		close(outfd_child);
+		return err;
+	}
+	err = got_privsep_send_tmpfd(pack->privsep_child->ibuf,
+	    basefd);
+	if (err) {
+		close(basefd);
+		close(accumfd);
+		close(outfd_child);
+		return err;
+	}
+
+	err = got_privsep_send_tmpfd(pack->privsep_child->ibuf,
+	    accumfd);
+	if (err) {
+		close(accumfd);
+		close(outfd_child);
+		return err;
+	}
+
+	err = got_privsep_recv_blob(size, pack->privsep_child->ibuf);
+	if (err)
+		return err;
+
+	if (lseek(outfd, SEEK_SET, 0) == -1)
+		err = got_error_from_errno();
+
+	return err;
+}
+
 const struct got_error *
 got_object_blob_open(struct got_blob_object **blob,
     struct got_repository *repo, struct got_object *obj, size_t blocksize)
@@ -480,8 +536,7 @@ got_object_blob_open(struct got_blob_object **blob,
 			if (err)
 				goto done;
 		}
-		err = got_object_read_packed_blob_privsep(&size, outfd,
-		    obj, pack);
+		err = read_packed_blob_privsep(&size, outfd, obj, pack);
 		if (err)
 			goto done;
 		obj->size = size;
blob - 091877528d84ffeecce69bcaa5d7a92d7cf41a75
blob + bab79facebb43d058755da15af744e18af33ee0d
--- lib/object_parse.c
+++ lib/object_parse.c
@@ -836,38 +836,6 @@ got_object_read_packed_tree_privsep(struct got_tree_ob
 		return err;
 
 	return got_privsep_recv_tree(tree, pack->privsep_child->ibuf);
-}
-
-const struct got_error *
-got_object_read_packed_blob_privsep(size_t *size, int outfd,
-    struct got_object *obj, struct got_pack *pack)
-{
-	const struct got_error *err = NULL;
-	int outfd_child;
-
-	outfd_child = dup(outfd);
-	if (outfd_child == -1)
-		return got_error_from_errno();
-
-	err = got_privsep_send_obj_req(pack->privsep_child->ibuf, -1, obj);
-	if (err)
-		return err;
-
-	err = got_privsep_send_blob_outfd(pack->privsep_child->ibuf,
-	    outfd_child);
-	if (err) {
-		close(outfd_child);
-		return err;
-	}
-
-	err = got_privsep_recv_blob(size, pack->privsep_child->ibuf);
-	if (err)
-		return err;
-
-	if (lseek(outfd, SEEK_SET, 0) == -1)
-		err = got_error_from_errno();
-
-	return err;
 }
 
 static const struct got_error *
blob - 3560e5c6fecdfae43a2c4fb617448f293a1db529
blob + a6731723b35cc9a1ee34da07102b0a30cdbb2161
--- lib/pack.c
+++ lib/pack.c
@@ -975,11 +975,10 @@ get_delta_chain_max_size(uint64_t *max_size, struct go
 
 static const struct got_error *
 dump_delta_chain_to_file(size_t *result_size, struct got_delta_chain *deltas,
-    struct got_pack *pack, FILE *outfile)
+    struct got_pack *pack, FILE *outfile, FILE *base_file, FILE *accum_file)
 {
 	const struct got_error *err = NULL;
 	struct got_delta *delta;
-	FILE *base_file = NULL, *accum_file = NULL;
 	uint8_t *base_buf = NULL, *accum_buf = NULL;
 	size_t accum_size = 0;
 	uint64_t max_size;
@@ -997,18 +996,9 @@ dump_delta_chain_to_file(size_t *result_size, struct g
 	if (max_size < GOT_DELTA_RESULT_SIZE_CACHED_MAX) {
 		accum_buf = malloc(max_size);
 		if (accum_buf == NULL)
-			return got_error_from_errno();
-	} else {
-		base_file = got_opentemp();
-		if (base_file == NULL)
 			return got_error_from_errno();
-
-		accum_file = got_opentemp();
-		if (accum_file == NULL) {
-			err = got_error_from_errno();
-			fclose(base_file);
-			return err;
-		}
+		base_file = NULL;
+		accum_file = NULL;
 	}
 
 	/* Deltas are ordered in ascending order. */
@@ -1224,7 +1214,7 @@ done:
 
 const struct got_error *
 got_packfile_extract_object(struct got_pack *pack, struct got_object *obj,
-    FILE *outfile)
+    FILE *outfile, FILE *base_file, FILE *accum_file)
 {
 	const struct got_error *err = NULL;
 
@@ -1247,7 +1237,7 @@ got_packfile_extract_object(struct got_pack *pack, str
 		}
 	} else
 		err = dump_delta_chain_to_file(&obj->size, &obj->deltas, pack,
-		    outfile);
+		    outfile, base_file, accum_file);
 
 	return err;
 }
blob - b7cdab14cb8dc234b6f786daf2860c4c1d25e6cc
blob + 9079955e9790c3b92539b537bb8bc36306b3195f
--- lib/privsep.c
+++ lib/privsep.c
@@ -270,6 +270,16 @@ const struct got_error *
 got_privsep_send_blob_outfd(struct imsgbuf *ibuf, int outfd)
 {
 	if (imsg_compose(ibuf, GOT_IMSG_BLOB_OUTFD, 0, 0, outfd, NULL, 0)
+	    == -1)
+		return got_error_from_errno();
+
+	return flush_imsg(ibuf);
+}
+
+const struct got_error *
+got_privsep_send_tmpfd(struct imsgbuf *ibuf, int fd)
+{
+	if (imsg_compose(ibuf, GOT_IMSG_TMPFD, 0, 0, fd, NULL, 0)
 	    == -1)
 		return got_error_from_errno();
 
blob - 001b16f5d436b8d2a68d194127cb3fde8cac7d97
blob + 51e3ea5274739b0370fd91f0a28663069e7036be
--- libexec/got-read-pack/got-read-pack.c
+++ libexec/got-read-pack/got-read-pack.c
@@ -180,67 +180,82 @@ tree_request(struct imsg *imsg, struct imsgbuf *ibuf, 
 }
 
 static const struct got_error *
-blob_request(struct imsg *imsg, struct imsgbuf *ibuf, struct got_pack *pack,
-    struct got_packidx *packidx, struct got_object_cache *objcache)
+receive_file(FILE **f, struct imsgbuf *ibuf, int imsg_code)
 {
-	const struct got_error *err = NULL;
-	struct got_object *obj = NULL;
-	FILE *f = NULL;
-	struct imsg imsg_outfd;
+	const struct got_error *err;
+	struct imsg imsg;
 	size_t datalen;
 
-	memset(&imsg_outfd, 0, sizeof(imsg_outfd));
-	imsg_outfd.fd = -1;
-
-	err = get_object(&obj, imsg, ibuf, pack, packidx, objcache,
-	    GOT_OBJ_TYPE_BLOB);
+	err = got_privsep_recv_imsg(&imsg, ibuf, 0);
 	if (err)
 		return err;
 
-	err = got_privsep_recv_imsg(&imsg_outfd, ibuf, 0);
-	if (err)
-		return err;
-
-	if (imsg_outfd.hdr.type != GOT_IMSG_BLOB_OUTFD) {
+	if (imsg.hdr.type != imsg_code) {
 		err = got_error(GOT_ERR_PRIVSEP_MSG);
 		goto done;
 	}
 
-	datalen = imsg_outfd.hdr.len - IMSG_HEADER_SIZE;
+	datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
 	if (datalen != 0) {
 		err = got_error(GOT_ERR_PRIVSEP_LEN);
 		goto done;
 	}
-	if (imsg_outfd.fd == -1) {
+	if (imsg.fd == -1) {
 		err = got_error(GOT_ERR_PRIVSEP_NO_FD);
 		goto done;
 	}
 
-	f = fdopen(imsg_outfd.fd, "w+");
-	if (f == NULL) {
+	*f = fdopen(imsg.fd, "w+");
+	if (*f == NULL) {
+		close(imsg.fd);
 		err = got_error_from_errno();
 		goto done;
 	}
+done:
+	imsg_free(&imsg);
+	return err;
+}
 
-	err = got_packfile_extract_object(pack, obj, f);
+static const struct got_error *
+blob_request(struct imsg *imsg, struct imsgbuf *ibuf, struct got_pack *pack,
+    struct got_packidx *packidx, struct got_object_cache *objcache)
+{
+	const struct got_error *err = NULL;
+	struct got_object *obj = NULL;
+	FILE *outfile = NULL, *basefile = NULL, *accumfile = NULL;
+
+	err = get_object(&obj, imsg, ibuf, pack, packidx, objcache,
+	    GOT_OBJ_TYPE_BLOB);
 	if (err)
+		return err;
+
+	err = receive_file(&outfile, ibuf, GOT_IMSG_BLOB_OUTFD);
+	if (err)
+		return err;
+	err = receive_file(&basefile, ibuf, GOT_IMSG_TMPFD);
+	if (err)
+		return err;
+	err = receive_file(&accumfile, ibuf, GOT_IMSG_TMPFD);
+	if (err)
+		return err;
+
+	err = got_packfile_extract_object(pack, obj, outfile, basefile,
+	    accumfile);
+	if (err)
 		goto done;
 
 	err = got_privsep_send_blob(ibuf, obj->size);
 done:
-	if (f)
-		fclose(f);
-	else if (imsg_outfd.fd != -1)
-		close(imsg_outfd.fd);
-	imsg_free(&imsg_outfd);
+	if (outfile)
+		fclose(outfile);
+	if (basefile)
+		fclose(basefile);
+	if (accumfile)
+		fclose(accumfile);
 	if (obj)
 		got_object_close(obj);
-	if (err) {
-		if (err->code == GOT_ERR_PRIVSEP_PIPE)
-			err = NULL;
-		else
-			got_privsep_send_error(ibuf, err);
-	}
+	if (err && err->code != GOT_ERR_PRIVSEP_PIPE)
+		got_privsep_send_error(ibuf, err);
 
 	return err;
 }