]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/intrinsics/stat.c
Update copyright years.
[thirdparty/gcc.git] / libgfortran / intrinsics / stat.c
1 /* Implementation of the STAT and FSTAT intrinsics.
2 Copyright (C) 2004-2020 Free Software Foundation, Inc.
3 Contributed by Steven G. Kargl <kargls@comcast.net>.
4
5 This file is part of the GNU Fortran runtime library (libgfortran).
6
7 Libgfortran is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
11
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
25
26 #include "libgfortran.h"
27
28 #include <errno.h>
29
30 #ifdef HAVE_SYS_STAT_H
31 #include <sys/stat.h>
32 #endif
33
34
35
36 #ifdef HAVE_STAT
37
38 /* SUBROUTINE STAT(FILE, SARRAY, STATUS)
39 CHARACTER(len=*), INTENT(IN) :: FILE
40 INTEGER, INTENT(OUT), :: SARRAY(13)
41 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
42
43 FUNCTION STAT(FILE, SARRAY)
44 INTEGER STAT
45 CHARACTER(len=*), INTENT(IN) :: FILE
46 INTEGER, INTENT(OUT), :: SARRAY(13) */
47
48 /*extern void stat_i4_sub_0 (char *, gfc_array_i4 *, GFC_INTEGER_4 *,
49 gfc_charlen_type, int);
50 internal_proto(stat_i4_sub_0);*/
51
52 static void
53 stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
54 gfc_charlen_type name_len, int is_lstat __attribute__ ((unused)))
55 {
56 int val;
57 char *str;
58 struct stat sb;
59
60 /* If the rank of the array is not 1, abort. */
61 if (GFC_DESCRIPTOR_RANK (sarray) != 1)
62 runtime_error ("Array rank of SARRAY is not 1.");
63
64 /* If the array is too small, abort. */
65 if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
66 runtime_error ("Array size of SARRAY is too small.");
67
68 /* Make a null terminated copy of the string. */
69 str = fc_strdup (name, name_len);
70
71 /* On platforms that don't provide lstat(), we use stat() instead. */
72 #ifdef HAVE_LSTAT
73 if (is_lstat)
74 val = lstat(str, &sb);
75 else
76 #endif
77 val = stat(str, &sb);
78
79 free (str);
80
81 if (val == 0)
82 {
83 index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
84
85 /* Device ID */
86 sarray->base_addr[0 * stride] = sb.st_dev;
87
88 /* Inode number */
89 sarray->base_addr[1 * stride] = sb.st_ino;
90
91 /* File mode */
92 sarray->base_addr[2 * stride] = sb.st_mode;
93
94 /* Number of (hard) links */
95 sarray->base_addr[3 * stride] = sb.st_nlink;
96
97 /* Owner's uid */
98 sarray->base_addr[4 * stride] = sb.st_uid;
99
100 /* Owner's gid */
101 sarray->base_addr[5 * stride] = sb.st_gid;
102
103 /* ID of device containing directory entry for file (0 if not available) */
104 #if HAVE_STRUCT_STAT_ST_RDEV
105 sarray->base_addr[6 * stride] = sb.st_rdev;
106 #else
107 sarray->base_addr[6 * stride] = 0;
108 #endif
109
110 /* File size (bytes) */
111 sarray->base_addr[7 * stride] = sb.st_size;
112
113 /* Last access time */
114 sarray->base_addr[8 * stride] = sb.st_atime;
115
116 /* Last modification time */
117 sarray->base_addr[9 * stride] = sb.st_mtime;
118
119 /* Last file status change time */
120 sarray->base_addr[10 * stride] = sb.st_ctime;
121
122 /* Preferred I/O block size (-1 if not available) */
123 #if HAVE_STRUCT_STAT_ST_BLKSIZE
124 sarray->base_addr[11 * stride] = sb.st_blksize;
125 #else
126 sarray->base_addr[11 * stride] = -1;
127 #endif
128
129 /* Number of blocks allocated (-1 if not available) */
130 #if HAVE_STRUCT_STAT_ST_BLOCKS
131 sarray->base_addr[12 * stride] = sb.st_blocks;
132 #else
133 sarray->base_addr[12 * stride] = -1;
134 #endif
135 }
136
137 if (status != NULL)
138 *status = (val == 0) ? 0 : errno;
139 }
140
141
142 extern void stat_i4_sub (char *, gfc_array_i4 *, GFC_INTEGER_4 *,
143 gfc_charlen_type);
144 iexport_proto(stat_i4_sub);
145
146 void
147 stat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
148 gfc_charlen_type name_len)
149 {
150 stat_i4_sub_0 (name, sarray, status, name_len, 0);
151 }
152 iexport(stat_i4_sub);
153
154
155 extern void lstat_i4_sub (char *, gfc_array_i4 *, GFC_INTEGER_4 *,
156 gfc_charlen_type);
157 iexport_proto(lstat_i4_sub);
158
159 void
160 lstat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
161 gfc_charlen_type name_len)
162 {
163 stat_i4_sub_0 (name, sarray, status, name_len, 1);
164 }
165 iexport(lstat_i4_sub);
166
167
168
169 static void
170 stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
171 gfc_charlen_type name_len, int is_lstat __attribute__ ((unused)))
172 {
173 int val;
174 char *str;
175 struct stat sb;
176
177 /* If the rank of the array is not 1, abort. */
178 if (GFC_DESCRIPTOR_RANK (sarray) != 1)
179 runtime_error ("Array rank of SARRAY is not 1.");
180
181 /* If the array is too small, abort. */
182 if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
183 runtime_error ("Array size of SARRAY is too small.");
184
185 /* Make a null terminated copy of the string. */
186 str = fc_strdup (name, name_len);
187
188 /* On platforms that don't provide lstat(), we use stat() instead. */
189 #ifdef HAVE_LSTAT
190 if (is_lstat)
191 val = lstat(str, &sb);
192 else
193 #endif
194 val = stat(str, &sb);
195
196 free (str);
197
198 if (val == 0)
199 {
200 index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
201
202 /* Device ID */
203 sarray->base_addr[0] = sb.st_dev;
204
205 /* Inode number */
206 sarray->base_addr[stride] = sb.st_ino;
207
208 /* File mode */
209 sarray->base_addr[2 * stride] = sb.st_mode;
210
211 /* Number of (hard) links */
212 sarray->base_addr[3 * stride] = sb.st_nlink;
213
214 /* Owner's uid */
215 sarray->base_addr[4 * stride] = sb.st_uid;
216
217 /* Owner's gid */
218 sarray->base_addr[5 * stride] = sb.st_gid;
219
220 /* ID of device containing directory entry for file (0 if not available) */
221 #if HAVE_STRUCT_STAT_ST_RDEV
222 sarray->base_addr[6 * stride] = sb.st_rdev;
223 #else
224 sarray->base_addr[6 * stride] = 0;
225 #endif
226
227 /* File size (bytes) */
228 sarray->base_addr[7 * stride] = sb.st_size;
229
230 /* Last access time */
231 sarray->base_addr[8 * stride] = sb.st_atime;
232
233 /* Last modification time */
234 sarray->base_addr[9 * stride] = sb.st_mtime;
235
236 /* Last file status change time */
237 sarray->base_addr[10 * stride] = sb.st_ctime;
238
239 /* Preferred I/O block size (-1 if not available) */
240 #if HAVE_STRUCT_STAT_ST_BLKSIZE
241 sarray->base_addr[11 * stride] = sb.st_blksize;
242 #else
243 sarray->base_addr[11 * stride] = -1;
244 #endif
245
246 /* Number of blocks allocated (-1 if not available) */
247 #if HAVE_STRUCT_STAT_ST_BLOCKS
248 sarray->base_addr[12 * stride] = sb.st_blocks;
249 #else
250 sarray->base_addr[12 * stride] = -1;
251 #endif
252 }
253
254 if (status != NULL)
255 *status = (val == 0) ? 0 : errno;
256 }
257
258
259 extern void stat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *,
260 gfc_charlen_type);
261 iexport_proto(stat_i8_sub);
262
263 void
264 stat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
265 gfc_charlen_type name_len)
266 {
267 stat_i8_sub_0 (name, sarray, status, name_len, 0);
268 }
269
270 iexport(stat_i8_sub);
271
272
273 extern void lstat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *,
274 gfc_charlen_type);
275 iexport_proto(lstat_i8_sub);
276
277 void
278 lstat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
279 gfc_charlen_type name_len)
280 {
281 stat_i8_sub_0 (name, sarray, status, name_len, 1);
282 }
283
284 iexport(lstat_i8_sub);
285
286
287 extern GFC_INTEGER_4 stat_i4 (char *, gfc_array_i4 *, gfc_charlen_type);
288 export_proto(stat_i4);
289
290 GFC_INTEGER_4
291 stat_i4 (char *name, gfc_array_i4 *sarray, gfc_charlen_type name_len)
292 {
293 GFC_INTEGER_4 val;
294 stat_i4_sub (name, sarray, &val, name_len);
295 return val;
296 }
297
298 extern GFC_INTEGER_8 stat_i8 (char *, gfc_array_i8 *, gfc_charlen_type);
299 export_proto(stat_i8);
300
301 GFC_INTEGER_8
302 stat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len)
303 {
304 GFC_INTEGER_8 val;
305 stat_i8_sub (name, sarray, &val, name_len);
306 return val;
307 }
308
309
310 /* SUBROUTINE LSTAT(FILE, SARRAY, STATUS)
311 CHARACTER(len=*), INTENT(IN) :: FILE
312 INTEGER, INTENT(OUT), :: SARRAY(13)
313 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
314
315 FUNCTION LSTAT(FILE, SARRAY)
316 INTEGER LSTAT
317 CHARACTER(len=*), INTENT(IN) :: FILE
318 INTEGER, INTENT(OUT), :: SARRAY(13) */
319
320 extern GFC_INTEGER_4 lstat_i4 (char *, gfc_array_i4 *, gfc_charlen_type);
321 export_proto(lstat_i4);
322
323 GFC_INTEGER_4
324 lstat_i4 (char *name, gfc_array_i4 *sarray, gfc_charlen_type name_len)
325 {
326 GFC_INTEGER_4 val;
327 lstat_i4_sub (name, sarray, &val, name_len);
328 return val;
329 }
330
331 extern GFC_INTEGER_8 lstat_i8 (char *, gfc_array_i8 *, gfc_charlen_type);
332 export_proto(lstat_i8);
333
334 GFC_INTEGER_8
335 lstat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len)
336 {
337 GFC_INTEGER_8 val;
338 lstat_i8_sub (name, sarray, &val, name_len);
339 return val;
340 }
341
342 #endif
343
344
345 #ifdef HAVE_FSTAT
346
347 /* SUBROUTINE FSTAT(UNIT, SARRAY, STATUS)
348 INTEGER, INTENT(IN) :: UNIT
349 INTEGER, INTENT(OUT) :: SARRAY(13)
350 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
351
352 FUNCTION FSTAT(UNIT, SARRAY)
353 INTEGER FSTAT
354 INTEGER, INTENT(IN) :: UNIT
355 INTEGER, INTENT(OUT) :: SARRAY(13) */
356
357 extern void fstat_i4_sub (GFC_INTEGER_4 *, gfc_array_i4 *, GFC_INTEGER_4 *);
358 iexport_proto(fstat_i4_sub);
359
360 void
361 fstat_i4_sub (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray, GFC_INTEGER_4 *status)
362 {
363 int val;
364 struct stat sb;
365
366 /* If the rank of the array is not 1, abort. */
367 if (GFC_DESCRIPTOR_RANK (sarray) != 1)
368 runtime_error ("Array rank of SARRAY is not 1.");
369
370 /* If the array is too small, abort. */
371 if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
372 runtime_error ("Array size of SARRAY is too small.");
373
374 /* Convert Fortran unit number to C file descriptor. */
375 val = unit_to_fd (*unit);
376 if (val >= 0)
377 val = fstat(val, &sb);
378
379 if (val == 0)
380 {
381 index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
382
383 /* Device ID */
384 sarray->base_addr[0 * stride] = sb.st_dev;
385
386 /* Inode number */
387 sarray->base_addr[1 * stride] = sb.st_ino;
388
389 /* File mode */
390 sarray->base_addr[2 * stride] = sb.st_mode;
391
392 /* Number of (hard) links */
393 sarray->base_addr[3 * stride] = sb.st_nlink;
394
395 /* Owner's uid */
396 sarray->base_addr[4 * stride] = sb.st_uid;
397
398 /* Owner's gid */
399 sarray->base_addr[5 * stride] = sb.st_gid;
400
401 /* ID of device containing directory entry for file (0 if not available) */
402 #if HAVE_STRUCT_STAT_ST_RDEV
403 sarray->base_addr[6 * stride] = sb.st_rdev;
404 #else
405 sarray->base_addr[6 * stride] = 0;
406 #endif
407
408 /* File size (bytes) */
409 sarray->base_addr[7 * stride] = sb.st_size;
410
411 /* Last access time */
412 sarray->base_addr[8 * stride] = sb.st_atime;
413
414 /* Last modification time */
415 sarray->base_addr[9 * stride] = sb.st_mtime;
416
417 /* Last file status change time */
418 sarray->base_addr[10 * stride] = sb.st_ctime;
419
420 /* Preferred I/O block size (-1 if not available) */
421 #if HAVE_STRUCT_STAT_ST_BLKSIZE
422 sarray->base_addr[11 * stride] = sb.st_blksize;
423 #else
424 sarray->base_addr[11 * stride] = -1;
425 #endif
426
427 /* Number of blocks allocated (-1 if not available) */
428 #if HAVE_STRUCT_STAT_ST_BLOCKS
429 sarray->base_addr[12 * stride] = sb.st_blocks;
430 #else
431 sarray->base_addr[12 * stride] = -1;
432 #endif
433 }
434
435 if (status != NULL)
436 *status = (val == 0) ? 0 : errno;
437 }
438 iexport(fstat_i4_sub);
439
440 extern void fstat_i8_sub (GFC_INTEGER_8 *, gfc_array_i8 *, GFC_INTEGER_8 *);
441 iexport_proto(fstat_i8_sub);
442
443 void
444 fstat_i8_sub (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray, GFC_INTEGER_8 *status)
445 {
446 int val;
447 struct stat sb;
448
449 /* If the rank of the array is not 1, abort. */
450 if (GFC_DESCRIPTOR_RANK (sarray) != 1)
451 runtime_error ("Array rank of SARRAY is not 1.");
452
453 /* If the array is too small, abort. */
454 if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13)
455 runtime_error ("Array size of SARRAY is too small.");
456
457 /* Convert Fortran unit number to C file descriptor. */
458 val = unit_to_fd ((int) *unit);
459 if (val >= 0)
460 val = fstat(val, &sb);
461
462 if (val == 0)
463 {
464 index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0);
465
466 /* Device ID */
467 sarray->base_addr[0] = sb.st_dev;
468
469 /* Inode number */
470 sarray->base_addr[stride] = sb.st_ino;
471
472 /* File mode */
473 sarray->base_addr[2 * stride] = sb.st_mode;
474
475 /* Number of (hard) links */
476 sarray->base_addr[3 * stride] = sb.st_nlink;
477
478 /* Owner's uid */
479 sarray->base_addr[4 * stride] = sb.st_uid;
480
481 /* Owner's gid */
482 sarray->base_addr[5 * stride] = sb.st_gid;
483
484 /* ID of device containing directory entry for file (0 if not available) */
485 #if HAVE_STRUCT_STAT_ST_RDEV
486 sarray->base_addr[6 * stride] = sb.st_rdev;
487 #else
488 sarray->base_addr[6 * stride] = 0;
489 #endif
490
491 /* File size (bytes) */
492 sarray->base_addr[7 * stride] = sb.st_size;
493
494 /* Last access time */
495 sarray->base_addr[8 * stride] = sb.st_atime;
496
497 /* Last modification time */
498 sarray->base_addr[9 * stride] = sb.st_mtime;
499
500 /* Last file status change time */
501 sarray->base_addr[10 * stride] = sb.st_ctime;
502
503 /* Preferred I/O block size (-1 if not available) */
504 #if HAVE_STRUCT_STAT_ST_BLKSIZE
505 sarray->base_addr[11 * stride] = sb.st_blksize;
506 #else
507 sarray->base_addr[11 * stride] = -1;
508 #endif
509
510 /* Number of blocks allocated (-1 if not available) */
511 #if HAVE_STRUCT_STAT_ST_BLOCKS
512 sarray->base_addr[12 * stride] = sb.st_blocks;
513 #else
514 sarray->base_addr[12 * stride] = -1;
515 #endif
516 }
517
518 if (status != NULL)
519 *status = (val == 0) ? 0 : errno;
520 }
521 iexport(fstat_i8_sub);
522
523 extern GFC_INTEGER_4 fstat_i4 (GFC_INTEGER_4 *, gfc_array_i4 *);
524 export_proto(fstat_i4);
525
526 GFC_INTEGER_4
527 fstat_i4 (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray)
528 {
529 GFC_INTEGER_4 val;
530 fstat_i4_sub (unit, sarray, &val);
531 return val;
532 }
533
534 extern GFC_INTEGER_8 fstat_i8 (GFC_INTEGER_8 *, gfc_array_i8 *);
535 export_proto(fstat_i8);
536
537 GFC_INTEGER_8
538 fstat_i8 (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray)
539 {
540 GFC_INTEGER_8 val;
541 fstat_i8_sub (unit, sarray, &val);
542 return val;
543 }
544
545 #endif