#endif
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
return total;
}
-static int copy_bytes(int dfd, int sfd)
+static int copy_bytes_sendfile(int destfd, int srcfd, off_t *ncopied)
{
- int res = 1;
- ssize_t bytes_sent;
- do
- bytes_sent = sendfile(dfd, sfd, NULL, PIPE_BUF);
- while (bytes_sent > 0);
+ ssize_t nsent;
+ off_t total = 0;
- if (bytes_sent == -1) {
- _E("sendfile() error: %m\n");
- res = -1;
- }
- return res;
+ do {
+ nsent = sendfile(destfd, srcfd, NULL, INT32_MAX);
+ if (nsent > 0)
+ total += nsent;
+ else if (nsent < 0 && errno == EAGAIN)
+ continue;
+ else
+ break;
+ } while (1);
+
+ if (ncopied)
+ *ncopied = total;
+
+ return nsent == -1 ? -1 : 0;
+}
+
+static int copy_bytes_rw(int destfd, int srcfd, off_t *ncopied)
+{
+ ssize_t n;
+ char buf[4096];
+ off_t total = 0;
+
+ do {
+ n = read(srcfd, buf, sizeof buf);
+ if (n < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ _E("read: %m");
+ return -1;
+ }
+
+ int m = write_fd(destfd, buf, n);
+ if (m != n) {
+ _E("failed to write data to destination fd: %m");
+ return -1;
+ }
+ total += m;
+ } while (n > 0);
+
+ if (ncopied)
+ *ncopied = total;
+
+ return 0;
+}
+
+int copy_bytes(int destfd, int srcfd, off_t *ncopied)
+{
+ int r = copy_bytes_sendfile(destfd, srcfd, ncopied);
+ return r == 0 ? r : copy_bytes_rw(destfd, srcfd, ncopied);
}
int copy_file(char *src, char *dst)
return -1;
}
- res = copy_bytes(dfd, sfd);
+ res = copy_bytes(dfd, sfd, NULL);
close(sfd);
close(dfd);
return -1;
}
- res = copy_bytes(dfd, sfd);
+ res = copy_bytes(dfd, sfd, NULL);
close(sfd);
return res;
int write_fd(int fd, const void *buf, int len);
+int copy_bytes(int destfd, int srcfd, off_t *ncopied);
+
int copy_file(char *src, char *dst);
int move_file(char *src, char *dst);