summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e081405)
raw | patch | inline | side by side (parent: e081405)
author | Andy Whitcroft <apw@shadowen.org> | |
Mon, 8 Jan 2007 15:58:08 +0000 (15:58 +0000) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Mon, 8 Jan 2007 23:44:47 +0000 (15:44 -0800) |
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>
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>
17 files changed:
builtin-grep.c | patch | blob | history | |
builtin-tar-tree.c | patch | blob | history | |
builtin-upload-archive.c | patch | blob | history | |
cache.h | patch | blob | history | |
dir.c | patch | blob | history | |
http-fetch.c | patch | blob | history | |
http-push.c | patch | blob | history | |
imap-send.c | patch | blob | history | |
index-pack.c | patch | blob | history | |
local-fetch.c | patch | blob | history | |
path.c | patch | blob | history | |
refs.c | patch | blob | history | |
sha1_file.c | patch | blob | history | |
ssh-fetch.c | patch | blob | history | |
ssh-upload.c | patch | blob | history | |
upload-pack.c | patch | blob | history | |
write_or_die.c | patch | blob | history |
diff --git a/builtin-grep.c b/builtin-grep.c
index 3b1b1cbbfa7bf348c17c025afa217ffff97087e3..2bfbdb71407dcd0ddfe970f6a614158d954cd4c0 100644 (file)
--- a/builtin-grep.c
+++ b/builtin-grep.c
if (i < 0)
goto err_ret;
data = xmalloc(st.st_size + 1);
- if (st.st_size != xread(i, data, st.st_size)) {
+ if (st.st_size != read_in_full(i, data, st.st_size)) {
error("'%s': short read %s", filename, strerror(errno));
close(i);
free(data);
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index 11e62fc141f592977373630c7671d3e7e914c314..ad802fc1aa7fe2b487b2ffdac68f27df82ebc941 100644 (file)
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
char *content = buffer + RECORDSIZE;
ssize_t n;
- n = xread(0, buffer, HEADERSIZE);
+ n = read_in_full(0, buffer, HEADERSIZE);
if (n < HEADERSIZE)
die("git-get-tar-commit-id: read error");
if (header->typeflag[0] != 'g')
index e4156f8f48aeed307b1754bada173034dd81a311..48ae09e9b5268ce1f11cfba433680a147ca39f7e 100644 (file)
--- a/builtin-upload-archive.c
+++ b/builtin-upload-archive.c
char buf[16384];
ssize_t sz = read(child_fd, buf, sizeof(buf));
if (sz < 0) {
- if (errno != EINTR)
+ if (errno != EAGAIN && errno != EINTR)
error_clnt("read error: %s\n", strerror(errno));
return;
}
index 38a20a806950752f0449cf244e06149d5d5aca51..a9583ff18eec46bf945ef820ea4a41fe51e0a4b1 100644 (file)
--- a/cache.h
+++ b/cache.h
extern char *git_log_output_encoding;
extern int copy_fd(int ifd, int ofd);
+extern int read_in_full(int fd, void *buf, size_t count);
extern void read_or_die(int fd, void *buf, size_t count);
extern int write_in_full(int fd, const void *buf, size_t count);
extern void write_or_die(int fd, const void *buf, size_t count);
index 0338d6c4e0ab4409d6023db96f5298d292692099..32b57f0125d1b9e95345eb23a9a32fbf8444b1b8 100644 (file)
--- a/dir.c
+++ b/dir.c
return 0;
}
buf = xmalloc(size+1);
- if (read(fd, buf, size) != size)
+ if (read_in_full(fd, buf, size) != size)
goto err;
close(fd);
diff --git a/http-fetch.c b/http-fetch.c
index 396552da022a1dca9c43738be4d87c664f31a06c..50a3b005ab65b422d9d02010c75c5ecdc115f034 100644 (file)
--- a/http-fetch.c
+++ b/http-fetch.c
prevlocal = open(prevfile, O_RDONLY);
if (prevlocal != -1) {
do {
- prev_read = read(prevlocal, prev_buf, PREV_BUF_SIZE);
+ prev_read = xread(prevlocal, prev_buf, PREV_BUF_SIZE);
if (prev_read>0) {
if (fwrite_sha1_file(prev_buf,
1,
diff --git a/http-push.c b/http-push.c
index ecefdfd4f8c9c17282f5cec10640343359278028..acb5c273aaf6fc5527fe0d4b326344064fcfa62e 100644 (file)
--- a/http-push.c
+++ b/http-push.c
prevlocal = open(prevfile, O_RDONLY);
if (prevlocal != -1) {
do {
- prev_read = read(prevlocal, prev_buf, PREV_BUF_SIZE);
+ prev_read = xread(prevlocal, prev_buf, PREV_BUF_SIZE);
if (prev_read>0) {
if (fwrite_sha1_file(prev_buf,
1,
diff --git a/imap-send.c b/imap-send.c
index ad91858bc43d046ea199f5a52c372b2a243c647f..8de19e3cc667dd08db529a874d59614183c8dbb7 100644 (file)
--- a/imap-send.c
+++ b/imap-send.c
static int
socket_read( Socket_t *sock, char *buf, int len )
{
- int n = read( sock->fd, buf, len );
+ int n = xread( sock->fd, buf, len );
if (n <= 0) {
socket_perror( "read", sock, n );
close( sock->fd );
fprintf( stderr, "Fatal: no random number source available.\n" );
exit( 3 );
}
- if (read( fd, dat, 128 ) != 128) {
+ if (read_in_full( fd, dat, 128 ) != 128) {
fprintf( stderr, "Fatal: cannot read random number source.\n" );
exit( 3 );
}
diff --git a/index-pack.c b/index-pack.c
index 5f6d128a836f8ed9447f81280ae679e19c9939ff..e9a53032226edd5663458031734c135afb5db0ef 100644 (file)
--- a/index-pack.c
+++ b/index-pack.c
/* Rewrite pack header with updated object number */
if (lseek(output_fd, 0, SEEK_SET) != 0)
die("cannot seek back: %s", strerror(errno));
- if (xread(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
+ if (read_in_full(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
die("cannot read pack header back: %s", strerror(errno));
hdr.hdr_entries = htonl(nr_objects);
if (lseek(output_fd, 0, SEEK_SET) != 0)
diff --git a/local-fetch.c b/local-fetch.c
index 7b6875cce6c5a08db06e637abc48ce8f26216db4..cf99cb72dd48f65a8c3dd1606b77334f79afab8f 100644 (file)
--- a/local-fetch.c
+++ b/local-fetch.c
fprintf(stderr, "cannot open %s\n", filename);
return -1;
}
- if (read(ifd, hex, 40) != 40 || get_sha1_hex(hex, sha1)) {
+ if (read_in_full(ifd, hex, 40) != 40 || get_sha1_hex(hex, sha1)) {
close(ifd);
fprintf(stderr, "cannot read from %s\n", filename);
return -1;
index 066f62195508033a5f72504e4805ea436424296e..bb5ee7bf99780b6c4069dd9833994b24f1577e82 100644 (file)
--- a/path.c
+++ b/path.c
fd = open(path, O_RDONLY);
if (fd < 0)
return -1;
- len = read(fd, buffer, sizeof(buffer)-1);
+ len = read_in_full(fd, buffer, sizeof(buffer)-1);
close(fd);
/*
index 52057455a20cb4641005c9248b5499cca83c77c1..2b69e1eddc01fc87ea18e22960184f57b5590dcc 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -284,7 +284,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
fd = open(path, O_RDONLY);
if (fd < 0)
return NULL;
- len = read(fd, buffer, sizeof(buffer)-1);
+ len = read_in_full(fd, buffer, sizeof(buffer)-1);
close(fd);
/*
diff --git a/sha1_file.c b/sha1_file.c
index d9622d95e7e3d7b91982ae60dbc36a7996856682..0c9483c5c0ddf2e99dd6d1b556ce5cf52c4bab30 100644 (file)
--- a/sha1_file.c
+++ b/sha1_file.c
if (ret != Z_OK)
break;
}
- size = read(fd, buffer + *bufposn, bufsize - *bufposn);
+ size = xread(fd, buffer + *bufposn, bufsize - *bufposn);
if (size <= 0) {
close(local);
unlink(tmpfile);
diff --git a/ssh-fetch.c b/ssh-fetch.c
index b006c5c9802d96bc504188e10a9698a1f943477c..72965d678ae4e4b2b2fc64e8979d8a9e1d3d81d0 100644 (file)
--- a/ssh-fetch.c
+++ b/ssh-fetch.c
remote = conn_buf[0];
memmove(conn_buf, conn_buf + 1, --conn_buf_posn);
} else {
- if (read(fd_in, &remote, 1) < 1)
+ if (xread(fd_in, &remote, 1) < 1)
return -1;
}
/* fprintf(stderr, "Got %d\n", remote); */
char type = 'v';
write(fd_out, &type, 1);
write(fd_out, &local_version, 1);
- if (read(fd_in, &remote_version, 1) < 1) {
+ if (xread(fd_in, &remote_version, 1) < 1) {
return error("Couldn't read version from remote end");
}
return 0;
char type = 'r';
write(fd_out, &type, 1);
write(fd_out, ref, strlen(ref) + 1);
- read(fd_in, &remote, 1);
+
+ if (read_in_full(fd_in, &remote, 1) != 1)
+ return -1;
if (remote < 0)
return remote;
- read(fd_in, sha1, 20);
+ if (read_in_full(fd_in, sha1, 20) != 20)
+ return -1;
return 0;
}
diff --git a/ssh-upload.c b/ssh-upload.c
index 901e0366df25f23530e68237eabe59891a5b78d7..86b169bf4fb7712327b72d8e57e25248f9572954 100644 (file)
--- a/ssh-upload.c
+++ b/ssh-upload.c
ssize_t size;
unsigned char sha1[20];
signed char remote;
- int posn = 0;
- do {
- size = read(fd_in, sha1 + posn, 20 - posn);
- if (size < 0) {
- perror("git-ssh-upload: read ");
- return -1;
- }
- if (!size)
- return -1;
- posn += size;
- } while (posn < 20);
+
+ size = read_in_full(fd_in, sha1, 20);
+ if (size < 0) {
+ perror("git-ssh-upload: read ");
+ return -1;
+ }
+ if (!size)
+ return -1;
if (verbose)
fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1));
static int serve_version(int fd_in, int fd_out)
{
- if (read(fd_in, &remote_version, 1) < 1)
+ if (xread(fd_in, &remote_version, 1) < 1)
return -1;
write(fd_out, &local_version, 1);
return 0;
int posn = 0;
signed char remote = 0;
do {
- if (posn >= PATH_MAX || read(fd_in, ref + posn, 1) < 1)
+ if (posn >= PATH_MAX || xread(fd_in, ref + posn, 1) < 1)
return -1;
posn++;
} while (ref[posn - 1]);
char type;
int retval;
do {
- retval = read(fd_in, &type, 1);
+ retval = xread(fd_in, &type, 1);
if (retval < 1) {
if (retval < 0)
perror("git-ssh-upload: read ");
diff --git a/upload-pack.c b/upload-pack.c
index c568ef066c9e7e0021468cfe7cb904f40ac477f1..03a4156e19655c1f1d724163d0a712f63fc72c6e 100644 (file)
--- a/upload-pack.c
+++ b/upload-pack.c
*cp++ = buffered;
outsz++;
}
- sz = read(pu_pipe[0], cp,
+ sz = xread(pu_pipe[0], cp,
sizeof(data) - outsz);
if (0 < sz)
;
/* Status ready; we ship that in the side-band
* or dump to the standard error.
*/
- sz = read(pe_pipe[0], progress,
+ sz = xread(pe_pipe[0], progress,
sizeof(progress));
if (0 < sz)
send_client_data(2, progress, sz);
diff --git a/write_or_die.c b/write_or_die.c
index 613c0c3f6e90cc6a1b7ae9c0ade4e5c10dc25029..e7f82639ffb068dd754855ca464a20721a36c9db 100644 (file)
--- a/write_or_die.c
+++ b/write_or_die.c
#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)