diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2006-09-18 22:09:49 +0000 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2006-09-18 22:09:49 +0000 |
commit | 0e3b87195ab0820d228cda986ac916d52b696aff (patch) | |
tree | aa59e32593d2e666b9afdc509704b4e38013f9f5 /src/chown-core.c | |
parent | bebf83d0fd198ea199f6df9684141d284b5323e2 (diff) | |
download | coreutils-0e3b87195ab0820d228cda986ac916d52b696aff.tar.xz |
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.
Diffstat (limited to 'src/chown-core.c')
-rw-r--r-- | src/chown-core.c | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/src/chown-core.c b/src/chown-core.c index 39cb34d8b..b5b0f3b42 100644 --- a/src/chown-core.c +++ b/src/chown-core.c @@ -51,6 +51,10 @@ enum RCH_status RC_error }; +/* Error number associated with the working directory, or 0 if no + error has been found. */ +static int wd_errno; + extern void chopt_init (struct Chown_option *chopt) { @@ -422,7 +426,7 @@ change_file_owner (FTS *fts, FTSENT *ent, return ok; } -/* Change the owner and/or group of the specified FILES. +/* Change the owner and/or group of the specified FILE. BIT_FLAGS specifies how to treat each symlink-to-directory that is encountered during a recursive traversal. CHOPT specifies additional options. @@ -431,11 +435,11 @@ change_file_owner (FTS *fts, FTSENT *ent, If REQUIRED_UID and/or REQUIRED_GID is not -1, then change only files with user ID and group ID that match the non-(-1) value(s). Return true if successful. */ -extern bool -chown_files (char **files, int bit_flags, - uid_t uid, gid_t gid, - uid_t required_uid, gid_t required_gid, - struct Chown_option const *chopt) +static bool +chown_file (char *file, int bit_flags, + uid_t uid, gid_t gid, + uid_t required_uid, gid_t required_gid, + struct Chown_option const *chopt) { bool ok = true; @@ -445,7 +449,11 @@ chown_files (char **files, int bit_flags, ? 0 : FTS_NOSTAT); - FTS *fts = xfts_open (files, bit_flags | stat_flags, NULL); + FTS *fts; + char *files[2]; + files[0] = file; + files[1] = NULL; + fts = xfts_open (files, bit_flags | stat_flags, NULL); while (1) { @@ -467,10 +475,40 @@ chown_files (char **files, int bit_flags, required_uid, required_gid, chopt); } - /* 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; +} + +/* Change the owner and/or group of the specified FILES. + BIT_FLAGS specifies how to treat each symlink-to-directory + that is encountered during a recursive traversal. + CHOPT specifies additional options. + If UID is not -1, then change the owner id of each file to UID. + If GID is not -1, then change the group id of each file to GID. + If REQUIRED_UID and/or REQUIRED_GID is not -1, then change only + files with user ID and group ID that match the non-(-1) value(s). + Return true if successful. */ +extern bool +chown_files (char **files, int bit_flags, + uid_t uid, gid_t gid, + uid_t required_uid, gid_t required_gid, + struct Chown_option const *chopt) +{ + bool ok = true; + + for (; *files; files++) + { + if (! IS_ABSOLUTE_FILE_NAME (*files) && wd_errno) + { + error (0, wd_errno, "."); + ok = false; + } + else + ok &= chown_file (*files, bit_flags, uid, gid, + required_uid, required_gid, chopt); + } return ok; } |