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