distinguish error versus short read from read_in_full()

Many callers of read_in_full() expect to see the exact number of bytes requested, but their error handling lumps together true read errors and short reads due to unexpected EOF. We can give more specific error messages by separating these cases (showing errno when appropriate, and otherwise describing the short read). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Sep 27, 2017 at 02:02 UTC 41dcc4dcccecca49e3f75212ce9e614ffe2bdcc8
3 files changed +16 -4
builtin/get-tar-commit-id.c
+3 -1
@@ -26,8 +26,10 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
26 usage(builtin_get_tar_commit_id_usage);
27
28 n = read_in_full(0, buffer, HEADERSIZE);
29 + if (n < 0)
30 + die_errno("git get-tar-commit-id: read error");
31 if (n != HEADERSIZE)
30 - die("git get-tar-commit-id: read error");
32 + die_errno("git get-tar-commit-id: EOF before reading tar header");
33 if (header->typeflag[0] != 'g')
34 return 1;
35 if (!skip_prefix(content, "52 comment=", &comment))
bulk-checkin.c
+4 -1
@@ -115,7 +115,10 @@ static int stream_to_pack(struct bulk_checkin_state *state,
115
116 if (size && !s.avail_in) {
117 ssize_t rsize = size < sizeof(ibuf) ? size : sizeof(ibuf);
118 - if (read_in_full(fd, ibuf, rsize) != rsize)
118 + ssize_t read_result = read_in_full(fd, ibuf, rsize);
119 + if (read_result < 0)
120 + die_errno("failed to read from '%s'", path);
121 + if (read_result != rsize)
122 die("failed to read %d bytes from '%s'",
123 (int)rsize, path);
124 offset += rsize;
packfile.c
+9 -2
@@ -444,6 +444,7 @@ static int open_packed_git_1(struct packed_git *p)
444 unsigned char sha1[20];
445 unsigned char *idx_sha1;
446 long fd_flag;
447 + ssize_t read_result;
448
449 if (!p->index_data && open_pack_index(p))
450 return error("packfile %s index unavailable", p->pack_name);
@@ -485,7 +486,10 @@ static int open_packed_git_1(struct packed_git *p)
486 return error("cannot set FD_CLOEXEC");
487
488 /* Verify we recognize this pack file format. */
488 - if (read_in_full(p->pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
489 + read_result = read_in_full(p->pack_fd, &hdr, sizeof(hdr));
490 + if (read_result < 0)
491 + return error_errno("error reading from %s", p->pack_name);
492 + if (read_result != sizeof(hdr))
493 return error("file %s is far too short to be a packfile", p->pack_name);
494 if (hdr.hdr_signature != htonl(PACK_SIGNATURE))
495 return error("file %s is not a GIT packfile", p->pack_name);
@@ -502,7 +506,10 @@ static int open_packed_git_1(struct packed_git *p)
506 p->num_objects);
507 if (lseek(p->pack_fd, p->pack_size - sizeof(sha1), SEEK_SET) == -1)
508 return error("end of packfile %s is unavailable", p->pack_name);
505 - if (read_in_full(p->pack_fd, sha1, sizeof(sha1)) != sizeof(sha1))
509 + read_result = read_in_full(p->pack_fd, sha1, sizeof(sha1));
510 + if (read_result < 0)
511 + return error_errno("error reading from %s", p->pack_name);
512 + if (read_result != sizeof(sha1))
513 return error("packfile %s signature is unavailable", p->pack_name);
514 idx_sha1 = ((unsigned char *)p->index_data) + p->index_size - 40;
515 if (hashcmp(sha1, idx_sha1))