Merge branch 'nd/do-not-move-worktree-manually'
[gitweb.git] / wrapper.c
index 371a7f0b63719f0a81ee64abb17b4ca6dbf9ba16..29a45d2654e982dbbb3fc328e16c01713d8a7fb5 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -236,8 +236,24 @@ ssize_t xread(int fd, void *buf, size_t len)
            len = MAX_IO_SIZE;
        while (1) {
                nr = read(fd, buf, len);
-               if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
-                       continue;
+               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);
+                       }
+               }
                return nr;
        }
 }
@@ -622,6 +638,22 @@ char *xgetcwd(void)
        return strbuf_detach(&sb, NULL);
 }
 
+int xsnprintf(char *dst, size_t max, const char *fmt, ...)
+{
+       va_list ap;
+       int len;
+
+       va_start(ap, fmt);
+       len = vsnprintf(dst, max, fmt, ap);
+       va_end(ap);
+
+       if (len < 0)
+               die("BUG: your snprintf is broken");
+       if (len >= max)
+               die("BUG: attempt to snprintf into too-small buffer");
+       return len;
+}
+
 static int write_file_v(const char *path, int fatal,
                        const char *fmt, va_list params)
 {