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;
}
}
return stream;
}
+FILE *fopen_for_writing(const char *path)
+{
+ FILE *ret = fopen(path, "w");
+
+ if (!ret && errno == EPERM) {
+ if (!unlink(path))
+ ret = fopen(path, "w");
+ else
+ errno = EPERM;
+ }
+ return ret;
+}
+
int xmkstemp(char *template)
{
int fd;
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)
{