Module Name: src Committed By: pooka Date: Thu Oct 8 20:36:41 UTC 2009
Modified Files: src/bin/cp: cp.c Log Message: Fix the "dne" handling and chmod behaviour properly: values of dne need to be on a stack instead of being a single variable since directories are processed depth-first. Otherwise dne randomly depends on the previously processed entry. This fixes both chmod of non-created directories (they used to be chmod'd even when not created if their last child element did not exist in the target subtree) and a "foo exists" bug exposed by my last commit which removed directory sorting. all regression tests passed To generate a diff of this commit: cvs rdiff -u -r1.52 -r1.53 src/bin/cp/cp.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/cp.c diff -u src/bin/cp/cp.c:1.52 src/bin/cp/cp.c:1.53 --- src/bin/cp/cp.c:1.52 Tue Sep 29 13:30:17 2009 +++ src/bin/cp/cp.c Thu Oct 8 20:36:41 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: cp.c,v 1.52 2009/09/29 13:30:17 pooka Exp $ */ +/* $NetBSD: cp.c,v 1.53 2009/10/08 20:36:41 pooka Exp $ */ /* * Copyright (c) 1988, 1993, 1994 @@ -43,7 +43,7 @@ #if 0 static char sccsid[] = "@(#)cp.c 8.5 (Berkeley) 4/29/95"; #else -__RCSID("$NetBSD: cp.c,v 1.52 2009/09/29 13:30:17 pooka Exp $"); +__RCSID("$NetBSD: cp.c,v 1.53 2009/10/08 20:36:41 pooka Exp $"); #endif #endif /* not lint */ @@ -65,6 +65,7 @@ #include <sys/param.h> #include <sys/stat.h> +#include <assert.h> #include <err.h> #include <errno.h> #include <fts.h> @@ -280,6 +281,26 @@ /* NOTREACHED */ } +static int dnestack[MAXPATHLEN]; /* unlikely we'll have more nested dirs */ +static ssize_t dnesp; +static void +pushdne(int dne) +{ + + dnestack[dnesp++] = dne; + assert(dnesp < MAXPATHLEN); +} + +static int +popdne(void) +{ + int rv; + + rv = dnestack[--dnesp]; + assert(dnesp >= 0); + return rv; +} + int copy(char *argv[], enum op type, int fts_options) { @@ -291,7 +312,6 @@ size_t nlen; char *p, *target_mid; - dne = 0; base = 0; /* XXX gcc -Wuninitialized (see comment below) */ if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL) @@ -398,8 +418,7 @@ this_failed = any_failed = 1; continue; } - if (!S_ISDIR(curr->fts_statp->st_mode)) - dne = 0; + dne = 0; } switch (curr->fts_statp->st_mode & S_IFMT) { @@ -439,6 +458,7 @@ * 555) and not causing a permissions race. If the * umask blocks owner writes, we fail.. */ + pushdne(dne); if (dne) { if (mkdir(to.p_path, curr->fts_statp->st_mode | S_IRWXU) < 0) @@ -462,16 +482,9 @@ */ if (pflag && setfile(curr->fts_statp, 0)) this_failed = any_failed = 1; - else if (dne) + else if ((dne = popdne())) (void)chmod(to.p_path, curr->fts_statp->st_mode); - - /* - * Since this is the second pass, we already - * noted (and acted on) the existence of the - * directory. - */ - dne = 0; } else {