Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 May 2009 19:30:03 GMT
From:      Jaakko Heinonen <jh@saunalahti.fi>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/133907: cp(1) wrongly reports errors in vacuous copy
Message-ID:  <200905041930.n44JU3nG077786@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/133907; it has been noted by GNATS.

From: Jaakko Heinonen <jh@saunalahti.fi>
To: james@jrv.org
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/133907: cp(1) wrongly reports errors in vacuous copy
Date: Mon, 4 May 2009 22:21:38 +0300

 Hi,
 
 On 2009-04-22, james@jrv.org wrote:
 > $ mkdir x y
 > $ cp -Rp x/ y
 > cp: utimes: y/x: No such file or directory
 > cp: chown: y/x: No such file or directory
 > cp: chmod: y/x: No such file or directory
 > cp: chflags: y/x: No such file or directory
 > $ 
 > 
 > Appears to affect only the vacuous case of arg x being an empty
 > directory, and only if -p is used.
 
 The problem is that in empty directory case fts(3) returns the path name
 without trailing slash in post-order phase. This results an incorrect
 value for "base".
 
 It's somewhat unexpected that fts(3) returns with different path name in
 post-order because the fts(3) manual page states:
 
   FTS_DP       A directory being visited in post-order.  The
 	       contents of the FTSENT structure will be
 	       unchanged from when it was returned in pre-
 	       order, i.e., with the fts_info field set to
 	       FTS_D.
 
 This happens only with FTS_NOCHDIR option used by cp(1).
 
 However there is actually no need to set the base value in post-order
 phase. This patch should fix the problem.
 
 --- patch begins here ---
 Index: bin/cp/cp.c
 ===================================================================
 --- bin/cp/cp.c	(revision 191680)
 +++ bin/cp/cp.c	(working copy)
 @@ -316,7 +316,8 @@ copy(char *argv[], enum op type, int fts
  			 * Since the first level MUST be FTS_ROOTLEVEL, base
  			 * is always initialized.
  			 */
 -			if (curr->fts_level == FTS_ROOTLEVEL) {
 +			if (curr->fts_level == FTS_ROOTLEVEL &&
 +			    curr->fts_info != FTS_DP) {
  				if (type != DIR_TO_DNE) {
  					p = strrchr(curr->fts_path, '/');
  					base = (p == NULL) ? 0 :
 --- patch ends here ---
 
 The fts(3) problem may be worth of fixing but I think that the cp(1)
 change is justified because the fts(3) (mis)behavior seems to exist on
 other OSes too.
 
 -- 
 Jaakko



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905041930.n44JU3nG077786>