Commit Diff


commit - f18c433aae68e5537cf67eae05c0343e970307ad
commit + 571608344a37fb96f46850a1124415ab68b1a431
blob - 80e5d2fbcd031246f1194edf450fa9da6e1a2901
blob + cf96009500ac33bb3b660dd7e99902801b0cb975
--- got/got.c
+++ got/got.c
@@ -5845,15 +5845,9 @@ cmd_ref(int argc, char *argv[])
 		got_path_strip_trailing_slashes(refname);
 
 #ifndef PROFILE
-	if (do_list) {
-		if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
-		    NULL) == -1)
-			err(1, "pledge");
-	} else {
-		if (pledge("stdio rpath wpath cpath fattr flock proc exec "
-		    "sendfd unveil", NULL) == -1)
-			err(1, "pledge");
-	}
+	if (pledge("stdio rpath wpath cpath fattr flock proc exec "
+	    "sendfd unveil", NULL) == -1)
+		err(1, "pledge");
 #endif
 	cwd = getcwd(NULL, 0);
 	if (cwd == NULL) {
@@ -5886,6 +5880,15 @@ cmd_ref(int argc, char *argv[])
 	error = got_repo_open(&repo, repo_path, NULL);
 	if (error != NULL)
 		goto done;
+
+#ifndef PROFILE
+	if (do_list) {
+		/* Remove "cpath" promise. */
+		if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
+		    NULL) == -1)
+			err(1, "pledge");
+	}
+#endif
 
 	error = apply_unveil(got_repo_get_path(repo), do_list,
 	    worktree ? got_worktree_get_root_path(worktree) : NULL);
@@ -6213,15 +6216,9 @@ cmd_branch(int argc, char *argv[])
 		usage_branch();
 
 #ifndef PROFILE
-	if (do_list || do_show) {
-		if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
-		    NULL) == -1)
-			err(1, "pledge");
-	} else {
-		if (pledge("stdio rpath wpath cpath fattr flock proc exec "
-		    "sendfd unveil", NULL) == -1)
-			err(1, "pledge");
-	}
+	if (pledge("stdio rpath wpath cpath fattr flock proc exec "
+	    "sendfd unveil", NULL) == -1)
+		err(1, "pledge");
 #endif
 	cwd = getcwd(NULL, 0);
 	if (cwd == NULL) {
@@ -6254,6 +6251,15 @@ cmd_branch(int argc, char *argv[])
 	error = got_repo_open(&repo, repo_path, NULL);
 	if (error != NULL)
 		goto done;
+
+#ifndef PROFILE
+	if (do_list || do_show) {
+		/* Remove "cpath" promise. */
+		if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
+		    NULL) == -1)
+			err(1, "pledge");
+	}
+#endif
 
 	error = apply_unveil(got_repo_get_path(repo), do_list,
 	    worktree ? got_worktree_get_root_path(worktree) : NULL);
@@ -6756,15 +6762,9 @@ cmd_tag(int argc, char *argv[])
 	tag_name = argv[0];
 
 #ifndef PROFILE
-	if (do_list) {
-		if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
-		    NULL) == -1)
-			err(1, "pledge");
-	} else {
-		if (pledge("stdio rpath wpath cpath fattr flock proc exec "
-		    "sendfd unveil", NULL) == -1)
-			err(1, "pledge");
-	}
+	if (pledge("stdio rpath wpath cpath fattr flock proc exec "
+	    "sendfd unveil", NULL) == -1)
+		err(1, "pledge");
 #endif
 	cwd = getcwd(NULL, 0);
 	if (cwd == NULL) {
@@ -6803,6 +6803,12 @@ cmd_tag(int argc, char *argv[])
 		error = got_repo_open(&repo, repo_path, NULL);
 		if (error != NULL)
 			goto done;
+#ifndef PROFILE
+		/* Remove "cpath" promise. */
+		if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
+		    NULL) == -1)
+			err(1, "pledge");
+#endif
 		error = apply_unveil(got_repo_get_path(repo), 1, NULL);
 		if (error)
 			goto done;
