1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* Provide a stub lchown function for systems that lack it.
5 Copyright (C) 1998-1999, 2002, 2004, 2006-2007, 2009-2013 Free Software
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* written by Jim Meyering */
34 /* If the system chown does not follow symlinks, we don't want it
35 replaced by gnulib's chown, which does follow symlinks. */
36 # if CHOWN_MODIFIES_SYMLINK
40 /* Work just like chown, except when FILE is a symbolic link.
41 In that case, set errno to EOPNOTSUPP and return -1.
42 But if autoconf tests determined that chown modifies
43 symlinks, then just call chown. */
46 lchown (const char *file, uid_t uid, gid_t gid)
49 # if ! CHOWN_MODIFIES_SYMLINK
52 if (lstat (file, &stats) == 0 && S_ISLNK (stats.st_mode))
59 return chown (file, uid, gid);
61 # else /* !HAVE_CHOWN */
67 #else /* HAVE_LCHOWN */
71 /* Work around trailing slash bugs in lchown. */
73 rpl_lchown (const char *file, uid_t uid, gid_t gid)
75 bool stat_valid = false;
78 # if CHOWN_CHANGE_TIME_BUG
81 if (gid != (gid_t) -1 || uid != (uid_t) -1)
83 if (lstat (file, &st))
86 if (!S_ISLNK (st.st_mode))
87 return chown (file, uid, gid);
91 # if CHOWN_TRAILING_SLASH_BUG
94 size_t len = strlen (file);
95 if (len && file[len - 1] == '/')
96 return chown (file, uid, gid);
100 result = lchown (file, uid, gid);
102 # if CHOWN_CHANGE_TIME_BUG && HAVE_LCHMOD
103 if (result == 0 && stat_valid
104 && (uid == st.st_uid || uid == (uid_t) -1)
105 && (gid == st.st_gid || gid == (gid_t) -1))
107 /* No change in ownership, but at least one argument was not -1,
108 so we are required to update ctime. Since lchown succeeded,
109 we assume that lchmod will do likewise. But if the system
110 lacks lchmod and lutimes, we are out of luck. Oh well. */
111 result = lchmod (file, st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO
112 | S_ISUID | S_ISGID | S_ISVTX));
119 #endif /* HAVE_LCHOWN */