diff options
| author | martin <martin@NetBSD.org> | 2021-09-23 10:11:02 +0000 |
|---|---|---|
| committer | martin <martin@NetBSD.org> | 2021-09-23 10:11:02 +0000 |
| commit | 24d837bb2212ac55bf5c6e7e5d6e04f501b88d02 (patch) | |
| tree | 81fe3ecdf5e4b990289637e15e3fb8fc2fd7475a /bin | |
| parent | bd5343f09d262b6c0eb84aa37d334035be7a000f (diff) | |
Pull up following revision(s) (requested by skrll in ticket #1348):
bin/cp/utils.c: revision 1.47
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 (limited to 'bin')
| -rw-r--r-- | bin/cp/utils.c | 128 |
1 files changed, 62 insertions, 66 deletions
diff --git a/bin/cp/utils.c b/bin/cp/utils.c index 6275fc6bf62..602001510a2 100644 --- a/bin/cp/utils.c +++ b/bin/cp/utils.c @@ -1,4 +1,4 @@ -/* $NetBSD: utils.c,v 1.46 2018/07/17 13:04:58 darcy Exp $ */ +/* $NetBSD: utils.c,v 1.46.2.1 2021/09/23 10:11:02 martin 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.46.2.1 2021/09/23 10:11:02 martin Exp $"); #endif #endif /* not lint */ @@ -174,87 +174,83 @@ copy_file(FTSENT *entp, int dne) 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; + bool need_copy = !S_ISREG(fs->st_mode) || fs->st_size > 0; - fi.from = entp->fts_path; - fi.to = to.p_path; - fi.size = fs->st_size; + struct finfo fi; - /* - * 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; - - 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); - - /* - * 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; - - 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); - - if (munmap(p, fsize) < 0) { - warn("%s", entp->fts_path); - rval = 1; - } - } - } + fi.from = entp->fts_path; + fi.to = to.p_path; + fi.size = fs->st_size; - if (use_read) { - while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) { - wcount = write(to_fd, buf, (size_t)rcount); - if (rcount != wcount || wcount == -1) { + /* + * 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; + + (void) madvise(p, (size_t)fs->st_size, MADV_SEQUENTIAL); + + /* + * 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; + + 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); |
