[PATCH 4/5] refs.c: add an err argument to commit_packed_refs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Ronnie Sahlberg <sahlberg@xxxxxxxxxx>
---
 refs.c | 85 +++++++++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 50 insertions(+), 35 deletions(-)

diff --git a/refs.c b/refs.c
index cfe1292..19e73f3 100644
--- a/refs.c
+++ b/refs.c
@@ -2232,8 +2232,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
  * Write an entry to the packed-refs file for the specified refname.
  * If peeled is non-NULL, write it as the entry's peeled value.
  */
-static void write_packed_entry(int fd, char *refname, unsigned char *sha1,
-			       unsigned char *peeled)
+static int write_packed_entry(int fd, char *refname, unsigned char *sha1,
+			      unsigned char *peeled, struct strbuf *err)
 {
 	char line[PATH_MAX + 100];
 	int len;
@@ -2241,33 +2241,50 @@ static void write_packed_entry(int fd, char *refname, unsigned char *sha1,
 	len = snprintf(line, sizeof(line), "%s %s\n",
 		       sha1_to_hex(sha1), refname);
 	/* this should not happen but just being defensive */
-	if (len > sizeof(line))
-		die("too long a refname '%s'", refname);
-	write_or_die(fd, line, len);
-
+	if (len > sizeof(line)) {
+		strbuf_addf(err, "too long a refname '%s'", refname);
+		return -1;
+	}
+	if (write_in_full(fd, line, len) != len) {
+		strbuf_addf(err, "error writing to packed-refs. %s",
+			    strerror(errno));
+		return -1;
+	}
 	if (peeled) {
 		if (snprintf(line, sizeof(line), "^%s\n",
 			     sha1_to_hex(peeled)) != PEELED_LINE_LENGTH)
 			die("internal error");
-		write_or_die(fd, line, PEELED_LINE_LENGTH);
+		len = PEELED_LINE_LENGTH;
+		if (write_in_full(fd, line, len) != len) {
+			strbuf_addf(err, "error writing to packed-refs. %s",
+				    strerror(errno));
+			return -1;
+		}
 	}
+	return 0;
 }
 
+struct write_packed_data {
+	int fd;
+	struct strbuf *err;
+};
+
 /*
  * An each_ref_entry_fn that writes the entry to a packed-refs file.
  */
 static int write_packed_entry_fn(struct ref_entry *entry, void *cb_data)
 {
-	int *fd = cb_data;
+	struct write_packed_data *data = cb_data;
 	enum peel_status peel_status = peel_entry(entry, 0);
 
-	if (peel_status != PEEL_PEELED && peel_status != PEEL_NON_TAG)
-		error("internal error: %s is not a valid packed reference!",
-		      entry->name);
-	write_packed_entry(*fd, entry->name, entry->u.value.sha1,
-			   peel_status == PEEL_PEELED ?
-			   entry->u.value.peeled : NULL);
-	return 0;
+	if (peel_status != PEEL_PEELED && peel_status != PEEL_NON_TAG) {
+		strbuf_addf(data->err, "internal error: %s is not a "
+			    "valid packed reference!", entry->name);
+		return -1;
+	}
+	return write_packed_entry(data->fd, entry->name, entry->u.value.sha1,
+				  peel_status == PEEL_PEELED ?
+				  entry->u.value.peeled : NULL, data->err);
 }
 
 static int lock_packed_refs(struct strbuf *err)
@@ -2296,30 +2313,34 @@ static int lock_packed_refs(struct strbuf *err)
 
 /*
  * Commit the packed refs changes.
- * On error we must make sure that errno contains a meaningful value.
  */
-static int commit_packed_refs(void)
+static int commit_packed_refs(struct strbuf *err)
 {
 	struct packed_ref_cache *packed_ref_cache =
 		get_packed_ref_cache(&ref_cache);
 	int error = 0;
-	int save_errno = 0;
+	struct write_packed_data data;
 
 	if (!packed_ref_cache->lock)
 		die("internal error: packed-refs not locked");
-	write_or_die(packed_ref_cache->lock->fd,
-		     PACKED_REFS_HEADER, strlen(PACKED_REFS_HEADER));
+	if (write_in_full(packed_ref_cache->lock->fd,
+			  PACKED_REFS_HEADER, strlen(PACKED_REFS_HEADER)) < 0) {
+		strbuf_addf(err, "error writing packed-refs. %s",
+			    strerror(errno));
+		return -1;
+       }
 
+	data.fd = packed_ref_cache->lock->fd;
+	data.err = err;
 	do_for_each_entry_in_dir(get_packed_ref_dir(packed_ref_cache),
-				 0, write_packed_entry_fn,
-				 &packed_ref_cache->lock->fd);
+				 0, write_packed_entry_fn, &data);
 	if (commit_lock_file(packed_ref_cache->lock)) {
-		save_errno = errno;
+		strbuf_addf(err, "unable to overwrite old ref-pack "
+			    "file. %s", strerror(errno));
 		error = -1;
 	}
 	packed_ref_cache->lock = NULL;
 	release_packed_ref_cache(packed_ref_cache);
-	errno = save_errno;
 	return error;
 }
 
@@ -2477,8 +2498,8 @@ int pack_refs(unsigned int flags)
 	do_for_each_entry_in_dir(get_loose_refs(&ref_cache), 0,
 				 pack_if_possible_fn, &cbdata);
 
-	if (commit_packed_refs())
-		die_errno("unable to overwrite old ref-pack file");
+	if (commit_packed_refs(&err))
+		die("%s", err.buf);
 
 	prune_refs(cbdata.ref_to_prune);
 	return 0;
@@ -2549,7 +2570,7 @@ static int repack_without_refs(const char **refnames, int n, struct strbuf *err)
 	struct ref_dir *packed;
 	struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
 	struct string_list_item *ref_to_delete;
-	int i, ret;
+	int i;
 
 	/* Look for a packed ref */
 	for (i = 0; i < n; i++)
@@ -2572,11 +2593,7 @@ static int repack_without_refs(const char **refnames, int n, struct strbuf *err)
 	}
 
 	/* Write what remains */
-	ret = commit_packed_refs();
-	if (ret && err)
-		strbuf_addf(err, "unable to overwrite old ref-pack file: %s",
-			    strerror(errno));
-	return ret;
+	return commit_packed_refs(err);
 }
 
 static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err)
@@ -3681,9 +3698,7 @@ int transaction_commit(struct ref_transaction *transaction,
 	if (need_repack) {
 		packed = get_packed_refs(&ref_cache);
 		sort_ref_dir(packed);
-		if (commit_packed_refs()){
-			strbuf_addf(err, "unable to overwrite old ref-pack "
-				    "file");
+		if (commit_packed_refs(err)){
 			ret = -1;
 			goto cleanup;
 		}
-- 
2.0.1.556.ge8f7cba.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]