Merge branch 'js/commit-gpgsign' of ../git-gui into js/git-gui-commit-gpgsign
[gitweb.git] / wrapper.c
index 5dc4e15aa9bf73bb2ce0a7af1837e092e0cab585..26db215f0c2f38e426d76e41fb16b7cb8deadeb3 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -227,6 +227,24 @@ int xopen(const char *path, int oflag, ...)
        }
 }
 
+static int handle_nonblock(int fd, short poll_events, int err)
+{
+       struct pollfd pfd;
+
+       if (err != EAGAIN && err != EWOULDBLOCK)
+               return 0;
+
+       pfd.fd = fd;
+       pfd.events = poll_events;
+
+       /*
+        * no need to check for errors, here;
+        * a subsequent read/write will detect unrecoverable errors
+        */
+       poll(&pfd, 1, -1);
+       return 1;
+}
+
 /*
  * xread() is the same a read(), but it automatically restarts read()
  * operations with a recoverable error (EAGAIN and EINTR). xread()
@@ -242,20 +260,8 @@ ssize_t xread(int fd, void *buf, size_t len)
                if (nr < 0) {
                        if (errno == EINTR)
                                continue;
-                       if (errno == EAGAIN || errno == EWOULDBLOCK) {
-                               struct pollfd pfd;
-                               pfd.events = POLLIN;
-                               pfd.fd = fd;
-                               /*
-                                * it is OK if this poll() failed; we
-                                * want to leave this infinite loop
-                                * only when read() returns with
-                                * success, or an expected failure,
-                                * which would be checked by the next
-                                * call to read(2).
-                                */
-                               poll(&pfd, 1, -1);
-                       }
+                       if (handle_nonblock(fd, POLLIN, errno))
+                               continue;
                }
                return nr;
        }
@@ -273,8 +279,13 @@ ssize_t xwrite(int fd, const void *buf, size_t len)
            len = MAX_IO_SIZE;
        while (1) {
                nr = write(fd, buf, len);
-               if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
-                       continue;
+               if (nr < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       if (handle_nonblock(fd, POLLOUT, errno))
+                               continue;
+               }
+
                return nr;
        }
 }