Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/bin/cp Fix the "dne" handling and chmod behaviour properly: ...
details: https://anonhg.NetBSD.org/src/rev/4087061b24e1
branches: trunk
changeset: 748002:4087061b24e1
user: pooka <pooka%NetBSD.org@localhost>
date: Thu Oct 08 20:36:41 2009 +0000
description:
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
diffstat:
bin/cp/cp.c | 39 ++++++++++++++++++++++++++-------------
1 files changed, 26 insertions(+), 13 deletions(-)
diffs (97 lines):
diff -r 290ade21059d -r 4087061b24e1 bin/cp/cp.c
--- a/bin/cp/cp.c Thu Oct 08 19:50:03 2009 +0000
+++ b/bin/cp/cp.c Thu Oct 08 20:36:41 2009 +0000
@@ -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
{
Home |
Main Index |
Thread Index |
Old Index