chmod.c revision 1.1.1.3 1 1.1 mrg /* Implementation of the CHMOD intrinsic.
2 1.1.1.3 mrg Copyright (C) 2006-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Franois-Xavier Coudert <coudert (at) clipper.ens.fr>
4 1.1 mrg
5 1.1 mrg This file is part of the GNU Fortran runtime library (libgfortran).
6 1.1 mrg
7 1.1 mrg Libgfortran is free software; you can redistribute it and/or
8 1.1 mrg modify it under the terms of the GNU General Public
9 1.1 mrg License as published by the Free Software Foundation; either
10 1.1 mrg version 3 of the License, or (at your option) any later version.
11 1.1 mrg
12 1.1 mrg Libgfortran is distributed in the hope that it will be useful,
13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 mrg GNU General Public License for more details.
16 1.1 mrg
17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
18 1.1 mrg permissions described in the GCC Runtime Library Exception, version
19 1.1 mrg 3.1, as published by the Free Software Foundation.
20 1.1 mrg
21 1.1 mrg You should have received a copy of the GNU General Public License and
22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 1.1 mrg <http://www.gnu.org/licenses/>. */
25 1.1 mrg
26 1.1 mrg #include "libgfortran.h"
27 1.1 mrg
28 1.1 mrg #if defined(HAVE_SYS_STAT_H)
29 1.1 mrg
30 1.1 mrg #include <sys/stat.h> /* For stat, chmod and umask. */
31 1.1 mrg
32 1.1 mrg
33 1.1 mrg /* INTEGER FUNCTION CHMOD (NAME, MODE)
34 1.1 mrg CHARACTER(len=*), INTENT(IN) :: NAME, MODE
35 1.1 mrg
36 1.1 mrg Sets the file permission "chmod" using a mode string.
37 1.1 mrg
38 1.1 mrg For MinGW, only _S_IWRITE and _S_IREAD are supported. To set those,
39 1.1 mrg only the user attributes are used.
40 1.1 mrg
41 1.1 mrg The mode string allows for the same arguments as POSIX's chmod utility.
42 1.1 mrg a) string containing an octal number.
43 1.1 mrg b) Comma separated list of clauses of the form:
44 1.1 mrg [<who-list>]<op>[<perm-list>|<permcopy>][<op>[<perm-list>|<permcopy>],...]
45 1.1 mrg <who> - 'u', 'g', 'o', 'a'
46 1.1 mrg <op> - '+', '-', '='
47 1.1 mrg <perm> - 'r', 'w', 'x', 'X', 's', t'
48 1.1 mrg If <op> is not followed by a perm-list or permcopy, '-' and '+' do not
49 1.1 mrg change the mode while '=' clears all file mode bits. 'u' stands for the
50 1.1 mrg user permissions, 'g' for the group and 'o' for the permissions for others.
51 1.1 mrg 'a' is equivalent to 'ugo'. '+' sets the given permission in addition to
52 1.1 mrg the ones of the file, '-' unsets the given permissions of the file, while
53 1.1 mrg '=' sets the file to that mode. 'r' sets the read, 'w' the write, and
54 1.1 mrg 'x' the execute mode. 'X' sets the execute bit if the file is a directory
55 1.1 mrg or if the user, group or other executable bit is set. 't' sets the sticky
56 1.1 mrg bit, 's' (un)sets the and/or S_ISUID/S_ISGID bit.
57 1.1 mrg
58 1.1 mrg Note that if <who> is omitted, the permissions are filtered by the umask.
59 1.1 mrg
60 1.1 mrg A return value of 0 indicates success, -1 an error of chmod() while 1
61 1.1 mrg indicates a mode parsing error. */
62 1.1 mrg
63 1.1 mrg
64 1.1 mrg static int
65 1.1 mrg chmod_internal (char *file, char *mode, gfc_charlen_type mode_len)
66 1.1 mrg {
67 1.1 mrg bool ugo[3];
68 1.1 mrg bool rwxXstugo[9];
69 1.1 mrg int set_mode, part;
70 1.1 mrg bool honor_umask, continue_clause = false;
71 1.1 mrg #ifndef __MINGW32__
72 1.1 mrg bool is_dir;
73 1.1 mrg #endif
74 1.1.1.3 mrg #ifdef HAVE_UMASK
75 1.1.1.3 mrg mode_t mode_mask;
76 1.1.1.3 mrg #endif
77 1.1.1.3 mrg mode_t file_mode, new_mode;
78 1.1 mrg struct stat stat_buf;
79 1.1 mrg
80 1.1 mrg if (mode_len == 0)
81 1.1 mrg return 1;
82 1.1 mrg
83 1.1 mrg if (mode[0] >= '0' && mode[0] <= '9')
84 1.1 mrg {
85 1.1 mrg unsigned fmode;
86 1.1 mrg if (sscanf (mode, "%o", &fmode) != 1)
87 1.1 mrg return 1;
88 1.1 mrg return chmod (file, (mode_t) fmode);
89 1.1 mrg }
90 1.1 mrg
91 1.1 mrg /* Read the current file mode. */
92 1.1 mrg if (stat (file, &stat_buf))
93 1.1 mrg return 1;
94 1.1 mrg
95 1.1 mrg file_mode = stat_buf.st_mode & ~S_IFMT;
96 1.1 mrg #ifndef __MINGW32__
97 1.1 mrg is_dir = stat_buf.st_mode & S_IFDIR;
98 1.1 mrg #endif
99 1.1 mrg
100 1.1 mrg #ifdef HAVE_UMASK
101 1.1 mrg /* Obtain the umask without distroying the setting. */
102 1.1 mrg mode_mask = 0;
103 1.1 mrg mode_mask = umask (mode_mask);
104 1.1 mrg (void) umask (mode_mask);
105 1.1 mrg #else
106 1.1 mrg honor_umask = false;
107 1.1 mrg #endif
108 1.1 mrg
109 1.1 mrg for (gfc_charlen_type i = 0; i < mode_len; i++)
110 1.1 mrg {
111 1.1 mrg if (!continue_clause)
112 1.1 mrg {
113 1.1 mrg ugo[0] = false;
114 1.1 mrg ugo[1] = false;
115 1.1 mrg ugo[2] = false;
116 1.1 mrg #ifdef HAVE_UMASK
117 1.1 mrg honor_umask = true;
118 1.1 mrg #endif
119 1.1 mrg }
120 1.1 mrg continue_clause = false;
121 1.1 mrg rwxXstugo[0] = false;
122 1.1 mrg rwxXstugo[1] = false;
123 1.1 mrg rwxXstugo[2] = false;
124 1.1 mrg rwxXstugo[3] = false;
125 1.1 mrg rwxXstugo[4] = false;
126 1.1 mrg rwxXstugo[5] = false;
127 1.1 mrg rwxXstugo[6] = false;
128 1.1 mrg rwxXstugo[7] = false;
129 1.1 mrg rwxXstugo[8] = false;
130 1.1 mrg part = 0;
131 1.1 mrg set_mode = -1;
132 1.1 mrg for (; i < mode_len; i++)
133 1.1 mrg {
134 1.1 mrg switch (mode[i])
135 1.1 mrg {
136 1.1 mrg /* User setting: a[ll]/u[ser]/g[roup]/o[ther]. */
137 1.1 mrg case 'a':
138 1.1 mrg if (part > 1)
139 1.1 mrg return 1;
140 1.1 mrg ugo[0] = true;
141 1.1 mrg ugo[1] = true;
142 1.1 mrg ugo[2] = true;
143 1.1 mrg part = 1;
144 1.1 mrg #ifdef HAVE_UMASK
145 1.1 mrg honor_umask = false;
146 1.1 mrg #endif
147 1.1 mrg break;
148 1.1 mrg case 'u':
149 1.1 mrg if (part == 2)
150 1.1 mrg {
151 1.1 mrg rwxXstugo[6] = true;
152 1.1 mrg part = 4;
153 1.1 mrg break;
154 1.1 mrg }
155 1.1 mrg if (part > 1)
156 1.1 mrg return 1;
157 1.1 mrg ugo[0] = true;
158 1.1 mrg part = 1;
159 1.1 mrg #ifdef HAVE_UMASK
160 1.1 mrg honor_umask = false;
161 1.1 mrg #endif
162 1.1 mrg break;
163 1.1 mrg case 'g':
164 1.1 mrg if (part == 2)
165 1.1 mrg {
166 1.1 mrg rwxXstugo[7] = true;
167 1.1 mrg part = 4;
168 1.1 mrg break;
169 1.1 mrg }
170 1.1 mrg if (part > 1)
171 1.1 mrg return 1;
172 1.1 mrg ugo[1] = true;
173 1.1 mrg part = 1;
174 1.1 mrg #ifdef HAVE_UMASK
175 1.1 mrg honor_umask = false;
176 1.1 mrg #endif
177 1.1 mrg break;
178 1.1 mrg case 'o':
179 1.1 mrg if (part == 2)
180 1.1 mrg {
181 1.1 mrg rwxXstugo[8] = true;
182 1.1 mrg part = 4;
183 1.1 mrg break;
184 1.1 mrg }
185 1.1 mrg if (part > 1)
186 1.1 mrg return 1;
187 1.1 mrg ugo[2] = true;
188 1.1 mrg part = 1;
189 1.1 mrg #ifdef HAVE_UMASK
190 1.1 mrg honor_umask = false;
191 1.1 mrg #endif
192 1.1 mrg break;
193 1.1 mrg
194 1.1 mrg /* Mode setting: =+-. */
195 1.1 mrg case '=':
196 1.1 mrg if (part > 2)
197 1.1 mrg {
198 1.1 mrg continue_clause = true;
199 1.1 mrg i--;
200 1.1 mrg part = 2;
201 1.1 mrg goto clause_done;
202 1.1 mrg }
203 1.1 mrg set_mode = 1;
204 1.1 mrg part = 2;
205 1.1 mrg break;
206 1.1 mrg
207 1.1 mrg case '-':
208 1.1 mrg if (part > 2)
209 1.1 mrg {
210 1.1 mrg continue_clause = true;
211 1.1 mrg i--;
212 1.1 mrg part = 2;
213 1.1 mrg goto clause_done;
214 1.1 mrg }
215 1.1 mrg set_mode = 2;
216 1.1 mrg part = 2;
217 1.1 mrg break;
218 1.1 mrg
219 1.1 mrg case '+':
220 1.1 mrg if (part > 2)
221 1.1 mrg {
222 1.1 mrg continue_clause = true;
223 1.1 mrg i--;
224 1.1 mrg part = 2;
225 1.1 mrg goto clause_done;
226 1.1 mrg }
227 1.1 mrg set_mode = 3;
228 1.1 mrg part = 2;
229 1.1 mrg break;
230 1.1 mrg
231 1.1 mrg /* Permissions: rwxXst - for ugo see above. */
232 1.1 mrg case 'r':
233 1.1 mrg if (part != 2 && part != 3)
234 1.1 mrg return 1;
235 1.1 mrg rwxXstugo[0] = true;
236 1.1 mrg part = 3;
237 1.1 mrg break;
238 1.1 mrg
239 1.1 mrg case 'w':
240 1.1 mrg if (part != 2 && part != 3)
241 1.1 mrg return 1;
242 1.1 mrg rwxXstugo[1] = true;
243 1.1 mrg part = 3;
244 1.1 mrg break;
245 1.1 mrg
246 1.1 mrg case 'x':
247 1.1 mrg if (part != 2 && part != 3)
248 1.1 mrg return 1;
249 1.1 mrg rwxXstugo[2] = true;
250 1.1 mrg part = 3;
251 1.1 mrg break;
252 1.1 mrg
253 1.1 mrg case 'X':
254 1.1 mrg if (part != 2 && part != 3)
255 1.1 mrg return 1;
256 1.1 mrg rwxXstugo[3] = true;
257 1.1 mrg part = 3;
258 1.1 mrg break;
259 1.1 mrg
260 1.1 mrg case 's':
261 1.1 mrg if (part != 2 && part != 3)
262 1.1 mrg return 1;
263 1.1 mrg rwxXstugo[4] = true;
264 1.1 mrg part = 3;
265 1.1 mrg break;
266 1.1 mrg
267 1.1 mrg case 't':
268 1.1 mrg if (part != 2 && part != 3)
269 1.1 mrg return 1;
270 1.1 mrg rwxXstugo[5] = true;
271 1.1 mrg part = 3;
272 1.1 mrg break;
273 1.1 mrg
274 1.1.1.3 mrg /* Trailing blanks are valid in Fortran. */
275 1.1 mrg case ' ':
276 1.1 mrg for (i++; i < mode_len; i++)
277 1.1 mrg if (mode[i] != ' ')
278 1.1 mrg break;
279 1.1 mrg if (i != mode_len)
280 1.1 mrg return 1;
281 1.1 mrg goto clause_done;
282 1.1 mrg
283 1.1 mrg case ',':
284 1.1 mrg goto clause_done;
285 1.1 mrg
286 1.1 mrg default:
287 1.1 mrg return 1;
288 1.1 mrg }
289 1.1 mrg }
290 1.1 mrg
291 1.1 mrg clause_done:
292 1.1 mrg if (part < 2)
293 1.1 mrg return 1;
294 1.1 mrg
295 1.1 mrg new_mode = 0;
296 1.1 mrg
297 1.1 mrg #ifdef __MINGW32__
298 1.1 mrg
299 1.1 mrg /* Read. */
300 1.1 mrg if (rwxXstugo[0] && (ugo[0] || honor_umask))
301 1.1 mrg new_mode |= _S_IREAD;
302 1.1 mrg
303 1.1 mrg /* Write. */
304 1.1 mrg if (rwxXstugo[1] && (ugo[0] || honor_umask))
305 1.1 mrg new_mode |= _S_IWRITE;
306 1.1 mrg
307 1.1 mrg #else
308 1.1 mrg
309 1.1 mrg /* Read. */
310 1.1 mrg if (rwxXstugo[0])
311 1.1 mrg {
312 1.1 mrg if (ugo[0] || honor_umask)
313 1.1 mrg new_mode |= S_IRUSR;
314 1.1 mrg if (ugo[1] || honor_umask)
315 1.1 mrg new_mode |= S_IRGRP;
316 1.1 mrg if (ugo[2] || honor_umask)
317 1.1 mrg new_mode |= S_IROTH;
318 1.1 mrg }
319 1.1 mrg
320 1.1 mrg /* Write. */
321 1.1 mrg if (rwxXstugo[1])
322 1.1 mrg {
323 1.1 mrg if (ugo[0] || honor_umask)
324 1.1 mrg new_mode |= S_IWUSR;
325 1.1 mrg if (ugo[1] || honor_umask)
326 1.1 mrg new_mode |= S_IWGRP;
327 1.1 mrg if (ugo[2] || honor_umask)
328 1.1 mrg new_mode |= S_IWOTH;
329 1.1 mrg }
330 1.1 mrg
331 1.1 mrg /* Execute. */
332 1.1 mrg if (rwxXstugo[2])
333 1.1 mrg {
334 1.1 mrg if (ugo[0] || honor_umask)
335 1.1 mrg new_mode |= S_IXUSR;
336 1.1 mrg if (ugo[1] || honor_umask)
337 1.1 mrg new_mode |= S_IXGRP;
338 1.1 mrg if (ugo[2] || honor_umask)
339 1.1 mrg new_mode |= S_IXOTH;
340 1.1 mrg }
341 1.1 mrg
342 1.1 mrg /* 'X' execute. */
343 1.1 mrg if (rwxXstugo[3]
344 1.1 mrg && (is_dir || (file_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
345 1.1 mrg new_mode |= (S_IXUSR | S_IXGRP | S_IXOTH);
346 1.1 mrg
347 1.1 mrg /* 's'. */
348 1.1 mrg if (rwxXstugo[4])
349 1.1 mrg {
350 1.1 mrg if (ugo[0] || honor_umask)
351 1.1 mrg new_mode |= S_ISUID;
352 1.1 mrg if (ugo[1] || honor_umask)
353 1.1 mrg new_mode |= S_ISGID;
354 1.1 mrg }
355 1.1 mrg
356 1.1 mrg /* As original 'u'. */
357 1.1 mrg if (rwxXstugo[6])
358 1.1 mrg {
359 1.1 mrg if (ugo[1] || honor_umask)
360 1.1 mrg {
361 1.1 mrg if (file_mode & S_IRUSR)
362 1.1 mrg new_mode |= S_IRGRP;
363 1.1 mrg if (file_mode & S_IWUSR)
364 1.1 mrg new_mode |= S_IWGRP;
365 1.1 mrg if (file_mode & S_IXUSR)
366 1.1 mrg new_mode |= S_IXGRP;
367 1.1 mrg }
368 1.1 mrg if (ugo[2] || honor_umask)
369 1.1 mrg {
370 1.1 mrg if (file_mode & S_IRUSR)
371 1.1 mrg new_mode |= S_IROTH;
372 1.1 mrg if (file_mode & S_IWUSR)
373 1.1 mrg new_mode |= S_IWOTH;
374 1.1 mrg if (file_mode & S_IXUSR)
375 1.1 mrg new_mode |= S_IXOTH;
376 1.1 mrg }
377 1.1 mrg }
378 1.1 mrg
379 1.1 mrg /* As original 'g'. */
380 1.1 mrg if (rwxXstugo[7])
381 1.1 mrg {
382 1.1 mrg if (ugo[0] || honor_umask)
383 1.1 mrg {
384 1.1 mrg if (file_mode & S_IRGRP)
385 1.1 mrg new_mode |= S_IRUSR;
386 1.1 mrg if (file_mode & S_IWGRP)
387 1.1 mrg new_mode |= S_IWUSR;
388 1.1 mrg if (file_mode & S_IXGRP)
389 1.1 mrg new_mode |= S_IXUSR;
390 1.1 mrg }
391 1.1 mrg if (ugo[2] || honor_umask)
392 1.1 mrg {
393 1.1 mrg if (file_mode & S_IRGRP)
394 1.1 mrg new_mode |= S_IROTH;
395 1.1 mrg if (file_mode & S_IWGRP)
396 1.1 mrg new_mode |= S_IWOTH;
397 1.1 mrg if (file_mode & S_IXGRP)
398 1.1 mrg new_mode |= S_IXOTH;
399 1.1 mrg }
400 1.1 mrg }
401 1.1 mrg
402 1.1 mrg /* As original 'o'. */
403 1.1 mrg if (rwxXstugo[8])
404 1.1 mrg {
405 1.1 mrg if (ugo[0] || honor_umask)
406 1.1 mrg {
407 1.1 mrg if (file_mode & S_IROTH)
408 1.1 mrg new_mode |= S_IRUSR;
409 1.1 mrg if (file_mode & S_IWOTH)
410 1.1 mrg new_mode |= S_IWUSR;
411 1.1 mrg if (file_mode & S_IXOTH)
412 1.1 mrg new_mode |= S_IXUSR;
413 1.1 mrg }
414 1.1 mrg if (ugo[1] || honor_umask)
415 1.1 mrg {
416 1.1 mrg if (file_mode & S_IROTH)
417 1.1 mrg new_mode |= S_IRGRP;
418 1.1 mrg if (file_mode & S_IWOTH)
419 1.1 mrg new_mode |= S_IWGRP;
420 1.1 mrg if (file_mode & S_IXOTH)
421 1.1 mrg new_mode |= S_IXGRP;
422 1.1 mrg }
423 1.1 mrg }
424 1.1 mrg #endif /* __MINGW32__ */
425 1.1 mrg
426 1.1 mrg #ifdef HAVE_UMASK
427 1.1 mrg if (honor_umask)
428 1.1 mrg new_mode &= ~mode_mask;
429 1.1 mrg #endif
430 1.1 mrg
431 1.1 mrg if (set_mode == 1)
432 1.1 mrg {
433 1.1 mrg #ifdef __MINGW32__
434 1.1 mrg if (ugo[0] || honor_umask)
435 1.1 mrg file_mode = (file_mode & ~(_S_IWRITE | _S_IREAD))
436 1.1 mrg | (new_mode & (_S_IWRITE | _S_IREAD));
437 1.1 mrg #else
438 1.1 mrg /* Set '='. */
439 1.1 mrg if ((ugo[0] || honor_umask) && !rwxXstugo[6])
440 1.1 mrg file_mode = (file_mode & ~(S_ISUID | S_IRUSR | S_IWUSR | S_IXUSR))
441 1.1 mrg | (new_mode & (S_ISUID | S_IRUSR | S_IWUSR | S_IXUSR));
442 1.1 mrg if ((ugo[1] || honor_umask) && !rwxXstugo[7])
443 1.1 mrg file_mode = (file_mode & ~(S_ISGID | S_IRGRP | S_IWGRP | S_IXGRP))
444 1.1 mrg | (new_mode & (S_ISGID | S_IRGRP | S_IWGRP | S_IXGRP));
445 1.1 mrg if ((ugo[2] || honor_umask) && !rwxXstugo[8])
446 1.1 mrg file_mode = (file_mode & ~(S_IROTH | S_IWOTH | S_IXOTH))
447 1.1 mrg | (new_mode & (S_IROTH | S_IWOTH | S_IXOTH));
448 1.1 mrg #ifndef __VXWORKS__
449 1.1 mrg if (is_dir && rwxXstugo[5])
450 1.1 mrg file_mode |= S_ISVTX;
451 1.1 mrg else if (!is_dir)
452 1.1 mrg file_mode &= ~S_ISVTX;
453 1.1 mrg #endif
454 1.1 mrg #endif
455 1.1 mrg }
456 1.1 mrg else if (set_mode == 2)
457 1.1 mrg {
458 1.1 mrg /* Clear '-'. */
459 1.1 mrg file_mode &= ~new_mode;
460 1.1 mrg #if !defined( __MINGW32__) && !defined (__VXWORKS__)
461 1.1 mrg if (rwxXstugo[5] || !is_dir)
462 1.1 mrg file_mode &= ~S_ISVTX;
463 1.1 mrg #endif
464 1.1 mrg }
465 1.1 mrg else if (set_mode == 3)
466 1.1 mrg {
467 1.1 mrg file_mode |= new_mode;
468 1.1 mrg #if !defined (__MINGW32__) && !defined (__VXWORKS__)
469 1.1 mrg if (rwxXstugo[5] && is_dir)
470 1.1 mrg file_mode |= S_ISVTX;
471 1.1 mrg else if (!is_dir)
472 1.1 mrg file_mode &= ~S_ISVTX;
473 1.1 mrg #endif
474 1.1 mrg }
475 1.1 mrg }
476 1.1 mrg
477 1.1 mrg return chmod (file, file_mode);
478 1.1 mrg }
479 1.1 mrg
480 1.1 mrg
481 1.1 mrg extern int chmod_func (char *, char *, gfc_charlen_type, gfc_charlen_type);
482 1.1 mrg export_proto(chmod_func);
483 1.1 mrg
484 1.1 mrg int
485 1.1 mrg chmod_func (char *name, char *mode, gfc_charlen_type name_len,
486 1.1 mrg gfc_charlen_type mode_len)
487 1.1 mrg {
488 1.1 mrg char *cname = fc_strdup (name, name_len);
489 1.1 mrg int ret = chmod_internal (cname, mode, mode_len);
490 1.1 mrg free (cname);
491 1.1 mrg return ret;
492 1.1 mrg }
493 1.1 mrg
494 1.1 mrg
495 1.1 mrg extern void chmod_i4_sub (char *, char *, GFC_INTEGER_4 *,
496 1.1 mrg gfc_charlen_type, gfc_charlen_type);
497 1.1 mrg export_proto(chmod_i4_sub);
498 1.1 mrg
499 1.1 mrg void
500 1.1 mrg chmod_i4_sub (char *name, char *mode, GFC_INTEGER_4 * status,
501 1.1 mrg gfc_charlen_type name_len, gfc_charlen_type mode_len)
502 1.1 mrg {
503 1.1 mrg int val;
504 1.1 mrg
505 1.1 mrg val = chmod_func (name, mode, name_len, mode_len);
506 1.1 mrg if (status)
507 1.1 mrg *status = val;
508 1.1 mrg }
509 1.1 mrg
510 1.1 mrg
511 1.1 mrg extern void chmod_i8_sub (char *, char *, GFC_INTEGER_8 *,
512 1.1 mrg gfc_charlen_type, gfc_charlen_type);
513 1.1 mrg export_proto(chmod_i8_sub);
514 1.1 mrg
515 1.1 mrg void
516 1.1 mrg chmod_i8_sub (char *name, char *mode, GFC_INTEGER_8 * status,
517 1.1 mrg gfc_charlen_type name_len, gfc_charlen_type mode_len)
518 1.1 mrg {
519 1.1 mrg int val;
520 1.1 mrg
521 1.1 mrg val = chmod_func (name, mode, name_len, mode_len);
522 1.1 mrg if (status)
523 1.1 mrg *status = val;
524 1.1 mrg }
525 1.1 mrg
526 1.1 mrg #endif
527