Skip to content

Commit

Permalink
Add write_or_die(), a helper function
Browse files Browse the repository at this point in the history
The little helper write_or_die() won't come back with bad news about
full disks or broken pipes.  It either succeeds or terminates the
program, making additional error handling unnecessary.

This patch adds the new function and uses it to replace two similar
ones (the one in tar-tree originally has been copied from cat-file
btw.).  I chose to add the fd parameter which both lacked to make
write_or_die() just as flexible as write() and thus suitable for
lib-ification.

There is a regression: error messages emitted by this function don't
show the program name, while the replaced two functions did.  That's
acceptable, I think; a lot of other functions do the same.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Rene Scharfe authored and Junio C Hamano committed Aug 22, 2006
1 parent 3f0073a commit 7230e6d
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 46 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ LIB_OBJS = \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
write_or_die.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS)

BUILTIN_OBJS = \
Expand Down
29 changes: 6 additions & 23 deletions builtin-cat-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,6 @@
#include "tree.h"
#include "builtin.h"

static void flush_buffer(const char *buf, unsigned long size)
{
while (size > 0) {
long ret = xwrite(1, buf, size);
if (ret < 0) {
/* Ignore epipe */
if (errno == EPIPE)
break;
die("git-cat-file: %s", strerror(errno));
} else if (!ret) {
die("git-cat-file: disk full?");
}
size -= ret;
buf += ret;
}
}

static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long size)
{
/* the parser in tag.c is useless here. */
Expand All @@ -42,7 +25,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
/* Found the tagger line. Copy out the contents
* of the buffer so far.
*/
flush_buffer(buf, cp - buf);
write_or_die(1, buf, cp - buf);

/*
* Do something intelligent, like pretty-printing
Expand All @@ -61,18 +44,18 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
sp++;
if (sp == cp) {
/* give up */
flush_buffer(tagger,
write_or_die(1, tagger,
cp - tagger);
break;
}
while (sp < cp &&
!('0' <= *sp && *sp <= '9'))
sp++;
flush_buffer(tagger, sp - tagger);
write_or_die(1, tagger, sp - tagger);
date = strtoul(sp, &ep, 10);
tz = strtol(ep, NULL, 10);
sp = show_date(date, tz);
flush_buffer(sp, strlen(sp));
write_or_die(1, sp, strlen(sp));
xwrite(1, "\n", 1);
break;
}
Expand All @@ -90,7 +73,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
* remainder as is.
*/
if (cp < endp)
flush_buffer(cp, endp - cp);
write_or_die(1, cp, endp - cp);
}

int cmd_cat_file(int argc, const char **argv, const char *prefix)
Expand Down Expand Up @@ -162,6 +145,6 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
if (!buf)
die("git-cat-file %s: bad file", argv[2]);

flush_buffer(buf, size);
write_or_die(1, buf, size);
return 0;
}
27 changes: 4 additions & 23 deletions builtin-tar-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,11 @@ static unsigned long offset;
static time_t archive_time;
static int tar_umask;

/* tries hard to write, either succeeds or dies in the attempt */
static void reliable_write(const void *data, unsigned long size)
{
const char *buf = data;

while (size > 0) {
long ret = xwrite(1, buf, size);
if (ret < 0) {
if (errno == EPIPE)
exit(0);
die("git-tar-tree: %s", strerror(errno));
} else if (!ret) {
die("git-tar-tree: disk full?");
}
size -= ret;
buf += ret;
}
}

/* writes out the whole block, but only if it is full */
static void write_if_needed(void)
{
if (offset == BLOCKSIZE) {
reliable_write(block, BLOCKSIZE);
write_or_die(1, block, BLOCKSIZE);
offset = 0;
}
}
Expand All @@ -70,7 +51,7 @@ static void write_blocked(const void *data, unsigned long size)
write_if_needed();
}
while (size >= BLOCKSIZE) {
reliable_write(buf, BLOCKSIZE);
write_or_die(1, buf, BLOCKSIZE);
size -= BLOCKSIZE;
buf += BLOCKSIZE;
}
Expand All @@ -94,10 +75,10 @@ static void write_trailer(void)
{
int tail = BLOCKSIZE - offset;
memset(block + offset, 0, tail);
reliable_write(block, BLOCKSIZE);
write_or_die(1, block, BLOCKSIZE);
if (tail < 2 * RECORDSIZE) {
memset(block, 0, offset);
reliable_write(block, BLOCKSIZE);
write_or_die(1, block, BLOCKSIZE);
}
}

Expand Down
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ extern char git_default_name[MAX_GITNAME];
extern char git_commit_encoding[MAX_ENCODING_LENGTH];

extern int copy_fd(int ifd, int ofd);
extern void write_or_die(int fd, const void *buf, size_t count);

/* Finish off pack transfer receiving end */
extern int receive_unpack_pack(int fd[2], const char *me, int quiet, int);
Expand Down
20 changes: 20 additions & 0 deletions write_or_die.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "cache.h"

void write_or_die(int fd, const void *buf, size_t count)
{
const char *p = buf;
ssize_t written;

while (count > 0) {
written = xwrite(fd, p, count);
if (written == 0)
die("disk full?");
else if (written < 0) {
if (errno == EPIPE)
exit(0);
die("write error (%s)", strerror(errno));
}
count -= written;
p += written;
}
}

0 comments on commit 7230e6d

Please sign in to comment.