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;
        }
 }

Reply via email to