From 0e3b87195ab0820d228cda986ac916d52b696aff Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 18 Sep 2006 22:09:49 +0000 Subject: Fix bug where chmod, chown, and chgrp did not process operands left-to-right in some cases. * src/chmod.c (wd_errno): New var. (chmod_file): New function, with most of the contents of the old prcess_file function. (process_files): Use it. This gives file names to fts one at a time, so that they are processed left-to-right as POSIX requires. * src/chown-core.c (wd_errno, chown_files): Likewise. (chown_file): New function. * tests/install/basic-1: Redo test so as to not workaround the chmod bug, thereby testing for it. --- src/chmod.c | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) (limited to 'src/chmod.c') diff --git a/src/chmod.c b/src/chmod.c index 29611366c..eb1cfe7a0 100644 --- a/src/chmod.c +++ b/src/chmod.c @@ -85,6 +85,10 @@ static enum Verbosity verbosity = V_off; Otherwise NULL. */ static struct dev_ino *root_dev_ino; +/* Error number associated with the working directory, or 0 if no + error has been found. */ +static int wd_errno; + /* For long options that have no equivalent short option, use a non-character as a pseudo short option, starting with CHAR_MAX + 1. */ enum @@ -279,16 +283,19 @@ process_file (FTS *fts, FTSENT *ent) return ok; } -/* Recursively change the modes of the specified FILES (the last entry - of which is NULL). BIT_FLAGS controls how fts works. +/* Recursively change the modes of the command-line operand FILE. + BIT_FLAGS controls how fts works. Return true if successful. */ static bool -process_files (char **files, int bit_flags) +chmod_file (char *file, int bit_flags) { + char *files[2]; bool ok = true; - - FTS *fts = xfts_open (files, bit_flags, NULL); + FTS *fts; + files[0] = file; + files[1] = NULL; + fts = xfts_open (files, bit_flags, NULL); while (1) { @@ -309,10 +316,31 @@ process_files (char **files, int bit_flags) ok &= process_file (fts, ent); } - /* Ignore failure, since the only way it can do so is in failing to - return to the original directory, and since we're about to exit, - that doesn't matter. */ - fts_close (fts); + if (fts_close (fts) != 0) + wd_errno = errno; + + return ok; +} + +/* Recursively change the modes of the specified FILES (the last entry + of which is NULL). BIT_FLAGS controls how fts works. + Return true if successful. */ +static bool +process_files (char **files, int bit_flags) +{ + bool ok = true; + wd_errno = 0; + + for (; *files; files++) + { + if (! IS_ABSOLUTE_FILE_NAME (*files) && wd_errno) + { + error (0, wd_errno, "."); + ok = false; + } + else + ok &= chmod_file (*files, bit_flags); + } return ok; } -- cgit v1.2.3-54-g00ecf