From 93d26e4cb9cec2eb8abb4f37e6dda2c86fcceeac Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Mon, 8 Jan 2007 15:58:08 +0000 Subject: 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 Signed-off-by: Junio C Hamano --- ssh-fetch.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'ssh-fetch.c') diff --git a/ssh-fetch.c b/ssh-fetch.c index b006c5c980..72965d678a 100644 --- a/ssh-fetch.c +++ b/ssh-fetch.c @@ -82,7 +82,7 @@ int fetch(unsigned char *sha1) 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); */ @@ -99,7 +99,7 @@ static int get_version(void) 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; @@ -111,10 +111,13 @@ int fetch_ref(char *ref, unsigned char *sha1) 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; } -- cgit v1.2.3 From 93822c2239a336e5cb583549071c59202ef6c5b2 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Mon, 8 Jan 2007 15:58:23 +0000 Subject: 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 Signed-off-by: Junio C Hamano --- ssh-fetch.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) (limited to 'ssh-fetch.c') diff --git a/ssh-fetch.c b/ssh-fetch.c index 72965d678a..4c172b6824 100644 --- a/ssh-fetch.c +++ b/ssh-fetch.c @@ -20,22 +20,6 @@ static int fd_out; static unsigned char remote_version; static unsigned char local_version = 1; -static ssize_t force_write(int fd, void *buffer, size_t length) -{ - ssize_t ret = 0; - while (ret < length) { - ssize_t size = write(fd, (char *) buffer + ret, length - ret); - if (size < 0) { - return size; - } - if (size == 0) { - return ret; - } - ret += size; - } - return ret; -} - static int prefetches; static struct object_list *in_transit; @@ -53,8 +37,9 @@ void prefetch(unsigned char *sha1) node->item = lookup_unknown_object(sha1); *end_of_transit = node; end_of_transit = &node->next; - force_write(fd_out, &type, 1); - force_write(fd_out, sha1, 20); + /* XXX: what if these writes fail? */ + write_in_full(fd_out, &type, 1); + write_in_full(fd_out, sha1, 20); prefetches++; } @@ -97,8 +82,10 @@ int fetch(unsigned char *sha1) static int get_version(void) { char type = 'v'; - write(fd_out, &type, 1); - write(fd_out, &local_version, 1); + if (write_in_full(fd_out, &type, 1) != 1 || + write_in_full(fd_out, &local_version, 1)) { + return error("Couldn't request version from remote end"); + } if (xread(fd_in, &remote_version, 1) < 1) { return error("Couldn't read version from remote end"); } @@ -109,8 +96,10 @@ int fetch_ref(char *ref, unsigned char *sha1) { signed char remote; char type = 'r'; - write(fd_out, &type, 1); - write(fd_out, ref, strlen(ref) + 1); + int length = strlen(ref) + 1; + if (write_in_full(fd_out, &type, 1) != 1 || + write_in_full(fd_out, ref, length) != length) + return -1; if (read_in_full(fd_in, &remote, 1) != 1) return -1; -- cgit v1.2.3