OpenCoverage

dirchownmod.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/dirchownmod.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* Change the ownership and mode bits of a directory.-
2-
3 Copyright (C) 2006-2018 Free Software Foundation, Inc.-
4-
5 This program is free software: you can redistribute it and/or modify-
6 it under the terms of the GNU General Public License as published by-
7 the Free Software Foundation; either version 3 of the License, or-
8 (at your option) any later version.-
9-
10 This program is distributed in the hope that it will be useful,-
11 but WITHOUT ANY WARRANTY; without even the implied warranty of-
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
13 GNU General Public License for more details.-
14-
15 You should have received a copy of the GNU General Public License-
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
17-
18/* Written by Paul Eggert. */-
19-
20#include <config.h>-
21-
22#include "dirchownmod.h"-
23-
24#include <errno.h>-
25#include <sys/types.h>-
26#include <sys/stat.h>-
27#include <unistd.h>-
28-
29#include "stat-macros.h"-
30-
31#ifndef HAVE_FCHMOD-
32# define HAVE_FCHMOD 0-
33# undef fchmod-
34# define fchmod(fd, mode) (-1)-
35#endif-
36-
37/* Change the ownership and mode bits of a directory. If FD is-
38 nonnegative, it should be a file descriptor associated with the-
39 directory; close it before returning. DIR is the name of the-
40 directory.-
41-
42 If MKDIR_MODE is not (mode_t) -1, mkdir (DIR, MKDIR_MODE) has just-
43 been executed successfully with umask zero, so DIR should be a-
44 directory (not a symbolic link).-
45-
46 First, set the file's owner to OWNER and group to GROUP, but leave-
47 the owner alone if OWNER is (uid_t) -1, and similarly for GROUP.-
48-
49 Then, set the file's mode bits to MODE, except preserve any of the-
50 bits that correspond to zero bits in MODE_BITS. In other words,-
51 MODE_BITS is a mask that specifies which of the file's mode bits-
52 should be set or cleared. MODE should be a subset of MODE_BITS,-
53 which in turn should be a subset of CHMOD_MODE_BITS.-
54-
55 This implementation assumes the current umask is zero.-
56-
57 Return 0 if successful, -1 (setting errno) otherwise. Unsuccessful-
58 calls may do the chown but not the chmod. */-
59-
60int-
61dirchownmod (int fd, char const *dir, mode_t mkdir_mode,-
62 uid_t owner, gid_t group,-
63 mode_t mode, mode_t mode_bits)-
64{-
65 struct stat st;-
66 int result = (fd < 0 ? stat (dir, &st) : fstat (fd, &st));
fd < 0Description
TRUEnever evaluated
FALSEevaluated 9 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
0-9
67-
68 if (result == 0)
result == 0Description
TRUEevaluated 9 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEnever evaluated
0-9
69 {-
70 mode_t dir_mode = st.st_mode;-
71-
72 /* Check whether DIR is a directory. If FD is nonnegative, this-
73 check avoids changing the ownership and mode bits of the-
74 wrong file in many cases. This doesn't fix all the race-
75 conditions, but it is better than nothing. */-
76 if (! S_ISDIR (dir_mode))
! (((( dir_mod... == (0040000))Description
TRUEnever evaluated
FALSEevaluated 9 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
0-9
77 {-
78 errno = ENOTDIR;-
79 result = -1;-
80 }
never executed: end of block
0
81 else-
82 {-
83 /* If at least one of the S_IXUGO bits are set, chown might-
84 clear the S_ISUID and S_SGID bits. Keep track of any-
85 file mode bits whose values are indeterminate due to this-
86 issue. */-
87 mode_t indeterminate = 0;-
88-
89 /* On some systems, chown clears S_ISUID and S_ISGID, so do-
90 chown before chmod. On older System V hosts, ordinary-
91 users can give their files away via chown; don't worry-
92 about that here, since users shouldn't do that. */-
93-
94 if ((owner != (uid_t) -1 && owner != st.st_uid)
owner != (uid_t) -1Description
TRUEnever evaluated
FALSEevaluated 9 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
owner != st.st_uidDescription
TRUEnever evaluated
FALSEnever evaluated
0-9
95 || (group != (gid_t) -1 && group != st.st_gid))
group != (gid_t) -1Description
TRUEnever evaluated
FALSEevaluated 9 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
group != st.st_gidDescription
TRUEnever evaluated
FALSEnever evaluated
0-9
96 {-
97 result = (0 <= fd
0 <= fdDescription
TRUEnever evaluated
FALSEnever evaluated
0
98 ? fchown (fd, owner, group)-
99 : mkdir_mode != (mode_t) -1
mkdir_mode != (mode_t) -1Description
TRUEnever evaluated
FALSEnever evaluated
0
100 ? lchown (dir, owner, group)-
101 : chown (dir, owner, group));-
102-
103 /* Either the user cares about an indeterminate bit and-
104 it'll be set properly by chmod below, or the user-
105 doesn't care and it's OK to use the bit's pre-chown-
106 value. So there's no need to re-stat DIR here. */-
107-
108 if (result == 0 && (dir_mode & S_IXUGO))
result == 0Description
TRUEnever evaluated
FALSEnever evaluated
(dir_mode & (0...>> 3) >> 3)) )Description
TRUEnever evaluated
FALSEnever evaluated
0
109 indeterminate = dir_mode & (S_ISUID | S_ISGID);
never executed: indeterminate = dir_mode & ( 04000 | 02000 );
0
110 }
never executed: end of block
0
111-
112 /* If the file mode bits might not be right, use chmod to-
113 change them. Don't change bits the user doesn't care-
114 about. */-
115 if (result == 0 && (((dir_mode ^ mode) | indeterminate) & mode_bits))
result == 0Description
TRUEevaluated 9 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEnever evaluated
(((dir_mode ^ ...) & mode_bits)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • ginstall
FALSEevaluated 7 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
0-9
116 {-
117 mode_t chmod_mode =-
118 mode | (dir_mode & CHMOD_MODE_BITS & ~mode_bits);-
119 result = (HAVE_FCHMOD && 0 <= fd
0 <= fdDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • ginstall
FALSEnever evaluated
0-2
120 ? fchmod (fd, chmod_mode)-
121 : mkdir_mode != (mode_t) -1
mkdir_mode != (mode_t) -1Description
TRUEnever evaluated
FALSEnever evaluated
0
122 ? lchmod (dir, chmod_mode)-
123 : chmod (dir, chmod_mode));-
124 }
executed 2 times by 1 test: end of block
Executed by:
  • ginstall
2
125 }
executed 9 times by 2 tests: end of block
Executed by:
  • ginstall
  • mkdir
9
126 }-
127-
128 if (0 <= fd)
0 <= fdDescription
TRUEevaluated 9 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEnever evaluated
0-9
129 {-
130 if (result == 0)
result == 0Description
TRUEevaluated 9 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEnever evaluated
0-9
131 result = close (fd);
executed 9 times by 2 tests: result = close (fd);
Executed by:
  • ginstall
  • mkdir
9
132 else-
133 {-
134 int e = errno;-
135 close (fd);-
136 errno = e;-
137 }
never executed: end of block
0
138 }-
139-
140 return result;
executed 9 times by 2 tests: return result;
Executed by:
  • ginstall
  • mkdir
9
141}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2