Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/bash/src/builtins/umask.def |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | This file is umask.def, from which is created umask.c. | - | ||||||||||||
2 | It implements the builtin "umask" in Bash. | - | ||||||||||||
3 | - | |||||||||||||
4 | Copyright (C) 1987-2015 Free Software Foundation, Inc. | - | ||||||||||||
5 | - | |||||||||||||
6 | This file is part of GNU Bash, the Bourne Again SHell. | - | ||||||||||||
7 | - | |||||||||||||
8 | Bash 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. | - | ||||||||||||
12 | - | |||||||||||||
13 | Bash 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. | - | ||||||||||||
17 | - | |||||||||||||
18 | You should have received a copy of the GNU General Public License | - | ||||||||||||
19 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | - | ||||||||||||
20 | - | |||||||||||||
21 | $PRODUCES umask.c | - | ||||||||||||
22 | - | |||||||||||||
23 | $BUILTIN umask | - | ||||||||||||
24 | $FUNCTION umask_builtin | - | ||||||||||||
25 | $SHORT_DOC umask [-p] [-S] [mode] | - | ||||||||||||
26 | Display or set file mode mask. | - | ||||||||||||
27 | - | |||||||||||||
28 | Sets the user file-creation mask to MODE. If MODE is omitted, prints | - | ||||||||||||
29 | the current value of the mask. | - | ||||||||||||
30 | - | |||||||||||||
31 | If MODE begins with a digit, it is interpreted as an octal number; | - | ||||||||||||
32 | otherwise it is a symbolic mode string like that accepted by chmod(1). | - | ||||||||||||
33 | - | |||||||||||||
34 | Options: | - | ||||||||||||
35 | -p if MODE is omitted, output in a form that may be reused as input | - | ||||||||||||
36 | -S makes the output symbolic; otherwise an octal number is output | - | ||||||||||||
37 | - | |||||||||||||
38 | Exit Status: | - | ||||||||||||
39 | Returns success unless MODE is invalid or an invalid option is given. | - | ||||||||||||
40 | $END | - | ||||||||||||
41 | - | |||||||||||||
42 | #include <config.h> | - | ||||||||||||
43 | - | |||||||||||||
44 | #include "../bashtypes.h" | - | ||||||||||||
45 | #include "filecntl.h" | - | ||||||||||||
46 | #if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) | - | ||||||||||||
47 | # include <sys/file.h> | - | ||||||||||||
48 | #endif | - | ||||||||||||
49 | - | |||||||||||||
50 | #if defined (HAVE_UNISTD_H) | - | ||||||||||||
51 | #include <unistd.h> | - | ||||||||||||
52 | #endif | - | ||||||||||||
53 | - | |||||||||||||
54 | #include <stdio.h> | - | ||||||||||||
55 | #include <chartypes.h> | - | ||||||||||||
56 | - | |||||||||||||
57 | #include "../bashintl.h" | - | ||||||||||||
58 | - | |||||||||||||
59 | #include "../shell.h" | - | ||||||||||||
60 | #include "posixstat.h" | - | ||||||||||||
61 | #include "common.h" | - | ||||||||||||
62 | #include "bashgetopt.h" | - | ||||||||||||
63 | - | |||||||||||||
64 | /* **************************************************************** */ | - | ||||||||||||
65 | /* */ | - | ||||||||||||
66 | /* UMASK Builtin and Helpers */ | - | ||||||||||||
67 | /* */ | - | ||||||||||||
68 | /* **************************************************************** */ | - | ||||||||||||
69 | - | |||||||||||||
70 | static void print_symbolic_umask __P((mode_t)); | - | ||||||||||||
71 | static int symbolic_umask __P((WORD_LIST *)); | - | ||||||||||||
72 | - | |||||||||||||
73 | /* Set or display the mask used by the system when creating files. Flag | - | ||||||||||||
74 | of -S means display the umask in a symbolic mode. */ | - | ||||||||||||
75 | int | - | ||||||||||||
76 | umask_builtin (list) | - | ||||||||||||
77 | WORD_LIST *list; | - | ||||||||||||
78 | { | - | ||||||||||||
79 | int print_symbolically, opt, umask_value, pflag; | - | ||||||||||||
80 | mode_t umask_arg; | - | ||||||||||||
81 | - | |||||||||||||
82 | print_symbolically = pflag = 0; | - | ||||||||||||
83 | reset_internal_getopt (); | - | ||||||||||||
84 | while ((opt = internal_getopt (list, "Sp")) != -1)
| 78-121 | ||||||||||||
85 | { | - | ||||||||||||
86 | switch (opt) | - | ||||||||||||
87 | { | - | ||||||||||||
88 | case 'S': executed 55 times by 1 test: case 'S': Executed by:
| 55 | ||||||||||||
89 | print_symbolically++; | - | ||||||||||||
90 | break; executed 55 times by 1 test: break; Executed by:
| 55 | ||||||||||||
91 | case 'p': executed 18 times by 1 test: case 'p': Executed by:
| 18 | ||||||||||||
92 | pflag++; | - | ||||||||||||
93 | break; executed 18 times by 1 test: break; Executed by:
| 18 | ||||||||||||
94 | CASE_HELPOPT; never executed: return (258); never executed: case -99: | 0 | ||||||||||||
95 | default: executed 5 times by 1 test: default: Executed by:
| 5 | ||||||||||||
96 | builtin_usage (); | - | ||||||||||||
97 | return (EX_USAGE); executed 5 times by 1 test: return (258); Executed by:
| 5 | ||||||||||||
98 | } | - | ||||||||||||
99 | } | - | ||||||||||||
100 | - | |||||||||||||
101 | list = loptend; | - | ||||||||||||
102 | - | |||||||||||||
103 | if (list)
| 55-66 | ||||||||||||
104 | { | - | ||||||||||||
105 | if (DIGIT (*list->word->word))
| 0-55 | ||||||||||||
106 | { | - | ||||||||||||
107 | umask_value = read_octal (list->word->word); | - | ||||||||||||
108 | - | |||||||||||||
109 | /* Note that other shells just let you set the umask to zero | - | ||||||||||||
110 | by specifying a number out of range. This is a problem | - | ||||||||||||
111 | with those shells. We don't change the umask if the input | - | ||||||||||||
112 | is lousy. */ | - | ||||||||||||
113 | if (umask_value == -1)
| 5-27 | ||||||||||||
114 | { | - | ||||||||||||
115 | sh_erange (list->word->word, _("octal number")); | - | ||||||||||||
116 | return (EXECUTION_FAILURE); executed 5 times by 1 test: return (1); Executed by:
| 5 | ||||||||||||
117 | } | - | ||||||||||||
118 | } executed 27 times by 1 test: end of block Executed by:
| 27 | ||||||||||||
119 | else | - | ||||||||||||
120 | { | - | ||||||||||||
121 | umask_value = symbolic_umask (list); | - | ||||||||||||
122 | if (umask_value == -1)
| 9-14 | ||||||||||||
123 | return (EXECUTION_FAILURE); executed 14 times by 1 test: return (1); Executed by:
| 14 | ||||||||||||
124 | } executed 9 times by 1 test: end of block Executed by:
| 9 | ||||||||||||
125 | umask_arg = (mode_t)umask_value; | - | ||||||||||||
126 | umask (umask_arg); | - | ||||||||||||
127 | if (print_symbolically)
| 9-27 | ||||||||||||
128 | print_symbolic_umask (umask_arg); executed 9 times by 1 test: print_symbolic_umask (umask_arg); Executed by:
| 9 | ||||||||||||
129 | } executed 36 times by 1 test: end of block Executed by:
| 36 | ||||||||||||
130 | else /* Display the UMASK for this user. */ | - | ||||||||||||
131 | { | - | ||||||||||||
132 | umask_arg = umask (022); | - | ||||||||||||
133 | umask (umask_arg); | - | ||||||||||||
134 | - | |||||||||||||
135 | if (pflag)
| 18-48 | ||||||||||||
136 | printf ("umask%s ", (print_symbolically ? " -S" : "")); executed 18 times by 1 test: printf ("umask%s ", (print_symbolically ? " -S" : "")); Executed by:
| 18 | ||||||||||||
137 | if (print_symbolically)
| 30-36 | ||||||||||||
138 | print_symbolic_umask (umask_arg); executed 36 times by 1 test: print_symbolic_umask (umask_arg); Executed by:
| 36 | ||||||||||||
139 | else | - | ||||||||||||
140 | printf ("%04lo\n", (unsigned long)umask_arg); executed 30 times by 1 test: printf ("%04lo\n", (unsigned long)umask_arg); Executed by:
| 30 | ||||||||||||
141 | } | - | ||||||||||||
142 | - | |||||||||||||
143 | return (sh_chkwrite (EXECUTION_SUCCESS)); executed 102 times by 1 test: return (sh_chkwrite (0)); Executed by:
| 102 | ||||||||||||
144 | } | - | ||||||||||||
145 | - | |||||||||||||
146 | /* Print the umask in a symbolic form. In the output, a letter is | - | ||||||||||||
147 | printed if the corresponding bit is clear in the umask. */ | - | ||||||||||||
148 | static void | - | ||||||||||||
149 | #if defined (__STDC__) | - | ||||||||||||
150 | print_symbolic_umask (mode_t um) | - | ||||||||||||
151 | #else | - | ||||||||||||
152 | print_symbolic_umask (um) | - | ||||||||||||
153 | mode_t um; | - | ||||||||||||
154 | #endif | - | ||||||||||||
155 | { | - | ||||||||||||
156 | char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */ | - | ||||||||||||
157 | int i; | - | ||||||||||||
158 | - | |||||||||||||
159 | i = 0; | - | ||||||||||||
160 | if ((um & S_IRUSR) == 0)
| 0-45 | ||||||||||||
161 | ubits[i++] = 'r'; executed 45 times by 1 test: ubits[i++] = 'r'; Executed by:
| 45 | ||||||||||||
162 | if ((um & S_IWUSR) == 0)
| 0-45 | ||||||||||||
163 | ubits[i++] = 'w'; executed 45 times by 1 test: ubits[i++] = 'w'; Executed by:
| 45 | ||||||||||||
164 | if ((um & S_IXUSR) == 0)
| 0-45 | ||||||||||||
165 | ubits[i++] = 'x'; executed 45 times by 1 test: ubits[i++] = 'x'; Executed by:
| 45 | ||||||||||||
166 | ubits[i] = '\0'; | - | ||||||||||||
167 | - | |||||||||||||
168 | i = 0; | - | ||||||||||||
169 | if ((um & S_IRGRP) == 0)
| 0-45 | ||||||||||||
170 | gbits[i++] = 'r'; executed 45 times by 1 test: gbits[i++] = 'r'; Executed by:
| 45 | ||||||||||||
171 | if ((um & S_IWGRP) == 0)
| 9-36 | ||||||||||||
172 | gbits[i++] = 'w'; executed 36 times by 1 test: gbits[i++] = 'w'; Executed by:
| 36 | ||||||||||||
173 | if ((um & S_IXGRP) == 0)
| 0-45 | ||||||||||||
174 | gbits[i++] = 'x'; executed 45 times by 1 test: gbits[i++] = 'x'; Executed by:
| 45 | ||||||||||||
175 | gbits[i] = '\0'; | - | ||||||||||||
176 | - | |||||||||||||
177 | i = 0; | - | ||||||||||||
178 | if ((um & S_IROTH) == 0)
| 0-45 | ||||||||||||
179 | obits[i++] = 'r'; executed 45 times by 1 test: obits[i++] = 'r'; Executed by:
| 45 | ||||||||||||
180 | if ((um & S_IWOTH) == 0)
| 9-36 | ||||||||||||
181 | obits[i++] = 'w'; executed 9 times by 1 test: obits[i++] = 'w'; Executed by:
| 9 | ||||||||||||
182 | if ((um & S_IXOTH) == 0)
| 0-45 | ||||||||||||
183 | obits[i++] = 'x'; executed 45 times by 1 test: obits[i++] = 'x'; Executed by:
| 45 | ||||||||||||
184 | obits[i] = '\0'; | - | ||||||||||||
185 | - | |||||||||||||
186 | printf ("u=%s,g=%s,o=%s\n", ubits, gbits, obits); | - | ||||||||||||
187 | } executed 45 times by 1 test: end of block Executed by:
| 45 | ||||||||||||
188 | - | |||||||||||||
189 | int | - | ||||||||||||
190 | parse_symbolic_mode (mode, initial_bits) | - | ||||||||||||
191 | char *mode; | - | ||||||||||||
192 | int initial_bits; | - | ||||||||||||
193 | { | - | ||||||||||||
194 | int who, op, perm, bits, c; | - | ||||||||||||
195 | char *s; | - | ||||||||||||
196 | - | |||||||||||||
197 | for (s = mode, bits = initial_bits;;) | - | ||||||||||||
198 | { | - | ||||||||||||
199 | who = op = perm = 0; | - | ||||||||||||
200 | - | |||||||||||||
201 | /* Parse the `who' portion of the symbolic mode clause. */ | - | ||||||||||||
202 | while (member (*s, "agou"))
| 0-82 | ||||||||||||
203 | { | - | ||||||||||||
204 | switch (c = *s++) | - | ||||||||||||
205 | { | - | ||||||||||||
206 | case 'u': executed 19 times by 1 test: case 'u': Executed by:
| 19 | ||||||||||||
207 | who |= S_IRWXU; | - | ||||||||||||
208 | continue; executed 19 times by 1 test: continue; Executed by:
| 19 | ||||||||||||
209 | case 'g': executed 13 times by 1 test: case 'g': Executed by:
| 13 | ||||||||||||
210 | who |= S_IRWXG; | - | ||||||||||||
211 | continue; executed 13 times by 1 test: continue; Executed by:
| 13 | ||||||||||||
212 | case 'o': executed 9 times by 1 test: case 'o': Executed by:
| 9 | ||||||||||||
213 | who |= S_IRWXO; | - | ||||||||||||
214 | continue; executed 9 times by 1 test: continue; Executed by:
| 9 | ||||||||||||
215 | case 'a': never executed: case 'a': | 0 | ||||||||||||
216 | who |= S_IRWXU | S_IRWXG | S_IRWXO; | - | ||||||||||||
217 | continue; never executed: continue; | 0 | ||||||||||||
218 | default: never executed: default: | 0 | ||||||||||||
219 | break; never executed: break; | 0 | ||||||||||||
220 | } | - | ||||||||||||
221 | } | - | ||||||||||||
222 | - | |||||||||||||
223 | /* The operation is now sitting in *s. */ | - | ||||||||||||
224 | op = *s++; | - | ||||||||||||
225 | switch (op) | - | ||||||||||||
226 | { | - | ||||||||||||
227 | case '+': never executed: case '+': | 0 | ||||||||||||
228 | case '-': never executed: case '-': | 0 | ||||||||||||
229 | case '=': executed 36 times by 1 test: case '=': Executed by:
| 36 | ||||||||||||
230 | break; executed 36 times by 1 test: break; Executed by:
| 36 | ||||||||||||
231 | default: executed 5 times by 1 test: default: Executed by:
| 5 | ||||||||||||
232 | builtin_error (_("`%c': invalid symbolic mode operator"), op); | - | ||||||||||||
233 | return (-1); executed 5 times by 1 test: return (-1); Executed by:
| 5 | ||||||||||||
234 | } | - | ||||||||||||
235 | - | |||||||||||||
236 | /* Parse out the `perm' section of the symbolic mode clause. */ | - | ||||||||||||
237 | while (member (*s, "rwx"))
| 9-114 | ||||||||||||
238 | { | - | ||||||||||||
239 | c = *s++; | - | ||||||||||||
240 | - | |||||||||||||
241 | switch (c) | - | ||||||||||||
242 | { | - | ||||||||||||
243 | case 'r': executed 32 times by 1 test: case 'r': Executed by:
| 32 | ||||||||||||
244 | perm |= S_IRUGO; | - | ||||||||||||
245 | break; executed 32 times by 1 test: break; Executed by:
| 32 | ||||||||||||
246 | case 'w': executed 23 times by 1 test: case 'w': Executed by:
| 23 | ||||||||||||
247 | perm |= S_IWUGO; | - | ||||||||||||
248 | break; executed 23 times by 1 test: break; Executed by:
| 23 | ||||||||||||
249 | case 'x': executed 32 times by 1 test: case 'x': Executed by:
| 32 | ||||||||||||
250 | perm |= S_IXUGO; | - | ||||||||||||
251 | break; executed 32 times by 1 test: break; Executed by:
| 32 | ||||||||||||
252 | } | - | ||||||||||||
253 | } executed 87 times by 1 test: end of block Executed by:
| 87 | ||||||||||||
254 | - | |||||||||||||
255 | /* Now perform the operation or return an error for a | - | ||||||||||||
256 | bad permission string. */ | - | ||||||||||||
257 | if (!*s || *s == ',')
| 9-27 | ||||||||||||
258 | { | - | ||||||||||||
259 | if (who)
| 0-27 | ||||||||||||
260 | perm &= who; executed 27 times by 1 test: perm &= who; Executed by:
| 27 | ||||||||||||
261 | - | |||||||||||||
262 | switch (op) | - | ||||||||||||
263 | { | - | ||||||||||||
264 | case '+': never executed: case '+': | 0 | ||||||||||||
265 | bits |= perm; | - | ||||||||||||
266 | break; never executed: break; | 0 | ||||||||||||
267 | case '-': never executed: case '-': | 0 | ||||||||||||
268 | bits &= ~perm; | - | ||||||||||||
269 | break; never executed: break; | 0 | ||||||||||||
270 | case '=': executed 27 times by 1 test: case '=': Executed by:
| 27 | ||||||||||||
271 | if (who == 0)
| 0-27 | ||||||||||||
272 | who = S_IRWXU | S_IRWXG | S_IRWXO; never executed: who = (0400|0200|0100) | ((0400|0200|0100) >> 3) | (((0400|0200|0100) >> 3) >> 3) ; | 0 | ||||||||||||
273 | bits &= ~who; | - | ||||||||||||
274 | bits |= perm; | - | ||||||||||||
275 | break; executed 27 times by 1 test: break; Executed by:
| 27 | ||||||||||||
276 | - | |||||||||||||
277 | /* No other values are possible. */ | - | ||||||||||||
278 | } | - | ||||||||||||
279 | - | |||||||||||||
280 | if (*s == '\0')
| 9-18 | ||||||||||||
281 | break; executed 9 times by 1 test: break; Executed by:
| 9 | ||||||||||||
282 | else | - | ||||||||||||
283 | s++; /* skip past ',' */ executed 18 times by 1 test: s++; Executed by:
| 18 | ||||||||||||
284 | } | - | ||||||||||||
285 | else | - | ||||||||||||
286 | { | - | ||||||||||||
287 | builtin_error (_("`%c': invalid symbolic mode character"), *s); | - | ||||||||||||
288 | return (-1); executed 9 times by 1 test: return (-1); Executed by:
| 9 | ||||||||||||
289 | } | - | ||||||||||||
290 | } | - | ||||||||||||
291 | - | |||||||||||||
292 | return (bits); executed 9 times by 1 test: return (bits); Executed by:
| 9 | ||||||||||||
293 | } | - | ||||||||||||
294 | - | |||||||||||||
295 | /* Set the umask from a symbolic mode string similar to that accepted | - | ||||||||||||
296 | by chmod. If the -S argument is given, then print the umask in a | - | ||||||||||||
297 | symbolic form. */ | - | ||||||||||||
298 | static int | - | ||||||||||||
299 | symbolic_umask (list) | - | ||||||||||||
300 | WORD_LIST *list; | - | ||||||||||||
301 | { | - | ||||||||||||
302 | int um, bits; | - | ||||||||||||
303 | - | |||||||||||||
304 | /* Get the initial umask. Don't change it yet. */ | - | ||||||||||||
305 | um = umask (022); | - | ||||||||||||
306 | umask (um); | - | ||||||||||||
307 | - | |||||||||||||
308 | /* All work is done with the complement of the umask -- it's | - | ||||||||||||
309 | more intuitive and easier to deal with. It is complemented | - | ||||||||||||
310 | again before being returned. */ | - | ||||||||||||
311 | bits = parse_symbolic_mode (list->word->word, ~um & 0777); | - | ||||||||||||
312 | if (bits == -1)
| 9-14 | ||||||||||||
313 | return (-1); executed 14 times by 1 test: return (-1); Executed by:
| 14 | ||||||||||||
314 | - | |||||||||||||
315 | um = ~bits & 0777; | - | ||||||||||||
316 | return (um); executed 9 times by 1 test: return (um); Executed by:
| 9 | ||||||||||||
317 | } | - | ||||||||||||
Source code | Switch to Preprocessed file |