git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andy Whitcroft <apw@shadowen.org>
To: git@vger.kernel.org
Subject: [PATCH 4/4] short i/o: fix config updates to use write_in_full
Date: Mon, 08 Jan 2007 15:58:38 +0000	[thread overview]
Message-ID: <260688736d18821c694cf54e11de60e7@pinky> (raw)
In-Reply-To: 45A2699F.5060100@shadowen.org


We need to check that the writes we perform during the update of
the users configuration work.  Convert to using write_in_full().

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
---
diff --git a/config.c b/config.c
index 5cbd130..2c9d07c 100644
--- a/config.c
+++ b/config.c
@@ -464,7 +464,15 @@ static int store_aux(const char* key, const char* value)
 	return 0;
 }
 
-static void store_write_section(int fd, const char* key)
+static int write_error()
+{
+	fprintf(stderr, "Failed to write new configuration file\n");
+	
+	/* Same error code as "failed to rename". */
+	return 4;
+}
+
+static int store_write_section(int fd, const char* key)
 {
 	const char *dot = strchr(key, '.');
 	int len1 = store.baselen, len2 = -1;
@@ -478,37 +486,60 @@ static void store_write_section(int fd, const char* key)
 		}
 	}
 
-	write(fd, "[", 1);
-	write(fd, key, len1);
+	if (write_in_full(fd, "[", 1) != 1 ||
+	    write_in_full(fd, key, len1) != len1)
+		return 0;
 	if (len2 >= 0) {
-		write(fd, " \"", 2);
+		if (write_in_full(fd, " \"", 2) != 2)
+			return 0;
 		while (--len2 >= 0) {
 			unsigned char c = *++dot;
 			if (c == '"')
-				write(fd, "\\", 1);
-			write(fd, &c, 1);
+				if (write_in_full(fd, "\\", 1) != 1)
+					return 0;
+			if (write_in_full(fd, &c, 1) != 1)
+				return 0;
 		}
-		write(fd, "\"", 1);
+		if (write_in_full(fd, "\"", 1) != 1)
+			return 0;
 	}
-	write(fd, "]\n", 2);
+	if (write_in_full(fd, "]\n", 2) != 2)
+		return 0;
+
+	return 1;
 }
 
