git-commit-vandalism/write_or_die.c
Andy Whitcroft 93822c2239 short i/o: fix calls to write to use xwrite or write_in_full
We have a number of badly checked write() calls.  Often we are
expecting write() to write exactly the size we requested or fail,
this fails to handle interrupts or short writes.  Switch to using
the new write_in_full().  Otherwise we at a minimum need to check
for EINTR and EAGAIN, where this is appropriate use xwrite().

Note, the changes to config handling are much larger and handled
in the next patch in the sequence.

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-08 15:44:47 -08:00

109 lines
1.9 KiB
C

#include "cache.h"
int read_in_full(int fd, void *buf, size_t count)
{
char *p = buf;
ssize_t total = 0;
ssize_t loaded = 0;
while (count > 0) {
loaded = xread(fd, p, count);
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));
}
int write_in_full(int fd, const void *buf, size_t count)
{
const char *p = buf;
ssize_t total = 0;
ssize_t written = 0;
while (count > 0) {
written = xwrite(fd, p, count);
if (written <= 0) {
if (total)
return total;
else
return written;
}
count -= written;
p += written;
total += written;
}
return total;
}
void write_or_die(int fd, const void *buf, size_t count)
{
ssize_t written;
written = write_in_full(fd, buf, count);
if (written == 0)
die("disk full?");
else if (written < 0) {
if (errno == EPIPE)
exit(0);
die("write error (%s)", strerror(errno));
}
}
int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg)
{
ssize_t written;
written = write_in_full(fd, buf, count);
if (written == 0) {
fprintf(stderr, "%s: disk full?\n", msg);
return 0;
}
else if (written < 0) {
if (errno == EPIPE)
exit(0);
fprintf(stderr, "%s: write error (%s)\n",
msg, strerror(errno));
return 0;
}
return 1;
}
int write_or_whine(int fd, const void *buf, size_t count, const char *msg)
{
ssize_t written;
written = write_in_full(fd, buf, count);
if (written == 0) {
fprintf(stderr, "%s: disk full?\n", msg);
return 0;
}
else if (written < 0) {
fprintf(stderr, "%s: write error (%s)\n",
msg, strerror(errno));
return 0;
}
return 1;
}