1 /* Implementation of the STAT and FSTAT intrinsics.
2 Copyright (C) 2004-2024 Free Software Foundation, Inc.
3 Contributed by Steven G. Kargl <kargls@comcast.net>.
5 This file is part of the GNU Fortran runtime library (libgfortran).
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.
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.
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.
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/>. */
26 #include "libgfortran.h"
30 #ifdef HAVE_SYS_STAT_H
38 /* SUBROUTINE STAT(FILE, SARRAY, STATUS)
39 CHARACTER(len=*), INTENT(IN) :: FILE
40 INTEGER, INTENT(OUT), :: SARRAY(13)
41 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
43 FUNCTION STAT(FILE, SARRAY)
45 CHARACTER(len=*), INTENT(IN) :: FILE
46 INTEGER, INTENT(OUT), :: SARRAY(13) */
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);*/
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
)))
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.");
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.");
68 /* Make a null terminated copy of the string. */
69 str
= fc_strdup (name
, name_len
);
71 /* On platforms that don't provide lstat(), we use stat() instead. */
74 val
= lstat(str
, &sb
);
83 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
86 sarray
->base_addr
[0 * stride
] = sb
.st_dev
;
89 sarray
->base_addr
[1 * stride
] = sb
.st_ino
;
92 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
94 /* Number of (hard) links */
95 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
98 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
101 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
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
;
107 sarray
->base_addr
[6 * stride
] = 0;
110 /* File size (bytes) */
111 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
113 /* Last access time */
114 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
116 /* Last modification time */
117 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
119 /* Last file status change time */
120 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
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
;
126 sarray
->base_addr
[11 * stride
] = -1;
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
;
133 sarray
->base_addr
[12 * stride
] = -1;
138 *status
= (val
== 0) ? 0 : errno
;
142 extern void stat_i4_sub (char *, gfc_array_i4
*, GFC_INTEGER_4
*,
144 iexport_proto(stat_i4_sub
);
147 stat_i4_sub (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
148 gfc_charlen_type name_len
)
150 stat_i4_sub_0 (name
, sarray
, status
, name_len
, 0);
152 iexport(stat_i4_sub
);
155 extern void lstat_i4_sub (char *, gfc_array_i4
*, GFC_INTEGER_4
*,
157 iexport_proto(lstat_i4_sub
);
160 lstat_i4_sub (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
161 gfc_charlen_type name_len
)
163 stat_i4_sub_0 (name
, sarray
, status
, name_len
, 1);
165 iexport(lstat_i4_sub
);
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
)))
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.");
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.");
185 /* Make a null terminated copy of the string. */
186 str
= fc_strdup (name
, name_len
);
188 /* On platforms that don't provide lstat(), we use stat() instead. */
191 val
= lstat(str
, &sb
);
194 val
= stat(str
, &sb
);
200 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
203 sarray
->base_addr
[0] = sb
.st_dev
;
206 sarray
->base_addr
[stride
] = sb
.st_ino
;
209 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
211 /* Number of (hard) links */
212 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
215 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
218 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
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
;
224 sarray
->base_addr
[6 * stride
] = 0;
227 /* File size (bytes) */
228 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
230 /* Last access time */
231 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
233 /* Last modification time */
234 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
236 /* Last file status change time */
237 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
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
;
243 sarray
->base_addr
[11 * stride
] = -1;
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
;
250 sarray
->base_addr
[12 * stride
] = -1;
255 *status
= (val
== 0) ? 0 : errno
;
259 extern void stat_i8_sub (char *, gfc_array_i8
*, GFC_INTEGER_8
*,
261 iexport_proto(stat_i8_sub
);
264 stat_i8_sub (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
265 gfc_charlen_type name_len
)
267 stat_i8_sub_0 (name
, sarray
, status
, name_len
, 0);
270 iexport(stat_i8_sub
);
273 extern void lstat_i8_sub (char *, gfc_array_i8
*, GFC_INTEGER_8
*,
275 iexport_proto(lstat_i8_sub
);
278 lstat_i8_sub (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
279 gfc_charlen_type name_len
)
281 stat_i8_sub_0 (name
, sarray
, status
, name_len
, 1);
284 iexport(lstat_i8_sub
);
287 extern GFC_INTEGER_4
stat_i4 (char *, gfc_array_i4
*, gfc_charlen_type
);
288 export_proto(stat_i4
);
291 stat_i4 (char *name
, gfc_array_i4
*sarray
, gfc_charlen_type name_len
)
294 stat_i4_sub (name
, sarray
, &val
, name_len
);
298 extern GFC_INTEGER_8
stat_i8 (char *, gfc_array_i8
*, gfc_charlen_type
);
299 export_proto(stat_i8
);
302 stat_i8 (char *name
, gfc_array_i8
*sarray
, gfc_charlen_type name_len
)
305 stat_i8_sub (name
, sarray
, &val
, name_len
);
310 /* SUBROUTINE LSTAT(FILE, SARRAY, STATUS)
311 CHARACTER(len=*), INTENT(IN) :: FILE
312 INTEGER, INTENT(OUT), :: SARRAY(13)
313 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
315 FUNCTION LSTAT(FILE, SARRAY)
317 CHARACTER(len=*), INTENT(IN) :: FILE
318 INTEGER, INTENT(OUT), :: SARRAY(13) */
320 extern GFC_INTEGER_4
lstat_i4 (char *, gfc_array_i4
*, gfc_charlen_type
);
321 export_proto(lstat_i4
);
324 lstat_i4 (char *name
, gfc_array_i4
*sarray
, gfc_charlen_type name_len
)
327 lstat_i4_sub (name
, sarray
, &val
, name_len
);
331 extern GFC_INTEGER_8
lstat_i8 (char *, gfc_array_i8
*, gfc_charlen_type
);
332 export_proto(lstat_i8
);
335 lstat_i8 (char *name
, gfc_array_i8
*sarray
, gfc_charlen_type name_len
)
338 lstat_i8_sub (name
, sarray
, &val
, name_len
);
347 /* SUBROUTINE FSTAT(UNIT, SARRAY, STATUS)
348 INTEGER, INTENT(IN) :: UNIT
349 INTEGER, INTENT(OUT) :: SARRAY(13)
350 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
352 FUNCTION FSTAT(UNIT, SARRAY)
354 INTEGER, INTENT(IN) :: UNIT
355 INTEGER, INTENT(OUT) :: SARRAY(13) */
357 extern void fstat_i4_sub (GFC_INTEGER_4
*, gfc_array_i4
*, GFC_INTEGER_4
*);
358 iexport_proto(fstat_i4_sub
);
361 fstat_i4_sub (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
)
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.");
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.");
374 /* Convert Fortran unit number to C file descriptor. */
375 val
= unit_to_fd (*unit
);
377 val
= fstat(val
, &sb
);
381 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
384 sarray
->base_addr
[0 * stride
] = sb
.st_dev
;
387 sarray
->base_addr
[1 * stride
] = sb
.st_ino
;
390 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
392 /* Number of (hard) links */
393 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
396 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
399 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
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
;
405 sarray
->base_addr
[6 * stride
] = 0;
408 /* File size (bytes) */
409 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
411 /* Last access time */
412 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
414 /* Last modification time */
415 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
417 /* Last file status change time */
418 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
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
;
424 sarray
->base_addr
[11 * stride
] = -1;
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
;
431 sarray
->base_addr
[12 * stride
] = -1;
436 *status
= (val
== 0) ? 0 : errno
;
438 iexport(fstat_i4_sub
);
440 extern void fstat_i8_sub (GFC_INTEGER_8
*, gfc_array_i8
*, GFC_INTEGER_8
*);
441 iexport_proto(fstat_i8_sub
);
444 fstat_i8_sub (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
)
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.");
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.");
457 /* Convert Fortran unit number to C file descriptor. */
458 val
= unit_to_fd ((int) *unit
);
460 val
= fstat(val
, &sb
);
464 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
467 sarray
->base_addr
[0] = sb
.st_dev
;
470 sarray
->base_addr
[stride
] = sb
.st_ino
;
473 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
475 /* Number of (hard) links */
476 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
479 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
482 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
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
;
488 sarray
->base_addr
[6 * stride
] = 0;
491 /* File size (bytes) */
492 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
494 /* Last access time */
495 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
497 /* Last modification time */
498 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
500 /* Last file status change time */
501 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
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
;
507 sarray
->base_addr
[11 * stride
] = -1;
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
;
514 sarray
->base_addr
[12 * stride
] = -1;
519 *status
= (val
== 0) ? 0 : errno
;
521 iexport(fstat_i8_sub
);
523 extern GFC_INTEGER_4
fstat_i4 (GFC_INTEGER_4
*, gfc_array_i4
*);
524 export_proto(fstat_i4
);
527 fstat_i4 (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
)
530 fstat_i4_sub (unit
, sarray
, &val
);
534 extern GFC_INTEGER_8
fstat_i8 (GFC_INTEGER_8
*, gfc_array_i8
*);
535 export_proto(fstat_i8
);
538 fstat_i8 (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
)
541 fstat_i8_sub (unit
, sarray
, &val
);