-static void store_write_pair(int fd, const char* key, const char* value)
+static int store_write_pair(int fd, const char* key, const char* value)
 {
 	int i;
+	int length = strlen(key+store.baselen+1);
 
-	write(fd, "\t", 1);
-	write(fd, key+store.baselen+1,
-		strlen(key+store.baselen+1));
-	write(fd, " = ", 3);
+	if (write_in_full(fd, "\t", 1) != 1 ||
+	    write_in_full(fd, key+store.baselen+1, length) != length ||
+	    write_in_full(fd, " = ", 3) != 3)
+		return 0;
 	for (i = 0; value[i]; i++)
 		switch (value[i]) {
-		case '\n': write(fd, "\\n", 2); break;
-		case '\t': write(fd, "\\t", 2); break;
-		case '"': case '\\': write(fd, "\\", 1);
-		default: write(fd, value+i, 1);
-	}
-	write(fd, "\n", 1);
+		case '\n':
+			if (write_in_full(fd, "\\n", 2) != 2)
+				return 0;
+			break;
+		case '\t':
+			if (write_in_full(fd, "\\t", 2) != 2)
+				return 0;
+			break;
+		case '"':
+		case '\\':
+			if (write_in_full(fd, "\\", 1) != 1)
+				return 0;
+		default:
+			if (write_in_full(fd, value+i, 1) != 1)
+				return 0;
+			break;
+		}
+	if (write_in_full(fd, "\n", 1) != 1)
+		return 0;
+	return 1;
 }
 
 static int find_beginning_of_line(const char* contents, int size,
@@ -648,8 +679,11 @@ int git_config_set_multivar(const char* key, const char* value,
 		}
 
 		store.key = (char*)key;
-		store_write_section(fd, key);
-		store_write_pair(fd, key, value);
+		if (!store_write_section(fd, key) ||
+		    !store_write_pair(fd, key, value)) {
+			ret = write_error();
+			goto out_free;
+		}
 	} else{
 		struct stat st;
 		char* contents;
@@ -729,10 +763,10 @@ int git_config_set_multivar(const char* key, const char* value,
 
 			/* write the first part of the config */
 			if (copy_end > copy_begin) {
-				write(fd, contents + copy_begin,
+				write_in_full(fd, contents + copy_begin,
 				copy_end - copy_begin);
 				if (new_line)
-					write(fd, "\n", 1);
+					write_in_full(fd, "\n", 1);
 			}
 			copy_begin = store.offset[i];
 		}
@@ -740,13 +774,19 @@ int git_config_set_multivar(const char* key, const char* value,
 		/* write the pair (value == NULL means unset) */
 		if (value != NULL) {
 			if (store.state == START)
-				store_write_section(fd, key);
-			store_write_pair(fd, key, value);
+				if (!store_write_section(fd, key)) {
+					ret = write_error();
+					goto out_free;
+				}
+			if (!store_write_pair(fd, key, value)) {
+				ret = write_error();
+				goto out_free;
+			}
 		}
 
 		/* write the rest of the config */
 		if (copy_begin < st.st_size)
-			write(fd, contents + copy_begin,
+			write_in_full(fd, contents + copy_begin,
 				st.st_size - copy_begin);
 
 		munmap(contents, st.st_size);
@@ -800,6 +840,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)
 
 	while (fgets(buf, sizeof(buf), config_file)) {
 		int i;
+		int length;
 		for (i = 0; buf[i] && isspace(buf[i]); i++)
 			; /* do nothing */
 		if (buf[i] == '[') {
@@ -830,15 +871,22 @@ int git_config_rename_section(const char *old_name, const char *new_name)
 				/* old_name matches */
 				ret++;
 				store.baselen = strlen(new_name);
-				store_write_section(out_fd, new_name);
+				if (!store_write_section(out_fd, new_name)) {
+					ret = write_error();
+					goto out;
+				}
 				continue;
 			}
 		}
-		write(out_fd, buf, strlen(buf));
+		length = strlen(buf);
+		if (write_in_full(out_fd, buf, length) != length) {
+			ret = write_error();
+			goto out;
+		}
 	}
 	fclose(config_file);
 	if (close(out_fd) || commit_lock_file(lock) < 0)
-		ret = error("Cannot commit config file!");
+			ret = error("Cannot commit config file!");
  out:
 	free(config_filename);
 	return ret;

  parent reply	other threads:[~2007-01-08 15:58 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-05 10:54 [PATCH] use xread where we are not checking for EAGAIN/EINTR Andy Whitcroft
2007-01-05 11:19 ` Junio C Hamano
2007-01-05 12:20   ` Andy Whitcroft
2007-01-08 15:56     ` Andy Whitcroft
2007-01-08 15:57       ` [PATCH 1/4] short i/o: clean up the naming for the write_{in,or}_xxx family Andy Whitcroft
2007-01-08 15:58       ` [PATCH 2/4] short i/o: fix calls to read to use xread or read_in_full Andy Whitcroft
2007-01-08 15:58       ` [PATCH 3/4] short i/o: fix calls to write to use xwrite or write_in_full Andy Whitcroft
2007-01-08 15:58       ` Andy Whitcroft [this message]
2007-01-08 20:13       ` [PATCH] use xread where we are not checking for EAGAIN/EINTR Junio C Hamano
2007-01-11 21:43       ` [PATCH] Avoid errors and warnings when attempting to do I/O on zero bytes Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=260688736d18821c694cf54e11de60e7@pinky \
    --to=apw@shadowen.org \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).