@@ -12109,7 +12115,7 @@ cmd_info(int argc, char *argv[])
 	argv += optind;
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
+	if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
 	    NULL) == -1)
 		err(1, "pledge");
 #endif
@@ -12126,6 +12132,12 @@ cmd_info(int argc, char *argv[])
 		goto done;
 	}
 
+#ifndef PROFILE
+	/* Remove "cpath" promise. */
+	if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
+	    NULL) == -1)
+		err(1, "pledge");
+#endif
 	error = apply_unveil(NULL, 0, got_worktree_get_root_path(worktree));
 	if (error)
 		goto done;
blob - 471a8ac92d12a89ee0e086f430301d0ca2adb743
blob + 59c11d1ab01684d8a2f16d934fb1d6870d7ac871
--- gotadmin/gotadmin.c
+++ gotadmin/gotadmin.c
@@ -295,7 +295,7 @@ cmd_info(int argc, char *argv[])
 	argv += optind;
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
+	if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
 	    NULL) == -1)
 		err(1, "pledge");
 #endif
@@ -307,7 +307,12 @@ cmd_info(int argc, char *argv[])
 	error = got_repo_open(&repo, repo_path, NULL);
 	if (error)
 		goto done;
-
+#ifndef PROFILE
+	/* Remove "cpath" promise. */
+	if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
+	    NULL) == -1)
+		err(1, "pledge");
+#endif
 	error = apply_unveil(got_repo_get_path_git_dir(repo), 1);
 	if (error)
 		goto done;
@@ -963,14 +968,19 @@ cmd_listpack(int argc, char *argv[])
 		return got_error_from_errno2("realpath", argv[0]);
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
+	if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
 	    NULL) == -1)
 		err(1, "pledge");
 #endif
 	error = got_repo_open(&repo, packfile_path, NULL);
 	if (error)
 		goto done;
-
+#ifndef PROFILE
+	/* Remove "cpath" promise. */
+	if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
+	    NULL) == -1)
+		err(1, "pledge");
+#endif
 	error = apply_unveil(got_repo_get_path_git_dir(repo), 1);
 	if (error)
 		goto done;
