http: respect protocol.*.allow=user for http-alternates
[gitweb.git] / wrapper.c
index 3df2fe0e5eb6b49bca5994338094e39982a161cf..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;
        }
 }
@@ -446,23 +457,6 @@ int git_mkstemp(char *path, size_t len, const char *template)
        return mkstemp(path);
 }
 
-/* git_mkstemps() - create tmp file with suffix honoring TMPDIR variable. */
-int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)
-{
-       const char *tmp;
-       size_t n;
-
-       tmp = getenv("TMPDIR");
-       if (!tmp)
-               tmp = "/tmp";
-       n = snprintf(path, len, "%s/%s", tmp, template);
-       if (len <= n) {
-               errno = ENAMETOOLONG;
-               return -1;
-       }
-       return mkstemps(path, suffix_len);
-}
-
 /* Adapted from libiberty's mkstemp.c. */
 
 #undef TMP_MAX