Module Name: src Committed By: martin Date: Thu Sep 23 10:11:02 UTC 2021
Modified Files: src/bin/cp [netbsd-9]: utils.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.46 -r1.46.2.1 src/bin/cp/utils.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/bin/cp/utils.c diff -u src/bin/cp/utils.c:1.46 src/bin/cp/utils.c:1.46.2.1 --- src/bin/cp/utils.c:1.46 Tue Jul 17 13:04:58 2018 +++ src/bin/cp/utils.c Thu Sep 23 10:11:02 2021 @@ -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; - - fi.from = entp->fts_path; - fi.to = to.p_path; - fi.size = fs->st_size; - - /* - * 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; + bool need_copy = !S_ISREG(fs->st_mode) || fs->st_size > 0; - 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); + struct finfo fi; - 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);