short i/o: fix config updates to use write_in_full

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>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Andy Whitcroft 2007-01-08 15:58:38 +00:00 committed by Junio C Hamano
parent 93822c2239
commit 480c9e521b

106
config.c
View File

@ -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;