diff options
Diffstat (limited to 'src/utils/include/all-io.h')
-rw-r--r-- | src/utils/include/all-io.h | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/utils/include/all-io.h b/src/utils/include/all-io.h index 8ffa9cf..5ed2d11 100644 --- a/src/utils/include/all-io.h +++ b/src/utils/include/all-io.h @@ -12,6 +12,10 @@ #include <string.h> #include <unistd.h> #include <errno.h> +#include <sys/types.h> +#ifdef HAVE_SYS_SENDFILE_H +# include <sys/sendfile.h> +#endif #include "c.h" @@ -63,13 +67,15 @@ static inline ssize_t read_all(int fd, char *buf, size_t count) memset(buf, 0, count); while (count > 0) { ret = read(fd, buf, count); - if (ret <= 0) { - if (ret < 0 && (errno == EAGAIN || errno == EINTR) && (tries++ < 5)) { + if (ret < 0) { + if ((errno == EAGAIN || errno == EINTR) && (tries++ < 5)) { xusleep(250000); continue; } return c ? c : -1; } + if (ret == 0) + return c; tries = 0; count -= ret; buf += ret; @@ -78,4 +84,32 @@ static inline ssize_t read_all(int fd, char *buf, size_t count) return c; } +static inline ssize_t sendfile_all(int out, int in, off_t *off, size_t count) +{ +#if defined(HAVE_SENDFILE) && defined(__linux__) + ssize_t ret; + ssize_t c = 0; + int tries = 0; + while (count) { + ret = sendfile(out, in, off, count); + if (ret < 0) { + if ((errno == EAGAIN || errno == EINTR) && (tries++ < 5)) { + xusleep(250000); + continue; + } + return c ? c : -1; + } + if (ret == 0) + return c; + tries = 0; + count -= ret; + c += ret; + } + return c; +#else + errno = ENOSYS; + return -1; +#endif +} + #endif /* UTIL_LINUX_ALL_IO_H */ |