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
{