commit: 2863e563f7b37d9e9cbb56551c8a4c033f802750
Author: Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 28 22:14:25 2016 +0000
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Wed Dec 28 22:14:25 2016 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=2863e563
copy_file: rewrite to use fds
This avoids FILE* leakage and produces a little bit smaller code.
libq/copy_file.c | 63 ++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 41 insertions(+), 22 deletions(-)
diff --git a/libq/copy_file.c b/libq/copy_file.c
index ee1338d..4230b73 100644
--- a/libq/copy_file.c
+++ b/libq/copy_file.c
@@ -1,31 +1,50 @@
-static int copy_file_fd(int fd_src, int fd_dst)
+static ssize_t safe_read(int fd, void *buf, size_t len)
{
- FILE *fp_src, *fp_dst;
- size_t rcnt, wcnt;
- char buf[BUFSIZE];
+ ssize_t ret;
- /* dont fclose() as that implicitly close()'s */
+ while (1) {
+ ret = read(fd, buf, len);
+ if (ret >= 0)
+ break;
+ else if (errno != EINTR)
+ break;
+ }
- fp_src = fdopen(fd_src, "r");
- if (!fp_src)
- return -1;
+ return ret;
+}
- fp_dst = fdopen(fd_dst, "w");
- if (!fp_dst)
- return -1;
+static ssize_t safe_write(int fd, const void *buf, size_t len)
+{
+ ssize_t ret;
- while (1) {
- rcnt = fread(buf, sizeof(buf[0]), sizeof(buf), fp_src);
- if (!rcnt) {
- fflush(fp_dst);
- return feof(fp_src) ? 0 : -1;
+ while (len) {
+ ret = write(fd, buf, len);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ return -1;
}
+ buf += ret;
+ len -= ret;
+ }
- wcnt = fwrite(buf, sizeof(buf[0]), rcnt, fp_dst);
- if (wcnt != rcnt) {
- if (ferror(fp_dst))
- return -1;
- fseek(fp_src, wcnt - rcnt, SEEK_CUR);
- }
+ return ret;
+}
+
+static int copy_file_fd(int fd_src, int fd_dst)
+{
+ ssize_t rcnt, wcnt;
+ char buf[64 * 1024];
+
+ while (1) {
+ rcnt = safe_read(fd_src, buf, sizeof(buf));
+ if (rcnt < 0)
+ return -1;
+ else if (rcnt == 0)
+ return 0;
+
+ wcnt = safe_write(fd_dst, buf, rcnt);
+ if (wcnt == -1)
+ return -1;
}
}