summaryrefslogtreecommitdiff
path: root/write_or_die.c
diff options
context:
space:
mode:
authorAndy Whitcroft <apw@shadowen.org>2007-01-08 15:58:08 +0000
committerJunio C Hamano <junkio@cox.net>2007-01-08 15:44:47 -0800
commit93d26e4cb9cec2eb8abb4f37e6dda2c86fcceeac (patch)
tree8d3cda91ddd8242531995cb304f37578bfaa7cf0 /write_or_die.c
parente08140568a131bcd26e64a0bc8188040847be998 (diff)
downloadgit-93d26e4cb9cec2eb8abb4f37e6dda2c86fcceeac.tar.gz
short i/o: fix calls to read to use xread or read_in_full
We have a number of badly checked read() calls. Often we are expecting read() to read exactly the size we requested or fail, this fails to handle interrupts or short reads. Add a read_in_full() providing those semantics. Otherwise we at a minimum need to check for EINTR and EAGAIN, where this is appropriate use xread(). Signed-off-by: Andy Whitcroft <apw@shadowen.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'write_or_die.c')
-rw-r--r--write_or_die.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/write_or_die.c b/write_or_die.c
index 613c0c3f6e..e7f82639ff 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -1,19 +1,36 @@
#include "cache.h"
-void read_or_die(int fd, void *buf, size_t count)
+int read_in_full(int fd, void *buf, size_t count)
{
char *p = buf;
- ssize_t loaded;
+ ssize_t total = 0;
+ ssize_t loaded = 0;
while (count > 0) {
loaded = xread(fd, p, count);
- if (loaded == 0)
- die("unexpected end of file");
- else if (loaded < 0)
- die("read error (%s)", strerror(errno));
+ if (loaded <= 0) {
+ if (total)
+ return total;
+ else
+ return loaded;
+ }
count -= loaded;
p += loaded;
+ total += loaded;
}
+
+ return total;
+}
+
+void read_or_die(int fd, void *buf, size_t count)
+{
+ ssize_t loaded;
+
+ loaded = read_in_full(fd, buf, count);
+ if (loaded == 0)
+ die("unexpected end of file");
+ else if (loaded < 0)
+ die("read error (%s)", strerror(errno));
}
void write_or_die(int fd, const void *buf, size_t count)