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/efa36196c6dc
branches: trunk
changeset: 965597:efa36196c6dc
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 cabe2bac3ef3 -r efa36196c6dc 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