Merge branch 'jk/write-in-full-fix'
Many codepaths did not diagnose write failures correctly when disks go full, due to their misuse of write_in_full() helper function, which have been corrected. * jk/write-in-full-fix: read_pack_header: handle signed/unsigned comparison in read result config: flip return value of store_write_*() notes-merge: use ssize_t for write_in_full() return value pkt-line: check write_in_full() errors against "< 0" convert less-trivial versions of "write_in_full() != len" avoid "write_in_full(fd, buf, len) != len" pattern get-tar-commit-id: check write_in_full() return against 0 config: avoid "write_in_full(fd, buf, len) < len" pattern
This commit is contained in:
commit
c50424a6f0
@ -33,8 +33,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
|
||||
if (!skip_prefix(content, "52 comment=", &comment))
|
||||
return 1;
|
||||
|
||||
n = write_in_full(1, comment, 41);
|
||||
if (n < 41)
|
||||
if (write_in_full(1, comment, 41) < 0)
|
||||
die_errno("git get-tar-commit-id: write error");
|
||||
|
||||
return 0;
|
||||
|
@ -743,7 +743,7 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed,
|
||||
size_t n;
|
||||
if (feed(feed_state, &buf, &n))
|
||||
break;
|
||||
if (write_in_full(proc.in, buf, n) != n)
|
||||
if (write_in_full(proc.in, buf, n) < 0)
|
||||
break;
|
||||
}
|
||||
close(proc.in);
|
||||
|
@ -18,7 +18,7 @@ static int outf(void *dummy, mmbuffer_t *ptr, int nbuf)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nbuf; i++)
|
||||
if (write_in_full(1, ptr[i].ptr, ptr[i].size) != ptr[i].size)
|
||||
if (write_in_full(1, ptr[i].ptr, ptr[i].size) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ static char *create_temp_file(struct object_id *oid)
|
||||
|
||||
xsnprintf(path, sizeof(path), ".merge_file_XXXXXX");
|
||||
fd = xmkstemp(path);
|
||||
if (write_in_full(fd, buf, size) != size)
|
||||
if (write_in_full(fd, buf, size) < 0)
|
||||
die_errno("unable to write temp-file");
|
||||
close(fd);
|
||||
return path;
|
||||
|
38
config.c
38
config.c
@ -2292,10 +2292,11 @@ static int write_error(const char *filename)
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int store_write_section(int fd, const char *key)
|
||||
static ssize_t write_section(int fd, const char *key)
|
||||
{
|
||||
const char *dot;
|
||||
int i, success;
|
||||
int i;
|
||||
ssize_t ret;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
|
||||
dot = memchr(key, '.', store.baselen);
|
||||
@ -2311,15 +2312,16 @@ static int store_write_section(int fd, const char *key)
|
||||
strbuf_addf(&sb, "[%.*s]\n", store.baselen, key);
|
||||
}
|
||||
|
||||
success = write_in_full(fd, sb.buf, sb.len) == sb.len;
|
||||
ret = write_in_full(fd, sb.buf, sb.len);
|
||||
strbuf_release(&sb);
|
||||
|
||||
return success;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int store_write_pair(int fd, const char *key, const char *value)
|
||||
static ssize_t write_pair(int fd, const char *key, const char *value)
|
||||
{
|
||||
int i, success;
|
||||
int i;
|
||||
ssize_t ret;
|
||||
int length = strlen(key + store.baselen + 1);
|
||||
const char *quote = "";
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
@ -2359,10 +2361,10 @@ static int store_write_pair(int fd, const char *key, const char *value)
|
||||
}
|
||||
strbuf_addf(&sb, "%s\n", quote);
|
||||
|
||||
success = write_in_full(fd, sb.buf, sb.len) == sb.len;
|
||||
ret = write_in_full(fd, sb.buf, sb.len);
|
||||
strbuf_release(&sb);
|
||||
|
||||
return success;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t find_beginning_of_line(const char *contents, size_t size,
|
||||
@ -2491,8 +2493,8 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
|
||||
}
|
||||
|
||||
store.key = (char *)key;
|
||||
if (!store_write_section(fd, key) ||
|
||||
!store_write_pair(fd, key, value))
|
||||
if (write_section(fd, key) < 0 ||
|
||||
write_pair(fd, key, value) < 0)
|
||||
goto write_err_out;
|
||||
} else {
|
||||
struct stat st;
|
||||
@ -2602,11 +2604,10 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
|
||||
/* write the first part of the config */
|
||||
if (copy_end > copy_begin) {
|
||||
if (write_in_full(fd, contents + copy_begin,
|
||||
copy_end - copy_begin) <
|
||||
copy_end - copy_begin)
|
||||
copy_end - copy_begin) < 0)
|
||||
goto write_err_out;
|
||||
if (new_line &&
|
||||
write_str_in_full(fd, "\n") != 1)
|
||||
write_str_in_full(fd, "\n") < 0)
|
||||
goto write_err_out;
|
||||
}
|
||||
copy_begin = store.offset[i];
|
||||
@ -2615,18 +2616,17 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
|
||||
/* write the pair (value == NULL means unset) */
|
||||
if (value != NULL) {
|
||||
if (store.state == START) {
|
||||
if (!store_write_section(fd, key))
|
||||
if (write_section(fd, key) < 0)
|
||||
goto write_err_out;
|
||||
}
|
||||
if (!store_write_pair(fd, key, value))
|
||||
if (write_pair(fd, key, value) < 0)
|
||||
goto write_err_out;
|
||||
}
|
||||
|
||||
/* write the rest of the config */
|
||||
if (copy_begin < contents_sz)
|
||||
if (write_in_full(fd, contents + copy_begin,
|
||||
contents_sz - copy_begin) <
|
||||
contents_sz - copy_begin)
|
||||
contents_sz - copy_begin) < 0)
|
||||
goto write_err_out;
|
||||
|
||||
munmap(contents, contents_sz);
|
||||
@ -2803,7 +2803,7 @@ int git_config_rename_section_in_file(const char *config_filename,
|
||||
continue;
|
||||
}
|
||||
store.baselen = strlen(new_name);
|
||||
if (!store_write_section(out_fd, new_name)) {
|
||||
if (write_section(out_fd, new_name) < 0) {
|
||||
ret = write_error(get_lock_file_path(lock));
|
||||
goto out;
|
||||
}
|
||||
@ -2829,7 +2829,7 @@ int git_config_rename_section_in_file(const char *config_filename,
|
||||
if (remove)
|
||||
continue;
|
||||
length = strlen(output);
|
||||
if (write_in_full(out_fd, output, length) != length) {
|
||||
if (write_in_full(out_fd, output, length) < 0) {
|
||||
ret = write_error(get_lock_file_path(lock));
|
||||
goto out;
|
||||
}
|
||||
|
2
diff.c
2
diff.c
@ -3738,7 +3738,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
|
||||
blob = buf.buf;
|
||||
size = buf.len;
|
||||
}
|
||||
if (write_in_full(temp->tempfile->fd, blob, size) != size ||
|
||||
if (write_in_full(temp->tempfile->fd, blob, size) < 0 ||
|
||||
close_tempfile_gently(temp->tempfile))
|
||||
die_errno("unable to write temp-file");
|
||||
temp->name = get_tempfile_path(temp->tempfile);
|
||||
|
5
entry.c
5
entry.c
@ -257,7 +257,8 @@ static int write_entry(struct cache_entry *ce,
|
||||
char *new;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
unsigned long size;
|
||||
size_t wrote, newsize = 0;
|
||||
ssize_t wrote;
|
||||
size_t newsize = 0;
|
||||
struct stat st;
|
||||
const struct submodule *sub;
|
||||
|
||||
@ -332,7 +333,7 @@ static int write_entry(struct cache_entry *ce,
|
||||
fstat_done = fstat_output(fd, state, &st);
|
||||
close(fd);
|
||||
free(new);
|
||||
if (wrote != size)
|
||||
if (wrote < 0)
|
||||
return error("unable to write file %s", path);
|
||||
break;
|
||||
case S_IFGITLINK:
|
||||
|
@ -2952,7 +2952,7 @@ static void parse_reset_branch(const char *arg)
|
||||
|
||||
static void cat_blob_write(const char *buf, unsigned long size)
|
||||
{
|
||||
if (write_in_full(cat_blob_fd, buf, size) != size)
|
||||
if (write_in_full(cat_blob_fd, buf, size) < 0)
|
||||
die_errno("Write to frontend failed");
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ static void inflate_request(const char *prog_name, int out, int buffer_input)
|
||||
die("zlib error inflating request, result %d", ret);
|
||||
|
||||
n = stream.total_out - cnt;
|
||||
if (write_in_full(out, out_buf, n) != n)
|
||||
if (write_in_full(out, out_buf, n) < 0)
|
||||
die("%s aborted reading request", prog_name);
|
||||
cnt += n;
|
||||
|
||||
@ -379,7 +379,7 @@ static void copy_request(const char *prog_name, int out)
|
||||
ssize_t n = read_request(0, &buf);
|
||||
if (n < 0)
|
||||
die_errno("error reading request body");
|
||||
if (write_in_full(out, buf, n) != n)
|
||||
if (write_in_full(out, buf, n) < 0)
|
||||
die("%s aborted reading request", prog_name);
|
||||
close(out);
|
||||
free(buf);
|
||||
|
@ -154,7 +154,7 @@ static void create_temp(mmfile_t *src, char *path, size_t len)
|
||||
|
||||
xsnprintf(path, len, ".merge_file_XXXXXX");
|
||||
fd = xmkstemp(path);
|
||||
if (write_in_full(fd, src->ptr, src->size) != src->size)
|
||||
if (write_in_full(fd, src->ptr, src->size) < 0)
|
||||
die_errno("unable to write temp-file");
|
||||
close(fd);
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ static void write_buf_to_worktree(const struct object_id *obj,
|
||||
fd = xopen(path, O_WRONLY | O_EXCL | O_CREAT, 0666);
|
||||
|
||||
while (size > 0) {
|
||||
long ret = write_in_full(fd, buf, size);
|
||||
ssize_t ret = write_in_full(fd, buf, size);
|
||||
if (ret < 0) {
|
||||
/* Ignore epipe */
|
||||
if (errno == EPIPE)
|
||||
|
29
pkt-line.c
29
pkt-line.c
@ -94,9 +94,9 @@ void packet_flush(int fd)
|
||||
int packet_flush_gently(int fd)
|
||||
{
|
||||
packet_trace("0000", 4, 1);
|
||||
if (write_in_full(fd, "0000", 4) == 4)
|
||||
return 0;
|
||||
return error("flush packet write failed");
|
||||
if (write_in_full(fd, "0000", 4) < 0)
|
||||
return error("flush packet write failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void packet_buf_flush(struct strbuf *buf)
|
||||
@ -137,19 +137,18 @@ static int packet_write_fmt_1(int fd, int gently,
|
||||
const char *fmt, va_list args)
|
||||
{
|
||||
static struct strbuf buf = STRBUF_INIT;
|
||||
ssize_t count;
|
||||
|
||||
strbuf_reset(&buf);
|
||||
format_packet(&buf, fmt, args);
|
||||
count = write_in_full(fd, buf.buf, buf.len);
|
||||
if (count == buf.len)
|
||||
return 0;
|
||||
|
||||
if (!gently) {
|
||||
check_pipe(errno);
|
||||
die_errno("packet write with format failed");
|
||||
if (write_in_full(fd, buf.buf, buf.len) < 0) {
|
||||
if (!gently) {
|
||||
check_pipe(errno);
|
||||
die_errno("packet write with format failed");
|
||||
}
|
||||
return error("packet write with format failed");
|
||||
}
|
||||
return error("packet write with format failed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void packet_write_fmt(int fd, const char *fmt, ...)
|
||||
@ -184,9 +183,9 @@ static int packet_write_gently(const int fd_out, const char *buf, size_t size)
|
||||
packet_size = size + 4;
|
||||
set_packet_header(packet_write_buffer, packet_size);
|
||||
memcpy(packet_write_buffer + 4, buf, size);
|
||||
if (write_in_full(fd_out, packet_write_buffer, packet_size) == packet_size)
|
||||
return 0;
|
||||
return error("packet write failed");
|
||||
if (write_in_full(fd_out, packet_write_buffer, packet_size) < 0)
|
||||
return error("packet write failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void packet_buf_write(struct strbuf *buf, const char *fmt, ...)
|
||||
|
@ -1922,7 +1922,7 @@ static int ce_write_flush(git_SHA_CTX *context, int fd)
|
||||
unsigned int buffered = write_buffer_len;
|
||||
if (buffered) {
|
||||
git_SHA1_Update(context, write_buffer, buffered);
|
||||
if (write_in_full(fd, write_buffer, buffered) != buffered)
|
||||
if (write_in_full(fd, write_buffer, buffered) < 0)
|
||||
return -1;
|
||||
write_buffer_len = 0;
|
||||
}
|
||||
@ -1971,7 +1971,7 @@ static int ce_flush(git_SHA_CTX *context, int fd, unsigned char *sha1)
|
||||
|
||||
/* Flush first if not enough space for SHA1 signature */
|
||||
if (left + 20 > WRITE_BUFFER_SIZE) {
|
||||
if (write_in_full(fd, write_buffer, left) != left)
|
||||
if (write_in_full(fd, write_buffer, left) < 0)
|
||||
return -1;
|
||||
left = 0;
|
||||
}
|
||||
@ -1980,7 +1980,7 @@ static int ce_flush(git_SHA_CTX *context, int fd, unsigned char *sha1)
|
||||
git_SHA1_Final(write_buffer + left, context);
|
||||
hashcpy(sha1, write_buffer + left);
|
||||
left += 20;
|
||||
return (write_in_full(fd, write_buffer, left) != left) ? -1 : 0;
|
||||
return (write_in_full(fd, write_buffer, left) < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
|
||||
|
2
refs.c
2
refs.c
@ -609,7 +609,7 @@ static int write_pseudoref(const char *pseudoref, const unsigned char *sha1,
|
||||
}
|
||||
}
|
||||
|
||||
if (write_in_full(fd, buf.buf, buf.len) != buf.len) {
|
||||
if (write_in_full(fd, buf.buf, buf.len) < 0) {
|
||||
strbuf_addf(err, "could not write to '%s'", filename);
|
||||
rollback_lock_file(&lock);
|
||||
goto done;
|
||||
|
@ -1549,7 +1549,7 @@ static int log_ref_write_fd(int fd, const struct object_id *old_oid,
|
||||
|
||||
written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
|
||||
free(logrec);
|
||||
if (written != len)
|
||||
if (written < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@ -1628,8 +1628,8 @@ static int write_ref_to_lockfile(struct ref_lock *lock,
|
||||
return -1;
|
||||
}
|
||||
fd = get_lock_file_fd(&lock->lk);
|
||||
if (write_in_full(fd, oid_to_hex(oid), GIT_SHA1_HEXSZ) != GIT_SHA1_HEXSZ ||
|
||||
write_in_full(fd, &term, 1) != 1 ||
|
||||
if (write_in_full(fd, oid_to_hex(oid), GIT_SHA1_HEXSZ) < 0 ||
|
||||
write_in_full(fd, &term, 1) < 0 ||
|
||||
close_ref_gently(lock) < 0) {
|
||||
strbuf_addf(err,
|
||||
"couldn't write '%s'", get_lock_file_path(&lock->lk));
|
||||
@ -3006,8 +3006,8 @@ static int files_reflog_expire(struct ref_store *ref_store,
|
||||
rollback_lock_file(&reflog_lock);
|
||||
} else if (update &&
|
||||
(write_in_full(get_lock_file_fd(&lock->lk),
|
||||
oid_to_hex(&cb.last_kept_oid), GIT_SHA1_HEXSZ) != GIT_SHA1_HEXSZ ||
|
||||
write_str_in_full(get_lock_file_fd(&lock->lk), "\n") != 1 ||
|
||||
oid_to_hex(&cb.last_kept_oid), GIT_SHA1_HEXSZ) < 0 ||
|
||||
write_str_in_full(get_lock_file_fd(&lock->lk), "\n") < 1 ||
|
||||
close_ref_gently(lock) < 0)) {
|
||||
status |= error("couldn't write %s",
|
||||
get_lock_file_path(&lock->lk));
|
||||
|
2
rerere.c
2
rerere.c
@ -258,7 +258,7 @@ static int write_rr(struct string_list *rr, int out_fd)
|
||||
rerere_id_hex(id),
|
||||
rr->items[i].string, 0);
|
||||
|
||||
if (write_in_full(out_fd, buf.buf, buf.len) != buf.len)
|
||||
if (write_in_full(out_fd, buf.buf, buf.len) < 0)
|
||||
die("unable to write rerere record");
|
||||
|
||||
strbuf_release(&buf);
|
||||
|
@ -1850,7 +1850,7 @@ int index_path(struct object_id *oid, const char *path, struct stat *st, unsigne
|
||||
|
||||
int read_pack_header(int fd, struct pack_header *header)
|
||||
{
|
||||
if (read_in_full(fd, header, sizeof(*header)) < sizeof(*header))
|
||||
if (read_in_full(fd, header, sizeof(*header)) != sizeof(*header))
|
||||
/* "eof before pack header was fully read" */
|
||||
return PH_ERROR_EOF;
|
||||
|
||||
|
@ -294,7 +294,7 @@ const char *setup_temporary_shallow(const struct oid_array *extra)
|
||||
if (write_shallow_commits(&sb, 0, extra)) {
|
||||
temp = xmks_tempfile(git_path("shallow_XXXXXX"));
|
||||
|
||||
if (write_in_full(temp->fd, sb.buf, sb.len) != sb.len ||
|
||||
if (write_in_full(temp->fd, sb.buf, sb.len) < 0 ||
|
||||
close_tempfile_gently(temp) < 0)
|
||||
die_errno("failed to write to %s",
|
||||
get_tempfile_path(temp));
|
||||
@ -319,7 +319,7 @@ void setup_alternate_shallow(struct lock_file *shallow_lock,
|
||||
LOCK_DIE_ON_ERROR);
|
||||
check_shallow_file_for_update();
|
||||
if (write_shallow_commits(&sb, 0, extra)) {
|
||||
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
|
||||
if (write_in_full(fd, sb.buf, sb.len) < 0)
|
||||
die_errno("failed to write to %s",
|
||||
get_lock_file_path(shallow_lock));
|
||||
*alternate_shallow_file = get_lock_file_path(shallow_lock);
|
||||
@ -366,7 +366,7 @@ void prune_shallow(int show_only)
|
||||
LOCK_DIE_ON_ERROR);
|
||||
check_shallow_file_for_update();
|
||||
if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
|
||||
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
|
||||
if (write_in_full(fd, sb.buf, sb.len) < 0)
|
||||
die_errno("failed to write to %s",
|
||||
get_lock_file_path(&shallow_lock));
|
||||
commit_lock_file(&shallow_lock);
|
||||
|
@ -540,7 +540,7 @@ int stream_blob_to_fd(int fd, const struct object_id *oid, struct stream_filter
|
||||
kept = 0;
|
||||
wrote = write_in_full(fd, buf, readlen);
|
||||
|
||||
if (wrote != readlen)
|
||||
if (wrote < 0)
|
||||
goto close_and_exit;
|
||||
}
|
||||
if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||
|
||||
|
@ -69,7 +69,7 @@ int cmd_main(int argc, const char **argv)
|
||||
}
|
||||
|
||||
fd = open (argv[4], O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
||||
if (fd < 0 || write_in_full(fd, out_buf, out_size) != out_size) {
|
||||
if (fd < 0 || write_in_full(fd, out_buf, out_size) < 0) {
|
||||
perror(argv[4]);
|
||||
return 1;
|
||||
}
|
||||
|
@ -44,8 +44,7 @@ static void sendline(struct helper_data *helper, struct strbuf *buffer)
|
||||
{
|
||||
if (debug)
|
||||
fprintf(stderr, "Debug: Remote helper: -> %s", buffer->buf);
|
||||
if (write_in_full(helper->helper->in, buffer->buf, buffer->len)
|
||||
!= buffer->len)
|
||||
if (write_in_full(helper->helper->in, buffer->buf, buffer->len) < 0)
|
||||
die_errno("Full write to remote helper failed");
|
||||
}
|
||||
|
||||
@ -74,7 +73,7 @@ static void write_constant(int fd, const char *str)
|
||||
{
|
||||
if (debug)
|
||||
fprintf(stderr, "Debug: Remote helper: -> %s", str);
|
||||
if (write_in_full(fd, str, strlen(str)) != strlen(str))
|
||||
if (write_in_full(fd, str, strlen(str)) < 0)
|
||||
die_errno("Full write to remote helper failed");
|
||||
}
|
||||
|
||||
|
@ -652,7 +652,7 @@ int xsnprintf(char *dst, size_t max, const char *fmt, ...)
|
||||
void write_file_buf(const char *path, const char *buf, size_t len)
|
||||
{
|
||||
int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (write_in_full(fd, buf, len) != len)
|
||||
if (write_in_full(fd, buf, len) < 0)
|
||||
die_errno(_("could not write to %s"), path);
|
||||
if (close(fd))
|
||||
die_errno(_("could not close %s"), path);
|
||||
|
Loading…
Reference in New Issue
Block a user