Skip to content

Commit 7230e6d

Browse files
Rene ScharfeJunio C Hamano
authored andcommitted
Add write_or_die(), a helper function
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3f0073a commit 7230e6d

File tree

5 files changed

+32
-46
lines changed

5 files changed

+32
-46
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ LIB_OBJS = \
248248
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
249249
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
250250
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
251+
write_or_die.o \
251252
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS)
252253

253254
BUILTIN_OBJS = \

builtin-cat-file.c

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,6 @@
99
#include "tree.h"
1010
#include "builtin.h"
1111

12-
static void flush_buffer(const char *buf, unsigned long size)
13-
{
14-
while (size > 0) {
15-
long ret = xwrite(1, buf, size);
16-
if (ret < 0) {
17-
/* Ignore epipe */
18-
if (errno == EPIPE)
19-
break;
20-
die("git-cat-file: %s", strerror(errno));
21-
} else if (!ret) {
22-
die("git-cat-file: disk full?");
23-
}
24-
size -= ret;
25-
buf += ret;
26-
}
27-
}
28-
2912
static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long size)
3013
{
3114
/* the parser in tag.c is useless here. */
@@ -42,7 +25,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
4225
/* Found the tagger line. Copy out the contents
4326
* of the buffer so far.
4427
*/
45-
flush_buffer(buf, cp - buf);
28+
write_or_die(1, buf, cp - buf);
4629

4730
/*
4831
* Do something intelligent, like pretty-printing
@@ -61,18 +44,18 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
6144
sp++;
6245
if (sp == cp) {
6346
/* give up */
64-
flush_buffer(tagger,
47+
write_or_die(1, tagger,
6548
cp - tagger);
6649
break;
6750
}
6851
while (sp < cp &&
6952
!('0' <= *sp && *sp <= '9'))
7053
sp++;
71-
flush_buffer(tagger, sp - tagger);
54+
write_or_die(1, tagger, sp - tagger);
7255
date = strtoul(sp, &ep, 10);
7356
tz = strtol(ep, NULL, 10);
7457
sp = show_date(date, tz);
75-
flush_buffer(sp, strlen(sp));
58+
write_or_die(1, sp, strlen(sp));
7659
xwrite(1, "\n", 1);
7760
break;
7861
}
@@ -90,7 +73,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
9073
* remainder as is.
9174
*/
9275
if (cp < endp)
93-
flush_buffer(cp, endp - cp);
76+
write_or_die(1, cp, endp - cp);
9477
}
9578

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

165-
flush_buffer(buf, size);
148+
write_or_die(1, buf, size);
166149
return 0;
167150
}

builtin-tar-tree.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,11 @@ static unsigned long offset;
2222
static time_t archive_time;
2323
static int tar_umask;
2424

25-
/* tries hard to write, either succeeds or dies in the attempt */
26-
static void reliable_write(const void *data, unsigned long size)
27-
{
28-
const char *buf = data;
29-
30-
while (size > 0) {
31-
long ret = xwrite(1, buf, size);
32-
if (ret < 0) {
33-
if (errno == EPIPE)
34-
exit(0);
35-
die("git-tar-tree: %s", strerror(errno));
36-
} else if (!ret) {
37-
die("git-tar-tree: disk full?");
38-
}
39-
size -= ret;
40-
buf += ret;
41-
}
42-
}
43-
4425
/* writes out the whole block, but only if it is full */
4526
static void write_if_needed(void)
4627
{
4728
if (offset == BLOCKSIZE) {
48-
reliable_write(block, BLOCKSIZE);
29+
write_or_die(1, block, BLOCKSIZE);
4930
offset = 0;
5031
}
5132
}
@@ -70,7 +51,7 @@ static void write_blocked(const void *data, unsigned long size)
7051
write_if_needed();
7152
}
7253
while (size >= BLOCKSIZE) {
73-
reliable_write(buf, BLOCKSIZE);
54+
write_or_die(1, buf, BLOCKSIZE);
7455
size -= BLOCKSIZE;
7556
buf += BLOCKSIZE;
7657
}
@@ -94,10 +75,10 @@ static void write_trailer(void)
9475
{
9576
int tail = BLOCKSIZE - offset;
9677
memset(block + offset, 0, tail);
97-
reliable_write(block, BLOCKSIZE);
78+
write_or_die(1, block, BLOCKSIZE);
9879
if (tail < 2 * RECORDSIZE) {
9980
memset(block, 0, offset);
100-
reliable_write(block, BLOCKSIZE);
81+
write_or_die(1, block, BLOCKSIZE);
10182
}
10283
}
10384

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ extern char git_default_name[MAX_GITNAME];
388388
extern char git_commit_encoding[MAX_ENCODING_LENGTH];
389389

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

392393
/* Finish off pack transfer receiving end */
393394
extern int receive_unpack_pack(int fd[2], const char *me, int quiet, int);

write_or_die.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "cache.h"
2+
3+
void write_or_die(int fd, const void *buf, size_t count)
4+
{
5+
const char *p = buf;
6+
ssize_t written;
7+
8+
while (count > 0) {
9+
written = xwrite(fd, p, count);
10+
if (written == 0)
11+
die("disk full?");
12+
else if (written < 0) {
13+
if (errno == EPIPE)
14+
exit(0);
15+
die("write error (%s)", strerror(errno));
16+
}
17+
count -= written;
18+
p += written;
19+
}
20+
}

0 commit comments

Comments
 (0)