Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/cp PR/54564: Jan Schaumann: cp of a fifo yields an empty...



details:   https://anonhg.NetBSD.org/src/rev/3448a6dc091a
branches:  trunk
changeset: 454644:3448a6dc091a
user:      christos <christos%NetBSD.org@localhost>
date:      Mon Sep 23 18:01:09 2019 +0000

description:
PR/54564: Jan Schaumann: cp of a fifo yields an empty file
Don't short-circuit 0 sized stat entries if they don't belong to regular files.
Also don't try to mmap non-regular files.

diffstat:

 bin/cp/utils.c |  122 +++++++++++++++++++++++++++-----------------------------
 1 files changed, 59 insertions(+), 63 deletions(-)

diffs (163 lines):

diff -r 2fce33b91008 -r 3448a6dc091a bin/cp/utils.c
--- a/bin/cp/utils.c    Mon Sep 23 17:37:04 2019 +0000
+++ b/bin/cp/utils.c    Mon Sep 23 18:01:09 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: utils.c,v 1.46 2018/07/17 13:04:58 darcy Exp $ */
+/* $NetBSD: utils.c,v 1.47 2019/09/23 18:01:09 christos Exp $ */
 
 /*-
  * Copyright (c) 1991, 1993, 1994
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)utils.c    8.3 (Berkeley) 4/1/94";
 #else
-__RCSID("$NetBSD: utils.c,v 1.46 2018/07/17 13:04:58 darcy Exp $");
+__RCSID("$NetBSD: utils.c,v 1.47 2019/09/23 18:01:09 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -174,87 +174,83 @@
 
        rval = 0;
 
-       /*
+       /* 
         * There's no reason to do anything other than close the file
-        * now if it's empty, so let's not bother.
+        * now if it's regular and empty, so let's not bother.
         */
-       if (fs->st_size > 0) {
-               struct finfo fi;
-
-               fi.from = entp->fts_path;
-               fi.to = to.p_path;
-               fi.size = fs->st_size;
+       bool need_copy = !S_ISREG(fs->st_mode) || fs->st_size > 0;
 
-               /*
-                * Mmap and write if less than 8M (the limit is so
-                * we don't totally trash memory on big files).
-                * This is really a minor hack, but it wins some CPU back.
-                */
-               bool use_read;
+       struct finfo fi;
 
-               use_read = true;
-               if (fs->st_size <= MMAP_MAX_SIZE) {
-                       size_t fsize = (size_t)fs->st_size;
-                       p = mmap(NULL, fsize, PROT_READ, MAP_FILE|MAP_SHARED,
-                           from_fd, (off_t)0);
-                       if (p != MAP_FAILED) {
-                               size_t remainder;
-
-                               use_read = false;
-
-                               (void) madvise(p, (size_t)fs->st_size,
-                                    MADV_SEQUENTIAL);
+       fi.from = entp->fts_path;
+       fi.to = to.p_path;
+       fi.size = fs->st_size;
 
-                               /*
-                                * Write out the data in small chunks to
-                                * avoid locking the output file for a
-                                * long time if the reading the data from
-                                * the source is slow.
-                                */
-                               remainder = fsize;
-                               do {
-                                       ssize_t chunk;
+       /*
+        * Mmap and write if less than 8M (the limit is so
+        * we don't totally trash memory on big files).
+        * This is really a minor hack, but it wins some CPU back.
+        */
+       if (S_ISREG(fs->st_mode) && fs->st_size && fs->st_size <= MMAP_MAX_SIZE) {
+               size_t fsize = (size_t)fs->st_size;
+               p = mmap(NULL, fsize, PROT_READ, MAP_FILE|MAP_SHARED,
+                   from_fd, (off_t)0);
+               if (p != MAP_FAILED) {
+                       size_t remainder;
+
+                       need_copy = false;
 
-                                       chunk = (remainder > MMAP_MAX_WRITE) ?
-                                           MMAP_MAX_WRITE : remainder;
-                                       if (write(to_fd, &p[fsize - remainder],
-                                           chunk) != chunk) {
-                                               warn("%s", to.p_path);
-                                               rval = 1;
-                                               break;
-                                       }
-                                       remainder -= chunk;
-                                       ptotal += chunk;
-                                       if (pinfo)
-                                               progress(&fi, ptotal);
-                               } while (remainder > 0);
+                       (void) madvise(p, (size_t)fs->st_size, MADV_SEQUENTIAL);
 
-                               if (munmap(p, fsize) < 0) {
-                                       warn("%s", entp->fts_path);
-                                       rval = 1;
-                               }
-                       }
-               }
+                       /*
+                        * Write out the data in small chunks to
+                        * avoid locking the output file for a
+                        * long time if the reading the data from
+                        * the source is slow.
+                        */
+                       remainder = fsize;
+                       do {
+                               ssize_t chunk;
 
-               if (use_read) {
-                       while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
-                               wcount = write(to_fd, buf, (size_t)rcount);
-                               if (rcount != wcount || wcount == -1) {
+                               chunk = (remainder > MMAP_MAX_WRITE) ?
+                                   MMAP_MAX_WRITE : remainder;
+                               if (write(to_fd, &p[fsize - remainder],
+                                   chunk) != chunk) {
                                        warn("%s", to.p_path);
                                        rval = 1;
                                        break;
                                }
-                               ptotal += wcount;
+                               remainder -= chunk;
+                               ptotal += chunk;
                                if (pinfo)
                                        progress(&fi, ptotal);
-                       }
-                       if (rcount < 0) {
+                       } while (remainder > 0);
+
+                       if (munmap(p, fsize) < 0) {
                                warn("%s", entp->fts_path);
                                rval = 1;
                        }
                }
        }
 
+       if (need_copy) {
+               while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
+                       wcount = write(to_fd, buf, (size_t)rcount);
+                       if (rcount != wcount || wcount == -1) {
+                               warn("%s", to.p_path);
+                               rval = 1;
+                               break;
+                       }
+                       ptotal += wcount;
+                       if (pinfo)
+                               progress(&fi, ptotal);
+               }
+               if (rcount < 0) {
+                       warn("%s", entp->fts_path);
+                       rval = 1;
+               }
+       }
+
        if (pflag && (fcpxattr(from_fd, to_fd) != 0))
                warn("%s: error copying extended attributes", to.p_path);
 



Home | Main Index | Thread Index | Old Index