1 /* Implementation of the STAT and FSTAT intrinsics.
2 Copyright (C) 2004-2015 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"
31 #ifdef HAVE_SYS_STAT_H
40 /* SUBROUTINE STAT(FILE, SARRAY, STATUS)
41 CHARACTER(len=*), INTENT(IN) :: FILE
42 INTEGER, INTENT(OUT), :: SARRAY(13)
43 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
45 FUNCTION STAT(FILE, SARRAY)
47 CHARACTER(len=*), INTENT(IN) :: FILE
48 INTEGER, INTENT(OUT), :: SARRAY(13) */
50 /*extern void stat_i4_sub_0 (char *, gfc_array_i4 *, GFC_INTEGER_4 *,
51 gfc_charlen_type, int);
52 internal_proto(stat_i4_sub_0);*/
55 stat_i4_sub_0 (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
56 gfc_charlen_type name_len
, int is_lstat
__attribute__ ((unused
)))
62 /* If the rank of the array is not 1, abort. */
63 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
64 runtime_error ("Array rank of SARRAY is not 1.");
66 /* If the array is too small, abort. */
67 if (GFC_DESCRIPTOR_EXTENT(sarray
,0) < 13)
68 runtime_error ("Array size of SARRAY is too small.");
70 /* Make a null terminated copy of the string. */
71 str
= fc_strdup (name
, name_len
);
73 /* On platforms that don't provide lstat(), we use stat() instead. */
76 val
= lstat(str
, &sb
);
85 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
88 sarray
->base_addr
[0 * stride
] = sb
.st_dev
;
91 sarray
->base_addr
[1 * stride
] = sb
.st_ino
;
94 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
96 /* Number of (hard) links */
97 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
100 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
103 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
105 /* ID of device containing directory entry for file (0 if not available) */
106 #if HAVE_STRUCT_STAT_ST_RDEV
107 sarray
->base_addr
[6 * stride
] = sb
.st_rdev
;
109 sarray
->base_addr
[6 * stride
] = 0;
112 /* File size (bytes) */
113 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
115 /* Last access time */
116 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
118 /* Last modification time */
119 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
121 /* Last file status change time */
122 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
124 /* Preferred I/O block size (-1 if not available) */
125 #if HAVE_STRUCT_STAT_ST_BLKSIZE
126 sarray
->base_addr
[11 * stride
] = sb
.st_blksize
;
128 sarray
->base_addr
[11 * stride
] = -1;
131 /* Number of blocks allocated (-1 if not available) */
132 #if HAVE_STRUCT_STAT_ST_BLOCKS
133 sarray
->base_addr
[12 * stride
] = sb
.st_blocks
;
135 sarray
->base_addr
[12 * stride
] = -1;
140 *status
= (val
== 0) ? 0 : errno
;
144 extern void stat_i4_sub (char *, gfc_array_i4
*, GFC_INTEGER_4
*,
146 iexport_proto(stat_i4_sub
);
149 stat_i4_sub (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
150 gfc_charlen_type name_len
)
152 stat_i4_sub_0 (name
, sarray
, status
, name_len
, 0);
154 iexport(stat_i4_sub
);
157 extern void lstat_i4_sub (char *, gfc_array_i4
*, GFC_INTEGER_4
*,
159 iexport_proto(lstat_i4_sub
);
162 lstat_i4_sub (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
163 gfc_charlen_type name_len
)
165 stat_i4_sub_0 (name
, sarray
, status
, name_len
, 1);
167 iexport(lstat_i4_sub
);
172 stat_i8_sub_0 (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
173 gfc_charlen_type name_len
, int is_lstat
__attribute__ ((unused
)))
179 /* If the rank of the array is not 1, abort. */
180 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
181 runtime_error ("Array rank of SARRAY is not 1.");
183 /* If the array is too small, abort. */
184 if (GFC_DESCRIPTOR_EXTENT(sarray
,0) < 13)
185 runtime_error ("Array size of SARRAY is too small.");
187 /* Make a null terminated copy of the string. */
188 str
= fc_strdup (name
, name_len
);
190 /* On platforms that don't provide lstat(), we use stat() instead. */
193 val
= lstat(str
, &sb
);
196 val
= stat(str
, &sb
);
202 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
205 sarray
->base_addr
[0] = sb
.st_dev
;
208 sarray
->base_addr
[stride
] = sb
.st_ino
;
211 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
213 /* Number of (hard) links */
214 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
217 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
220 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
222 /* ID of device containing directory entry for file (0 if not available) */
223 #if HAVE_STRUCT_STAT_ST_RDEV
224 sarray
->base_addr
[6 * stride
] = sb
.st_rdev
;
226 sarray
->base_addr
[6 * stride
] = 0;
229 /* File size (bytes) */
230 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
232 /* Last access time */
233 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
235 /* Last modification time */
236 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
238 /* Last file status change time */
239 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
241 /* Preferred I/O block size (-1 if not available) */
242 #if HAVE_STRUCT_STAT_ST_BLKSIZE
243 sarray
->base_addr
[11 * stride
] = sb
.st_blksize
;
245 sarray
->base_addr
[11 * stride
] = -1;
248 /* Number of blocks allocated (-1 if not available) */
249 #if HAVE_STRUCT_STAT_ST_BLOCKS
250 sarray
->base_addr
[12 * stride
] = sb
.st_blocks
;
252 sarray
->base_addr
[12 * stride
] = -1;
257 *status
= (val
== 0) ? 0 : errno
;
261 extern void stat_i8_sub (char *, gfc_array_i8
*, GFC_INTEGER_8
*,
263 iexport_proto(stat_i8_sub
);
266 stat_i8_sub (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
267 gfc_charlen_type name_len
)
269 stat_i8_sub_0 (name
, sarray
, status
, name_len
, 0);
272 iexport(stat_i8_sub
);
275 extern void lstat_i8_sub (char *, gfc_array_i8
*, GFC_INTEGER_8
*,
277 iexport_proto(lstat_i8_sub
);
280 lstat_i8_sub (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
281 gfc_charlen_type name_len
)
283 stat_i8_sub_0 (name
, sarray
, status
, name_len
, 1);
286 iexport(lstat_i8_sub
);
289 extern GFC_INTEGER_4
stat_i4 (char *, gfc_array_i4
*, gfc_charlen_type
);
290 export_proto(stat_i4
);
293 stat_i4 (char *name
, gfc_array_i4
*sarray
, gfc_charlen_type name_len
)
296 stat_i4_sub (name
, sarray
, &val
, name_len
);
300 extern GFC_INTEGER_8
stat_i8 (char *, gfc_array_i8
*, gfc_charlen_type
);
301 export_proto(stat_i8
);
304 stat_i8 (char *name
, gfc_array_i8
*sarray
, gfc_charlen_type name_len
)
307 stat_i8_sub (name
, sarray
, &val
, name_len
);
312 /* SUBROUTINE LSTAT(FILE, SARRAY, STATUS)
313 CHARACTER(len=*), INTENT(IN) :: FILE
314 INTEGER, INTENT(OUT), :: SARRAY(13)
315 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
317 FUNCTION LSTAT(FILE, SARRAY)
319 CHARACTER(len=*), INTENT(IN) :: FILE
320 INTEGER, INTENT(OUT), :: SARRAY(13) */
322 extern GFC_INTEGER_4
lstat_i4 (char *, gfc_array_i4
*, gfc_charlen_type
);
323 export_proto(lstat_i4
);
326 lstat_i4 (char *name
, gfc_array_i4
*sarray
, gfc_charlen_type name_len
)
329 lstat_i4_sub (name
, sarray
, &val
, name_len
);
333 extern GFC_INTEGER_8
lstat_i8 (char *, gfc_array_i8
*, gfc_charlen_type
);
334 export_proto(lstat_i8
);
337 lstat_i8 (char *name
, gfc_array_i8
*sarray
, gfc_charlen_type name_len
)
340 lstat_i8_sub (name
, sarray
, &val
, name_len
);
349 /* SUBROUTINE FSTAT(UNIT, SARRAY, STATUS)
350 INTEGER, INTENT(IN) :: UNIT
351 INTEGER, INTENT(OUT) :: SARRAY(13)
352 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
354 FUNCTION FSTAT(UNIT, SARRAY)
356 INTEGER, INTENT(IN) :: UNIT
357 INTEGER, INTENT(OUT) :: SARRAY(13) */
359 extern void fstat_i4_sub (GFC_INTEGER_4
*, gfc_array_i4
*, GFC_INTEGER_4
*);
360 iexport_proto(fstat_i4_sub
);
363 fstat_i4_sub (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
)
368 /* If the rank of the array is not 1, abort. */
369 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
370 runtime_error ("Array rank of SARRAY is not 1.");
372 /* If the array is too small, abort. */
373 if (GFC_DESCRIPTOR_EXTENT(sarray
,0) < 13)
374 runtime_error ("Array size of SARRAY is too small.");
376 /* Convert Fortran unit number to C file descriptor. */
377 val
= unit_to_fd (*unit
);
379 val
= fstat(val
, &sb
);
383 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
386 sarray
->base_addr
[0 * stride
] = sb
.st_dev
;
389 sarray
->base_addr
[1 * stride
] = sb
.st_ino
;
392 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
394 /* Number of (hard) links */
395 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
398 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
401 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
403 /* ID of device containing directory entry for file (0 if not available) */
404 #if HAVE_STRUCT_STAT_ST_RDEV
405 sarray
->base_addr
[6 * stride
] = sb
.st_rdev
;
407 sarray
->base_addr
[6 * stride
] = 0;
410 /* File size (bytes) */
411 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
413 /* Last access time */
414 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
416 /* Last modification time */
417 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
419 /* Last file status change time */
420 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
422 /* Preferred I/O block size (-1 if not available) */
423 #if HAVE_STRUCT_STAT_ST_BLKSIZE
424 sarray
->base_addr
[11 * stride
] = sb
.st_blksize
;
426 sarray
->base_addr
[11 * stride
] = -1;
429 /* Number of blocks allocated (-1 if not available) */
430 #if HAVE_STRUCT_STAT_ST_BLOCKS
431 sarray
->base_addr
[12 * stride
] = sb
.st_blocks
;
433 sarray
->base_addr
[12 * stride
] = -1;
438 *status
= (val
== 0) ? 0 : errno
;
440 iexport(fstat_i4_sub
);
442 extern void fstat_i8_sub (GFC_INTEGER_8
*, gfc_array_i8
*, GFC_INTEGER_8
*);
443 iexport_proto(fstat_i8_sub
);
446 fstat_i8_sub (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
)
451 /* If the rank of the array is not 1, abort. */
452 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
453 runtime_error ("Array rank of SARRAY is not 1.");
455 /* If the array is too small, abort. */
456 if (GFC_DESCRIPTOR_EXTENT(sarray
,0) < 13)
457 runtime_error ("Array size of SARRAY is too small.");
459 /* Convert Fortran unit number to C file descriptor. */
460 val
= unit_to_fd ((int) *unit
);
462 val
= fstat(val
, &sb
);
466 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
469 sarray
->base_addr
[0] = sb
.st_dev
;
472 sarray
->base_addr
[stride
] = sb
.st_ino
;
475 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
477 /* Number of (hard) links */
478 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
481 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
484 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
486 /* ID of device containing directory entry for file (0 if not available) */
487 #if HAVE_STRUCT_STAT_ST_RDEV
488 sarray
->base_addr
[6 * stride
] = sb
.st_rdev
;
490 sarray
->base_addr
[6 * stride
] = 0;
493 /* File size (bytes) */
494 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
496 /* Last access time */
497 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
499 /* Last modification time */
500 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
502 /* Last file status change time */
503 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
505 /* Preferred I/O block size (-1 if not available) */
506 #if HAVE_STRUCT_STAT_ST_BLKSIZE
507 sarray
->base_addr
[11 * stride
] = sb
.st_blksize
;
509 sarray
->base_addr
[11 * stride
] = -1;
512 /* Number of blocks allocated (-1 if not available) */
513 #if HAVE_STRUCT_STAT_ST_BLOCKS
514 sarray
->base_addr
[12 * stride
] = sb
.st_blocks
;
516 sarray
->base_addr
[12 * stride
] = -1;
521 *status
= (val
== 0) ? 0 : errno
;
523 iexport(fstat_i8_sub
);
525 extern GFC_INTEGER_4
fstat_i4 (GFC_INTEGER_4
*, gfc_array_i4
*);
526 export_proto(fstat_i4
);
529 fstat_i4 (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
)
532 fstat_i4_sub (unit
, sarray
, &val
);
536 extern GFC_INTEGER_8
fstat_i8 (GFC_INTEGER_8
*, gfc_array_i8
*);
537 export_proto(fstat_i8
);
540 fstat_i8 (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
)
543 fstat_i8_sub (unit
, sarray
, &val
);