From c70a582e5ef7a381814fcac3437751e6fbe36088 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Tue, 14 Sep 2010 17:47:00 +0200 Subject: [PATCH] Handle EINTR correctly --- NEWS.txt | 2 ++ hash.c | 9 +++++++-- util.c | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/NEWS.txt b/NEWS.txt index 8f97df500..20a1ca4c9 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -55,6 +55,8 @@ Bug fixes - Made `--ccache-skip` work for all options. + - EINTR is now handled correctly. + Other ~~~~~ diff --git a/hash.c b/hash.c index bcc012ac9..b6a9e5ea2 100644 --- a/hash.c +++ b/hash.c @@ -99,8 +99,13 @@ hash_fd(struct mdfour *md, int fd) char buf[16384]; ssize_t n; - while ((n = read(fd, buf, sizeof(buf))) > 0) { - hash_buffer(md, buf, n); + while ((n = read(fd, buf, sizeof(buf))) != 0) { + if (n == -1 && errno != EINTR) { + break; + } + if (n > 0) { + hash_buffer(md, buf, n); + } } return n == 0; } diff --git a/util.c b/util.c index ff6ff1517..491732836 100644 --- a/util.c +++ b/util.c @@ -146,9 +146,14 @@ copy_fd(int fd_in, int fd_out) } while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) { - if (write(fd_out, buf, n) != n) { - fatal("Failed to copy fd"); - } + ssize_t count, written = 0; + do { + count = write(fd_out, buf + written, n - written); + if (count == -1 && errno != EINTR) { + fatal("Failed to copy fd"); + } + written += count; + } while (written < n); } gzclose(gz_in); @@ -174,7 +179,7 @@ copy_file(const char *src, const char *dest, int compress_dest) int fd_in = -1, fd_out = -1; gzFile gz_in = NULL, gz_out = NULL; char buf[10240]; - int n, ret; + int n, written; char *tmp_name; #ifndef _WIN32 mode_t mask; @@ -232,11 +237,19 @@ copy_file(const char *src, const char *dest, int compress_dest) while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) { if (compress_dest) { - ret = gzwrite(gz_out, buf, n); + written = gzwrite(gz_out, buf, n); } else { - ret = write(fd_out, buf, n); + ssize_t count; + written = 0; + do { + count = write(fd_out, buf + written, n - written); + if (count == -1 && errno != EINTR) { + break; + } + written += count; + } while (written < n); } - if (ret != n) { + if (written != n) { if (compress_dest) { cc_log("gzwrite error: %s (errno: %s)", gzerror(gz_in, &errnum), @@ -1093,13 +1106,19 @@ read_file(const char *path, size_t size_hint, char **data, size_t *size) allocated = size_hint; *data = x_malloc(allocated); ret = 0; - do { - pos += ret; + while (true) { if (pos > allocated / 2) { allocated *= 2; *data = x_realloc(*data, allocated); } - } while ((ret = read(fd, *data + pos, allocated - pos)) > 0); + ret = read(fd, *data + pos, allocated - pos); + if (ret == 0 || (ret == -1 && errno != EINTR)) { + break; + } + if (ret > 0) { + pos += ret; + } + } close(fd); if (ret == -1) { cc_log("Failed reading %s", path); -- 2.47.2