Commit Diff


commit - c294a758150a69ed50df4df8fb5986257cce07fd
commit + 5345b4c7e102ec42f81e1b9b229294a0774d9b40
blob - 379232fed66680154f7f43abb7948287cd9bd809
blob + 977f28bca21557ad62008b7a21e4d731ecc5cbd9
--- lib/got_lib_lockfile.h
+++ lib/got_lib_lockfile.h
@@ -27,5 +27,6 @@ struct got_lockfile {
 	int fd;
 };
 
-const struct got_error *got_lockfile_lock(struct got_lockfile **, const char *);
-const struct got_error *got_lockfile_unlock(struct got_lockfile *);
+const struct got_error *got_lockfile_lock(struct got_lockfile **,
+    const char *, int);
+const struct got_error *got_lockfile_unlock(struct got_lockfile *, int);
blob - 71a5d735012116d324357ccca04f1c7be867e6c2
blob + 846038c091fec21e8c028ab14a6fcdb0ea52c913
--- lib/lockfile.c
+++ lib/lockfile.c
@@ -31,7 +31,7 @@
 #include "got_lib_lockfile.h"
 
 const struct got_error *
-got_lockfile_lock(struct got_lockfile **lf, const char *path)
+got_lockfile_lock(struct got_lockfile **lf, const char *path, int dir_fd)
 {
 	const struct got_error *err = NULL;
 	int attempts = 5;
@@ -53,9 +53,15 @@ got_lockfile_lock(struct got_lockfile **lf, const char
 	}
 
 	do {
-		(*lf)->fd = open((*lf)->path,
-		    O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK,
-		    GOT_DEFAULT_FILE_MODE);
+		if (dir_fd != -1) {
+			(*lf)->fd = openat(dir_fd, (*lf)->path,
+			    O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK,
+			    GOT_DEFAULT_FILE_MODE);
+		} else {
+			(*lf)->fd = open((*lf)->path,
+			    O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK,
+			    GOT_DEFAULT_FILE_MODE);
+		}
 		if ((*lf)->fd != -1)
 			break;
 		if (errno != EEXIST) {
@@ -69,18 +75,22 @@ got_lockfile_lock(struct got_lockfile **lf, const char
 		err = got_error(GOT_ERR_LOCKFILE_TIMEOUT);
 done:
 	if (err) {
-		got_lockfile_unlock(*lf);
+		got_lockfile_unlock(*lf, dir_fd);
 		*lf = NULL;
 	}
 	return err;
 }
 
 const struct got_error *
-got_lockfile_unlock(struct got_lockfile *lf)
+got_lockfile_unlock(struct got_lockfile *lf, int dir_fd)
 {
 	const struct got_error *err = NULL;
 
-	if (lf->path && lf->fd != -1 && unlink(lf->path) != 0)
+	if (dir_fd != -1) {
+		if (lf->path && lf->fd != -1 &&
+		    unlinkat(dir_fd, lf->path, 0) != 0)
+			err = got_error_from_errno("unlinkat");
+	} else if (lf->path && lf->fd != -1 && unlink(lf->path) != 0)
 		err = got_error_from_errno("unlink");
 	if (lf->fd != -1 && close(lf->fd) == -1 && err == NULL)
 		err = got_error_from_errno("close");
blob - 38484be4282a8429eade676e2b71bcbb96196be8
blob + 70dc0d95f90464c02d691b2e2157c818079650c3
--- lib/object_create.c
+++ lib/object_create.c
@@ -87,7 +87,7 @@ create_object_file(struct got_object_id *id, FILE *con
 	if (err)
 		goto done;
 
-	err = got_lockfile_lock(&lf, objpath);
+	err = got_lockfile_lock(&lf, objpath, -1);
 	if (err)
 		goto done;
 
@@ -107,7 +107,7 @@ done:
 	if (tmpfile && fclose(tmpfile) == EOF && err == NULL)
 		err = got_error_from_errno("fclose");
 	if (lf)
-		unlock_err = got_lockfile_unlock(lf);
+		unlock_err = got_lockfile_unlock(lf, -1);
 	return err ? err : unlock_err;
 }
 
blob - b89875ec9e861ec53c6a8c19a5fcbaa184ead648
blob + ee703d1487de86d26b7373621514084605d208eb
--- lib/reference.c
+++ lib/reference.c
@@ -174,7 +174,7 @@ parse_ref_file(struct got_reference **ref, const char 
 	struct got_lockfile *lf = NULL;
 
 	if (lock) {
-		err = got_lockfile_lock(&lf, abspath);
+		err = got_lockfile_lock(&lf, abspath, -1);
 		if (err) {
 			if (err->code == GOT_ERR_ERRNO && errno == ENOENT)
 				err = got_error_not_ref(name);
@@ -189,7 +189,7 @@ parse_ref_file(struct got_reference **ref, const char 
 		else
 			err = got_error_not_ref(name);
 		if (lock)
-			got_lockfile_unlock(lf);
+			got_lockfile_unlock(lf, -1);
 		return err;
 	}
 
@@ -206,7 +206,7 @@ parse_ref_file(struct got_reference **ref, const char 
 				err = got_error_from_errno2("getline", abspath);
 		}
 		if (lock)
-			got_lockfile_unlock(lf);
+			got_lockfile_unlock(lf, -1);
 		goto done;
 	}
 	while (linelen > 0 && line[linelen - 1] == '\n') {
@@ -217,12 +217,12 @@ parse_ref_file(struct got_reference **ref, const char 
 	err = parse_ref_line(ref, absname, line);
 	if (lock) {
 		if (err)
-			got_lockfile_unlock(lf);
+			got_lockfile_unlock(lf, -1);
 		else {
 			if (*ref)
 				(*ref)->lf = lf;
 			else
-				got_lockfile_unlock(lf);
+				got_lockfile_unlock(lf, -1);
 		}
 	}
 done:
@@ -479,7 +479,7 @@ got_ref_open(struct got_reference **ref, struct got_re
 		}
 
 		if (lock) {
-			err = got_lockfile_lock(&lf, packed_refs_path);
+			err = got_lockfile_lock(&lf, packed_refs_path, -1);
 			if (err)
 				goto done;
 		}
@@ -502,7 +502,7 @@ done:
 	if (!err && *ref == NULL)
 		err = got_error_not_ref(refname);
 	if (err && lf)
-		got_lockfile_unlock(lf);
+		got_lockfile_unlock(lf, -1);
 	free(path_refs);
 	return err;
 }
@@ -1175,7 +1175,7 @@ got_ref_write(struct got_reference *ref, struct got_re
 	}
 
 	if (ref->lf == NULL) {
-		err = got_lockfile_lock(&lf, path);
+		err = got_lockfile_lock(&lf, path, -1);
 		if (err)
 			goto done;
 	}
@@ -1203,7 +1203,7 @@ got_ref_write(struct got_reference *ref, struct got_re
 	tmppath = NULL;
 done:
 	if (ref->lf == NULL && lf)
-		unlock_err = got_lockfile_unlock(lf);
+		unlock_err = got_lockfile_unlock(lf, -1);
 	if (f) {
 		if (fclose(f) == EOF && err == NULL)
 			err = got_error_from_errno("fclose");
@@ -1244,7 +1244,7 @@ delete_packed_ref(struct got_reference *delref, struct
 		goto done;
 
 	if (delref->lf == NULL) {
-		err = got_lockfile_lock(&lf, packed_refs_path);
+		err = got_lockfile_lock(&lf, packed_refs_path, -1);
 		if (err)
 			goto done;
 	}
@@ -1348,7 +1348,7 @@ delete_packed_ref(struct got_reference *delref, struct
 	}
 done:
 	if (delref->lf == NULL && lf)
-		unlock_err = got_lockfile_unlock(lf);
+		unlock_err = got_lockfile_unlock(lf, -1);
 	if (f) {
 		if (fclose(f) == EOF && err == NULL)
 			err = got_error_from_errno("fclose");
@@ -1385,7 +1385,7 @@ delete_loose_ref(struct got_reference *ref, struct got
 	}
 
 	if (ref->lf == NULL) {
-		err = got_lockfile_lock(&lf, path);
+		err = got_lockfile_lock(&lf, path, -1);
 		if (err)
 			goto done;
 	}
@@ -1396,7 +1396,7 @@ delete_loose_ref(struct got_reference *ref, struct got
 		err = got_error_from_errno2("unlink", path);
 done:
 	if (ref->lf == NULL && lf)
-		unlock_err = got_lockfile_unlock(lf);
+		unlock_err = got_lockfile_unlock(lf, -1);
 
 	free(path_refs);
 	free(path);
@@ -1446,7 +1446,7 @@ const struct got_error *
 got_ref_unlock(struct got_reference *ref)
 {
 	const struct got_error *err;
-	err = got_lockfile_unlock(ref->lf);
+	err = got_lockfile_unlock(ref->lf, -1);
 	ref->lf = NULL;
 	return err;
 }
blob - 391b44aff9089bc0157349e22029d60c4765029c
blob + c5017d50e0b3fa7053f7d9159a76ee0467cf926a
--- lib/repository_admin.c
+++ lib/repository_admin.c
@@ -1053,7 +1053,7 @@ purge_loose_object(struct got_object_id *id, void *dat
 	}
 
 	if (!a->dry_run) {
-		err = got_lockfile_lock(&lf, path);
+		err = got_lockfile_lock(&lf, path, -1);
 		if (err)
 			goto done;
 		if (unlink(path) == -1) {
@@ -1073,7 +1073,7 @@ done:
 		err = got_error_from_errno("close");
 	free(path);
 	if (lf)
-		unlock_err = got_lockfile_unlock(lf);
+		unlock_err = got_lockfile_unlock(lf, -1);
 	return err ? err : unlock_err;
 }