summaryrefslogtreecommitdiff
path: root/src/install.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-11-20 14:08:33 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2011-11-20 14:09:53 -0800
commit71b7ddcdd5c473f9eaf6035b96acc68c14cb379e (patch)
treea4d7544dc4ed5123a2ffaf40105fc8d0049ddf22 /src/install.c
parent8ffc159611db3443282aee42465afc8a1597519c (diff)
downloadcoreutils-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.c24
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 */