From slaven.rezic@berlin.de  Sat Sep 14 15:10:05 2002
Return-Path: <slaven.rezic@berlin.de>
Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id EBF4537B401
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 14 Sep 2002 15:10:05 -0700 (PDT)
Received: from mailoutvl21.berlin.de (mail.berlin.de [195.243.105.33])
	by mx1.FreeBSD.org (Postfix) with ESMTP id CC1AB43E6E
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 14 Sep 2002 15:10:04 -0700 (PDT)
	(envelope-from slaven.rezic@berlin.de)
Received: from herceg.de ([213.7.181.35]) by mailoutvl21.berlin.de
          (InterMail vK.4.03.05.00 201-232-132 license c0e4b842f1eddc5308d584e55543c802)
          with ESMTP id <20020914221312.QGQT27460.mailoutvl21@herceg.de>
          for <FreeBSD-gnats-submit@freebsd.org>;
          Sun, 15 Sep 2002 00:13:12 +0200
Received: (from eserte@localhost)
	by vran.herceg.de (8.12.4/8.12.4/Submit) id g8EM7tXK020830;
	Sun, 15 Sep 2002 00:07:55 +0200 (CEST)
	(envelope-from eserte)
Message-Id: <200209142207.g8EM7tXK020830@vran.herceg.de>
Date: Sun, 15 Sep 2002 00:07:55 +0200 (CEST)
From: Slaven Rezic <eserte@vran.herceg.de>
Reply-To: slaven.rezic@berlin.de
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: cp -p may report wrong exit status
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         42789
>Category:       bin
>Synopsis:       cp -p may report wrong exit status
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Sep 14 15:20:02 PDT 2002
>Closed-Date:    Sat Aug 02 10:55:50 PDT 2003
>Last-Modified:  Sat Aug 02 10:55:50 PDT 2003
>Originator:     Slaven Rezic
>Release:        FreeBSD 4.6-STABLE i386
>Organization:
www.rezic.de
>Environment:
System: FreeBSD vran.herceg.de 4.6-STABLE FreeBSD 4.6-STABLE #15: Sat Jul 27 09:32:28 CEST 2002 root@vran.herceg.de:/usr/local/src/FreeBSD-4/src/sys/compile/VRAN i386


	
>Description:

	cp -p may report success when a copy fails but setting the
	mode bits (via setfile()) succeeds. This may be fatal for mv,
	which relies on the exit code of cp.

>How-To-Repeat:
	
	Use mv on a directory with a big file between different filesystems.
	The big file should be too large for the target filesystem.
	Hence the mv fails, but the source directory is nevertheless
	deleted.

>Fix:

	
--- bin/cp/cp.c.orig	Sat Sep 14 23:52:30 2002
+++ bin/cp/cp.c	Sat Sep 14 23:57:35 2002
@@ -250,7 +250,7 @@ copy(argv, type, fts_options)
 	struct stat to_stat;
 	FTS *ftsp;
 	FTSENT *curr;
-	int base = 0, dne, badcp, nlen, rval;
+	int base = 0, dne, badcp, nlen, rval, newrval;
 	char *p, *target_mid;
 	mode_t mask, mode;
 
@@ -350,9 +350,11 @@ copy(argv, type, fts_options)
 			 * honour setuid, setgid and sticky bits, but we
 			 * normally want to preserve them on directories.
 			 */
-			if (pflag)
-				rval = setfile(curr->fts_statp, 0);
-			else {
+			if (pflag) {
+				newrval = setfile(curr->fts_statp, 0);
+				if (newrval)
+					rval = newrval;
+			} else {
 				mode = curr->fts_statp->st_mode;
 				if ((mode & (S_ISUID | S_ISGID | S_ISTXT)) ||
 				    ((mode | S_IRWXU) & mask) != (mode & mask))


>Release-Note:
>Audit-Trail:

From: Ralf Becker <ralf@akk.org>
To: freebsd-gnats-submit@FreeBSD.org, slaven.rezic@berlin.de
Cc:  
Subject: bin/42789: cp -p may report wrong exit status
Date: Mon, 16 Sep 2002 15:27:25 +0200

 In my opinion slaven's fixed the problem at the wrong place.
 The error is caused by the fact that there is no check of the return
 value after calling one one of the copy_* functions.
 Isn't it enough to do this at the end of the loop ?
 
 *** cp.c.orig	Mon Sep 16 13:19:16 2002
 --- cp.c	Mon Sep 16 13:26:26 2002
 ***************
 *** 445,450 ****
 --- 445,454 ----
   		}
   		if (vflag && !badcp)
   			(void)printf("%s -> %s\n", curr->fts_path, to.p_path);
 + 		if ( rval != 0 || badcp != 0) {
 + 			/* error occured */
 + 			break;
 + 		}
   	}
   	if (errno)
   		err(1, "fts_read");
 
 Ralf
 -- 
 Ralf Becker           ralf@akk.org 
 Arbeitskreis Kultur und Kommunikation / Universitaet Karlsruhe
 Paulckeplatz 1        76131 Karlsruhe
 Tel 0721/96403-22     Fax 0721/608-4019 
 --------------------