blob - 6a3d3981c9afd96d48ef7746b2d0b1d78793a7ca
blob + 0aed8754f53747ab02a5563d0a6435959c59c3d4
--- lib/got_lib_pack.h
+++ lib/got_lib_pack.h
@@ -21,6 +21,8 @@ struct got_pack {
 	uint8_t *map;
 	size_t filesize;
 	struct got_privsep_child *privsep_child;
+	int basefd;
+	int accumfd;
 	int child_has_tempfiles;
 	int child_has_delta_outfd;
 	struct got_delta_cache *delta_cache;
blob - 2d612890612d7d8a8e30549c38659cd083a2e41e
blob + 47175236af75523bec4c9972e40679dcdd6d15f0
--- lib/object.c
+++ lib/object.c
@@ -172,7 +172,7 @@ static const struct got_error *
 pack_child_send_tempfiles(struct imsgbuf *ibuf, struct got_pack *pack)
 {
 	const struct got_error *err;
-	int basefd, accumfd;
+	int basefd = -1, accumfd = -1;
 
 	/* 
 	 * For performance reasons, the child will keep reusing the
@@ -183,23 +183,29 @@ pack_child_send_tempfiles(struct imsgbuf *ibuf, struct
 	if (pack->child_has_tempfiles)
 		return NULL;
 
-	basefd = got_opentempfd();
+	basefd = dup(pack->basefd);
 	if (basefd == -1)
-		return got_error_from_errno("got_opentempfd");
+		return got_error_from_errno("dup");
 
+	accumfd = dup(pack->accumfd);
+	if (accumfd == -1) {
+		err = got_error_from_errno("dup");
+		goto done;
+	}
+
 	err = got_privsep_send_tmpfd(ibuf, basefd);
 	if (err)
-		return err;
-
-	accumfd = got_opentempfd();
-	if (accumfd == -1)
-		return got_error_from_errno("got_opentempfd");
+		goto done;
 
 	err = got_privsep_send_tmpfd(ibuf, accumfd);
-	if (err)
-		return err;
-
-	pack->child_has_tempfiles = 1;
+done:
+	if (err) {
+		if (basefd != -1)
+			close(basefd);
+		if (accumfd != -1)
+			close(accumfd);
+	} else
+		pack->child_has_tempfiles = 1;
 	return NULL;
 }
 
blob - 2c612a33c5d96977b8bbe4ac08c2fc41cc78381b
blob + bbeafedb2d303742ae359d0ab03b005700ed75e2
--- lib/pack.c
+++ lib/pack.c
@@ -751,6 +751,11 @@ got_pack_close(struct got_pack *pack)
 		pack->delta_cache = NULL;
 	}
 
+	/*
+	 * Leave accumfd and basefd alone. They are managed by the
+	 * repository layer and can be reused.
+	 */
+
 	return err;
 }
 
blob - 7896e9194a183430cbeecf89b54758b1e9b1dc94
blob + f4585bf3d903303171bdbc6a683382e865a425e9
--- lib/repository.c
+++ lib/repository.c
@@ -50,6 +50,7 @@
 #include "got_path.h"
 #include "got_cancel.h"
 #include "got_object.h"
+#include "got_opentemp.h"
 
 #include "got_lib_delta.h"
 #include "got_lib_inflate.h"
@@ -700,6 +701,19 @@ got_repo_open(struct got_repository **repop, const cha
 	repo->pack_cache_size = GOT_PACK_CACHE_SIZE;
 	if (repo->pack_cache_size > rl.rlim_cur / 8)
 		repo->pack_cache_size = rl.rlim_cur / 8;
+	for (i = 0; i < nitems(repo->packs); i++) {
+		if (i < repo->pack_cache_size) {
+			repo->packs[i].basefd = got_opentempfd();
+			if (repo->packs[i].basefd == -1)
+				return got_error_from_errno("got_opentempfd");
+			repo->packs[i].accumfd = got_opentempfd();
+			if (repo->packs[i].accumfd == -1)
+				return got_error_from_errno("got_opentempfd");
+		} else {
+			repo->packs[i].basefd = -1;
+			repo->packs[i].accumfd = -1;
+		}
+	}
 
 	repo_path = realpath(path, NULL);
 	if (repo_path == NULL) {
@@ -786,6 +800,16 @@ got_repo_close(struct got_repository *repo)
 		if (repo->packs[i].path_packfile == NULL)
 			break;
 		got_pack_close(&repo->packs[i]);
+		if (repo->packs[i].basefd != -1) {
+			if (close(repo->packs[i].basefd) == -1 && err == NULL)
+				err = got_error_from_errno("close");
+			repo->packs[i].basefd = -1;
+		}
+		if (repo->packs[i].accumfd != -1) {
+			if (close(repo->packs[i].accumfd) == -1 && err == NULL)
+				err = got_error_from_errno("close");
+			repo->packs[i].accumfd = -1;
+		}
 	}
 
 	free(repo->path);
@@ -1326,6 +1350,10 @@ got_repo_cache_pack(struct got_pack **packp, struct go
 		err = got_pack_close(&repo->packs[i - 1]);
 		if (err)
 			return err;
+		if (ftruncate(repo->packs[i - 1].basefd, 0L) == -1)
+			return got_error_from_errno("ftruncate");
+		if (ftruncate(repo->packs[i - 1].accumfd, 0L) == -1)
+			return got_error_from_errno("ftruncate");
 		memmove(&repo->packs[1], &repo->packs[0],
 		    sizeof(repo->packs) - sizeof(repo->packs[0]));
 		i = 0;