diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2011-11-20 14:08:33 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2011-11-20 14:09:53 -0800 |
commit | 71b7ddcdd5c473f9eaf6035b96acc68c14cb379e (patch) | |
tree | a4d7544dc4ed5123a2ffaf40105fc8d0049ddf22 /src/install.c | |
parent | 8ffc159611db3443282aee42465afc8a1597519c (diff) | |
download | coreutils-71b7ddcdd5c473f9eaf6035b96acc68c14cb379e.tar.xz |
port to GNU hosts, where getuid and friends can fail
* src/groups.c (main):
* src/install.c (need_copy):
* src/su.c (log_su):
* src/test.c (unary_operator):
* src/whoami.c (main):
Don't assume that getuid and friends always succeed.
This fixes the same problem that we recently fixed with 'id'.
Diffstat (limited to 'src/install.c')
-rw-r--r-- | src/install.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/install.c b/src/install.c index dbff9c94b..94534f81e 100644 --- a/src/install.c +++ b/src/install.c @@ -192,9 +192,27 @@ need_copy (const char *src_name, const char *dest_name, return true; if (src_sb.st_size != dest_sb.st_size - || (dest_sb.st_mode & CHMOD_MODE_BITS) != mode - || dest_sb.st_uid != (owner_id == (uid_t) -1 ? getuid () : owner_id) - || dest_sb.st_gid != (group_id == (gid_t) -1 ? getgid () : group_id)) + || (dest_sb.st_mode & CHMOD_MODE_BITS) != mode) + return true; + + if (owner_id == (uid_t) -1) + { + errno = 0; + uid_t ruid = getuid (); + if ((ruid == (uid_t) -1 && errno) || dest_sb.st_uid != ruid) + return true; + } + else if (dest_sb.st_uid != owner_id) + return true; + + if (group_id == (uid_t) -1) + { + errno = 0; + gid_t rgid = getgid (); + if ((rgid == (uid_t) -1 && errno) || dest_sb.st_gid != rgid) + return true; + } + else if (dest_sb.st_gid != group_id) return true; /* compare SELinux context if preserving */ |