From: Slaven Rezic <slaven.rezic@berlin.de>
To: Ralf Becker <ralf@akk.org>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/42789: cp -p may report wrong exit status
Date: 16 Sep 2002 15:55:41 +0200

 Ralf Becker <ralf@akk.org> writes:
 
 > In my opinion slaven's fixed the problem at the wrong place.
 > The error is caused by the fact that there is no check of the return
 > value after calling one one of the copy_* functions.
 > Isn't it enough to do this at the end of the loop ?
 
 The current behavior is that cp tries to copy all traversed files,
 regardless of an error in an individual copy. If there was at least
 one error, then rval is set to 1 and returned at the end of cp (except
 for the bug below).
 
 So you want to stop cp at the first error? What's the opinion of POSIX
 on this?
 
 Regards,
 	Slaven
 
 
 > *** cp.c.orig	Mon Sep 16 13:19:16 2002
 > --- cp.c	Mon Sep 16 13:26:26 2002
 > ***************
 > *** 445,450 ****
 > --- 445,454 ----
 >   		}
 >   		if (vflag && !badcp)
 >   			(void)printf("%s -> %s\n", curr->fts_path, to.p_path);
 > + 		if ( rval != 0 || badcp != 0) {
 > + 			/* error occured */
 > + 			break;
 > + 		}
 >   	}
 >   	if (errno)
 >   		err(1, "fts_read");
 > 
 
 -- 
 Slaven Rezic - slaven.rezic@berlin.de
 
     tksm - Perl/Tk program for searching and replacing in multiple files
     http://ptktools.sourceforge.net/#tksm

From: Ralf Becker <ralf@akk.org>
To: Slaven Rezic <slaven.rezic@berlin.de>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/42789: cp -p may report wrong exit status
Date: Tue, 17 Sep 2002 12:33:26 +0200

 On Mon, Sep 16, 2002 at 03:55:41PM +0200, Slaven Rezic wrote:
 > The current behavior is that cp tries to copy all traversed files,
 > regardless of an error in an individual copy. If there was at least
 > one error, then rval is set to 1 and returned at the end of cp (except
 > for the bug below).
 Yes, i realized it
 > 
 > So you want to stop cp at the first error? What's the opinion of POSIX
 > on this?
 
 In the POSIX-Specs is written (excerpt :-)):
 **
 d. The contents of source_file shall be written to the file descriptor.
 Any write errors shall cause cp to write a diagnostic message to standard
 error and continue to step 3e.
 
 e.The file descriptor shall be closed.
 
 f.The cp utility shall do nothing more with source_file.  If a write
 error occurred in step 3d, it is unspecified if cp continues with any
 remaining files. If no write error occurred in step 3d, cp shall go on
 to any remaining files.
 **
 
 So, the situation is more clear. Your change is absolutly neccessary to
 preserve the return value of copy_*  in the case of any error.
 The remaining question if cp should stop on write errors is a question
 of taste.
 (My understanding of f. is, that cp should continue if
 read, open ... on the source file fails.)
 
 Ralf
 -- 
 Ralf Becker           ralf@akk.org 
 Arbeitskreis Kultur und Kommunikation / Universitaet Karlsruhe
 Paulckeplatz 1        76131 Karlsruhe
 Tel 0721/96403-22     Fax 0721/608-4019 
 --------------------
State-Changed-From-To: open->closed 
State-Changed-By: jhb 
State-Changed-When: Sat Aug 2 10:55:00 PDT 2003 
State-Changed-Why:  
Closed at the request of the submitter.  The bug has been fixed in both 
current and 4-stable. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=42789 
>Unformatted:
