]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Handle EINTR correctly
authorJoel Rosdahl <joel@rosdahl.net>
Tue, 14 Sep 2010 15:47:00 +0000 (17:47 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 15 Sep 2010 06:34:52 +0000 (08:34 +0200)
NEWS.txt
hash.c
util.c

index 8f97df5004ef7b47510d88bbb147ab0475f410f8..20a1ca4c9bfef297c0dc0273499ed64ad6d83089 100644 (file)
--- 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 bcc012ac926f31e77225bd626735c52025598821..b6a9e5ea2dad46f4cad36106ee6bc7f9403a7124 100644 (file)
--- 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 ff6ff151721c0e9916fe433b2e16bb892003d6e4..49173283643c4a4fce907fb91d21145135fd3761 100644 (file)
--- 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);