summaryrefslogtreecommitdiffstats
path: root/src/utils/include/all-io.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/include/all-io.h')
-rw-r--r--src/utils/include/all-io.h38
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 */