Subject: bin/37018: cp(1) verbose flag stops working after error
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <dieter.NetBSD@pandora.be>
List: netbsd-bugs
Date: 09/22/2007 21:35:00
>Number: 37018
>Category: bin
>Synopsis: cp(1) verbose flag stops working after error
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Sep 22 21:35:00 +0000 2007
>Originator: dieter roelants
>Release: NetBSD 4.99.22
>Organization:
>Environment:
System: NetBSD simult.amelgem.be 4.99.22 NetBSD 4.99.22 (SIMULT) #23: Mon Jul 2 19:30:03 CEST 2007 dieter@simult.amelgem.be:/build/obj.i386.current/sys/arch/i386/compile/SIMULT i386
Architecture: i386
Machine: i386
>Description:
The verbose flag of cp(1) should show all files being
successfully copied. However, after an error is encountered,
later successful copies aren't shown.
>How-To-Repeat:
simult:p5:/tmp/p$ ls -l
total 8
-rw-r--r-- 1 dieter wheel 0 Sep 22 21:25 a
---------- 1 dieter wheel 0 Sep 22 21:25 b
-rw-r--r-- 1 dieter wheel 0 Sep 22 21:25 c
drwxr-xr-x 2 dieter wheel 512 Sep 22 21:25 dest
simult:p5:/tmp/p$ cp -v ? dest/
c -> dest/c
cp: b: Permission denied
simult:p5:/tmp/p$ ls dest
a c
>Fix:
Index: cp.c
===================================================================
RCS file: /cvsroot/src/bin/cp/cp.c,v
retrieving revision 1.48
diff -u -r1.48 cp.c
--- cp.c 26 Dec 2006 00:13:24 -0000 1.48
+++ cp.c 22 Sep 2007 19:15:11 -0000
@@ -286,7 +286,7 @@
struct stat to_stat;
FTS *ftsp;
FTSENT *curr;
- int base, dne, rval, sval;
+ int base, dne, rval, sval, tval;
size_t nlen;
char *p, *target_mid;
@@ -296,18 +296,18 @@
if ((ftsp = fts_open(argv, fts_options, mastercmp)) == NULL)
err(EXIT_FAILURE, "%s", argv[0]);
/* NOTREACHED */
- for (rval = 0; (curr = fts_read(ftsp)) != NULL;) {
+ for (rval = 0; (curr = fts_read(ftsp)) != NULL; tval = 0) {
switch (curr->fts_info) {
case FTS_NS:
case FTS_DNR:
case FTS_ERR:
warnx("%s: %s", curr->fts_path,
strerror(curr->fts_errno));
- rval = 1;
+ tval = 1;
continue;
case FTS_DC: /* Warn, continue. */
warnx("%s: directory causes a cycle", curr->fts_path);
- rval = 1;
+ tval = 1;
continue;
}
@@ -320,7 +320,7 @@
to.target_end - to.p_path + 1) > MAXPATHLEN) {
warnx("%s/%s: name too long (not copied)",
to.p_path, curr->fts_name);
- rval = 1;
+ tval = 1;
continue;
}
@@ -366,7 +366,7 @@
if (target_mid - to.p_path + nlen >= PATH_MAX) {
warnx("%s%s: name too long (not copied)",
to.p_path, p);
- rval = 1;
+ tval = 1;
continue;
}
(void)strncat(target_mid, p, nlen);
@@ -384,7 +384,7 @@
to_stat.st_ino == curr->fts_statp->st_ino) {
warnx("%s and %s are identical (not copied).",
to.p_path, curr->fts_path);
- rval = 1;
+ tval = 1;
if (S_ISDIR(curr->fts_statp->st_mode))
(void)fts_set(ftsp, curr, FTS_SKIP);
continue;
@@ -393,7 +393,7 @@
S_ISDIR(to_stat.st_mode)) {
warnx("cannot overwrite directory %s with non-directory %s",
to.p_path, curr->fts_path);
- rval = 1;
+ tval = 1;
continue;
}
if (!S_ISDIR(curr->fts_statp->st_mode))
@@ -406,10 +406,10 @@
if((fts_options & FTS_LOGICAL) ||
((fts_options & FTS_COMFOLLOW) && curr->fts_level == 0)) {
if (copy_file(curr, dne))
- rval = 1;
+ tval = 1;
} else {
if (copy_link(curr, !dne))
- rval = 1;
+ tval = 1;
}
break;
case S_IFDIR:
@@ -418,7 +418,7 @@
warnx("%s is a directory (not copied).",
curr->fts_path);
(void)fts_set(ftsp, curr, FTS_SKIP);
- rval = 1;
+ tval = 1;
break;
}
@@ -459,7 +459,7 @@
* forever.
*/
if (pflag && setfile(curr->fts_statp, 0))
- rval = 1;
+ tval = 1;
else if (dne)
(void)chmod(to.p_path,
curr->fts_statp->st_mode);
@@ -475,7 +475,7 @@
{
warnx("directory %s encountered when not expected.",
curr->fts_path);
- rval = 1;
+ tval = 1;
break;
}
@@ -484,26 +484,27 @@
case S_IFCHR:
if (Rflag) {
if (copy_special(curr->fts_statp, !dne))
- rval = 1;
+ tval = 1;
} else
if (copy_file(curr, dne))
- rval = 1;
+ tval = 1;
break;
case S_IFIFO:
if (Rflag) {
if (copy_fifo(curr->fts_statp, !dne))
- rval = 1;
+ tval = 1;
} else
if (copy_file(curr, dne))
- rval = 1;
+ tval = 1;
break;
default:
if (copy_file(curr, dne))
- rval = 1;
+ tval = 1;
break;
}
- if (vflag && !rval)
+ if (vflag && !tval)
(void)printf("%s -> %s\n", curr->fts_path, to.p_path);
+ rval |= tval;
}
if (errno) {
err(EXIT_FAILURE, "fts_read");