1 /* Implementation of the STAT and FSTAT intrinsics.
2 Copyright (C) 2004, 2005, 2006, 2007, 2009, 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Steven G. Kargl <kargls@comcast.net>.
6 This file is part of the GNU Fortran runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 3 of the License, or (at your option) any later version.
13 Libgfortran 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.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 #include "libgfortran.h"
32 #ifdef HAVE_SYS_STAT_H
41 /* SUBROUTINE STAT(FILE, SARRAY, STATUS)
42 CHARACTER(len=*), INTENT(IN) :: FILE
43 INTEGER, INTENT(OUT), :: SARRAY(13)
44 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
46 FUNCTION STAT(FILE, SARRAY)
48 CHARACTER(len=*), INTENT(IN) :: FILE
49 INTEGER, INTENT(OUT), :: SARRAY(13) */
51 /*extern void stat_i4_sub_0 (char *, gfc_array_i4 *, GFC_INTEGER_4 *,
52 gfc_charlen_type, int);
53 internal_proto(stat_i4_sub_0);*/
56 stat_i4_sub_0 (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
57 gfc_charlen_type name_len
, int is_lstat
__attribute__ ((unused
)))
63 /* If the rank of the array is not 1, abort. */
64 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
65 runtime_error ("Array rank of SARRAY is not 1.");
67 /* If the array is too small, abort. */
68 if (GFC_DESCRIPTOR_EXTENT(sarray
,0) < 13)
69 runtime_error ("Array size of SARRAY is too small.");
71 /* Trim trailing spaces from name. */
72 while (name_len
> 0 && name
[name_len
- 1] == ' ')
75 /* Make a null terminated copy of the string. */
76 str
= gfc_alloca (name_len
+ 1);
77 memcpy (str
, name
, name_len
);
80 /* On platforms that don't provide lstat(), we use stat() instead. */
83 val
= lstat(str
, &sb
);
90 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
93 sarray
->base_addr
[0 * stride
] = sb
.st_dev
;
96 sarray
->base_addr
[1 * stride
] = sb
.st_ino
;
99 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
101 /* Number of (hard) links */
102 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
105 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
108 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
110 /* ID of device containing directory entry for file (0 if not available) */
111 #if HAVE_STRUCT_STAT_ST_RDEV
112 sarray
->base_addr
[6 * stride
] = sb
.st_rdev
;
114 sarray
->base_addr
[6 * stride
] = 0;
117 /* File size (bytes) */
118 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
120 /* Last access time */
121 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
123 /* Last modification time */
124 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
126 /* Last file status change time */
127 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
129 /* Preferred I/O block size (-1 if not available) */
130 #if HAVE_STRUCT_STAT_ST_BLKSIZE
131 sarray
->base_addr
[11 * stride
] = sb
.st_blksize
;
133 sarray
->base_addr
[11 * stride
] = -1;
136 /* Number of blocks allocated (-1 if not available) */
137 #if HAVE_STRUCT_STAT_ST_BLOCKS
138 sarray
->base_addr
[12 * stride
] = sb
.st_blocks
;
140 sarray
->base_addr
[12 * stride
] = -1;
145 *status
= (val
== 0) ? 0 : errno
;
149 extern void stat_i4_sub (char *, gfc_array_i4
*, GFC_INTEGER_4
*,
151 iexport_proto(stat_i4_sub
);
154 stat_i4_sub (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
155 gfc_charlen_type name_len
)
157 stat_i4_sub_0 (name
, sarray
, status
, name_len
, 0);
159 iexport(stat_i4_sub
);
162 extern void lstat_i4_sub (char *, gfc_array_i4
*, GFC_INTEGER_4
*,
164 iexport_proto(lstat_i4_sub
);
167 lstat_i4_sub (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
168 gfc_charlen_type name_len
)
170 stat_i4_sub_0 (name
, sarray
, status
, name_len
, 1);
172 iexport(lstat_i4_sub
);
177 stat_i8_sub_0 (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
178 gfc_charlen_type name_len
, int is_lstat
__attribute__ ((unused
)))
184 /* If the rank of the array is not 1, abort. */
185 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
186 runtime_error ("Array rank of SARRAY is not 1.");
188 /* If the array is too small, abort. */
189 if (GFC_DESCRIPTOR_EXTENT(sarray
,0) < 13)
190 runtime_error ("Array size of SARRAY is too small.");
192 /* Trim trailing spaces from name. */
193 while (name_len
> 0 && name
[name_len
- 1] == ' ')
196 /* Make a null terminated copy of the string. */
197 str
= gfc_alloca (name_len
+ 1);
198 memcpy (str
, name
, name_len
);
199 str
[name_len
] = '\0';
201 /* On platforms that don't provide lstat(), we use stat() instead. */
204 val
= lstat(str
, &sb
);
207 val
= stat(str
, &sb
);
211 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
214 sarray
->base_addr
[0] = sb
.st_dev
;
217 sarray
->base_addr
[stride
] = sb
.st_ino
;
220 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
222 /* Number of (hard) links */
223 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
226 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
229 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
231 /* ID of device containing directory entry for file (0 if not available) */
232 #if HAVE_STRUCT_STAT_ST_RDEV
233 sarray
->base_addr
[6 * stride
] = sb
.st_rdev
;
235 sarray
->base_addr
[6 * stride
] = 0;
238 /* File size (bytes) */
239 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
241 /* Last access time */
242 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
244 /* Last modification time */
245 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
247 /* Last file status change time */
248 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
250 /* Preferred I/O block size (-1 if not available) */
251 #if HAVE_STRUCT_STAT_ST_BLKSIZE
252 sarray
->base_addr
[11 * stride
] = sb
.st_blksize
;
254 sarray
->base_addr
[11 * stride
] = -1;
257 /* Number of blocks allocated (-1 if not available) */
258 #if HAVE_STRUCT_STAT_ST_BLOCKS
259 sarray
->base_addr
[12 * stride
] = sb
.st_blocks
;
261 sarray
->base_addr
[12 * stride
] = -1;
266 *status
= (val
== 0) ? 0 : errno
;
270 extern void stat_i8_sub (char *, gfc_array_i8
*, GFC_INTEGER_8
*,
272 iexport_proto(stat_i8_sub
);
275 stat_i8_sub (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
276 gfc_charlen_type name_len
)
278 stat_i8_sub_0 (name
, sarray
, status
, name_len
, 0);
281 iexport(stat_i8_sub
);
284 extern void lstat_i8_sub (char *, gfc_array_i8
*, GFC_INTEGER_8
*,
286 iexport_proto(lstat_i8_sub
);
289 lstat_i8_sub (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
290 gfc_charlen_type name_len
)
292 stat_i8_sub_0 (name
, sarray
, status
, name_len
, 1);
295 iexport(lstat_i8_sub
);
298 extern GFC_INTEGER_4
stat_i4 (char *, gfc_array_i4
*, gfc_charlen_type
);
299 export_proto(stat_i4
);
302 stat_i4 (char *name
, gfc_array_i4
*sarray
, gfc_charlen_type name_len
)
305 stat_i4_sub (name
, sarray
, &val
, name_len
);
309 extern GFC_INTEGER_8
stat_i8 (char *, gfc_array_i8
*, gfc_charlen_type
);
310 export_proto(stat_i8
);
313 stat_i8 (char *name
, gfc_array_i8
*sarray
, gfc_charlen_type name_len
)
316 stat_i8_sub (name
, sarray
, &val
, name_len
);
321 /* SUBROUTINE LSTAT(FILE, SARRAY, STATUS)
322 CHARACTER(len=*), INTENT(IN) :: FILE
323 INTEGER, INTENT(OUT), :: SARRAY(13)
324 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
326 FUNCTION LSTAT(FILE, SARRAY)
328 CHARACTER(len=*), INTENT(IN) :: FILE
329 INTEGER, INTENT(OUT), :: SARRAY(13) */
331 extern GFC_INTEGER_4
lstat_i4 (char *, gfc_array_i4
*, gfc_charlen_type
);
332 export_proto(lstat_i4
);
335 lstat_i4 (char *name
, gfc_array_i4
*sarray
, gfc_charlen_type name_len
)
338 lstat_i4_sub (name
, sarray
, &val
, name_len
);
342 extern GFC_INTEGER_8
lstat_i8 (char *, gfc_array_i8
*, gfc_charlen_type
);
343 export_proto(lstat_i8
);
346 lstat_i8 (char *name
, gfc_array_i8
*sarray
, gfc_charlen_type name_len
)
349 lstat_i8_sub (name
, sarray
, &val
, name_len
);
358 /* SUBROUTINE FSTAT(UNIT, SARRAY, STATUS)
359 INTEGER, INTENT(IN) :: UNIT
360 INTEGER, INTENT(OUT) :: SARRAY(13)
361 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
363 FUNCTION FSTAT(UNIT, SARRAY)
365 INTEGER, INTENT(IN) :: UNIT
366 INTEGER, INTENT(OUT) :: SARRAY(13) */
368 extern void fstat_i4_sub (GFC_INTEGER_4
*, gfc_array_i4
*, GFC_INTEGER_4
*);
369 iexport_proto(fstat_i4_sub
);
372 fstat_i4_sub (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
)
377 /* If the rank of the array is not 1, abort. */
378 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
379 runtime_error ("Array rank of SARRAY is not 1.");
381 /* If the array is too small, abort. */
382 if (GFC_DESCRIPTOR_EXTENT(sarray
,0) < 13)
383 runtime_error ("Array size of SARRAY is too small.");
385 /* Convert Fortran unit number to C file descriptor. */
386 val
= unit_to_fd (*unit
);
388 val
= fstat(val
, &sb
);
392 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
395 sarray
->base_addr
[0 * stride
] = sb
.st_dev
;
398 sarray
->base_addr
[1 * stride
] = sb
.st_ino
;
401 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
403 /* Number of (hard) links */
404 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
407 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
410 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
412 /* ID of device containing directory entry for file (0 if not available) */
413 #if HAVE_STRUCT_STAT_ST_RDEV
414 sarray
->base_addr
[6 * stride
] = sb
.st_rdev
;
416 sarray
->base_addr
[6 * stride
] = 0;
419 /* File size (bytes) */
420 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
422 /* Last access time */
423 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
425 /* Last modification time */
426 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
428 /* Last file status change time */
429 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
431 /* Preferred I/O block size (-1 if not available) */
432 #if HAVE_STRUCT_STAT_ST_BLKSIZE
433 sarray
->base_addr
[11 * stride
] = sb
.st_blksize
;
435 sarray
->base_addr
[11 * stride
] = -1;
438 /* Number of blocks allocated (-1 if not available) */
439 #if HAVE_STRUCT_STAT_ST_BLOCKS
440 sarray
->base_addr
[12 * stride
] = sb
.st_blocks
;
442 sarray
->base_addr
[12 * stride
] = -1;
447 *status
= (val
== 0) ? 0 : errno
;
449 iexport(fstat_i4_sub
);
451 extern void fstat_i8_sub (GFC_INTEGER_8
*, gfc_array_i8
*, GFC_INTEGER_8
*);
452 iexport_proto(fstat_i8_sub
);
455 fstat_i8_sub (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
)
460 /* If the rank of the array is not 1, abort. */
461 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
462 runtime_error ("Array rank of SARRAY is not 1.");
464 /* If the array is too small, abort. */
465 if (GFC_DESCRIPTOR_EXTENT(sarray
,0) < 13)
466 runtime_error ("Array size of SARRAY is too small.");
468 /* Convert Fortran unit number to C file descriptor. */
469 val
= unit_to_fd ((int) *unit
);
471 val
= fstat(val
, &sb
);
475 index_type stride
= GFC_DESCRIPTOR_STRIDE(sarray
,0);
478 sarray
->base_addr
[0] = sb
.st_dev
;
481 sarray
->base_addr
[stride
] = sb
.st_ino
;
484 sarray
->base_addr
[2 * stride
] = sb
.st_mode
;
486 /* Number of (hard) links */
487 sarray
->base_addr
[3 * stride
] = sb
.st_nlink
;
490 sarray
->base_addr
[4 * stride
] = sb
.st_uid
;
493 sarray
->base_addr
[5 * stride
] = sb
.st_gid
;
495 /* ID of device containing directory entry for file (0 if not available) */
496 #if HAVE_STRUCT_STAT_ST_RDEV
497 sarray
->base_addr
[6 * stride
] = sb
.st_rdev
;
499 sarray
->base_addr
[6 * stride
] = 0;
502 /* File size (bytes) */
503 sarray
->base_addr
[7 * stride
] = sb
.st_size
;
505 /* Last access time */
506 sarray
->base_addr
[8 * stride
] = sb
.st_atime
;
508 /* Last modification time */
509 sarray
->base_addr
[9 * stride
] = sb
.st_mtime
;
511 /* Last file status change time */
512 sarray
->base_addr
[10 * stride
] = sb
.st_ctime
;
514 /* Preferred I/O block size (-1 if not available) */
515 #if HAVE_STRUCT_STAT_ST_BLKSIZE
516 sarray
->base_addr
[11 * stride
] = sb
.st_blksize
;
518 sarray
->base_addr
[11 * stride
] = -1;
521 /* Number of blocks allocated (-1 if not available) */
522 #if HAVE_STRUCT_STAT_ST_BLOCKS
523 sarray
->base_addr
[12 * stride
] = sb
.st_blocks
;
525 sarray
->base_addr
[12 * stride
] = -1;
530 *status
= (val
== 0) ? 0 : errno
;
532 iexport(fstat_i8_sub
);
534 extern GFC_INTEGER_4
fstat_i4 (GFC_INTEGER_4
*, gfc_array_i4
*);
535 export_proto(fstat_i4
);
538 fstat_i4 (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
)
541 fstat_i4_sub (unit
, sarray
, &val
);
545 extern GFC_INTEGER_8
fstat_i8 (GFC_INTEGER_8
*, gfc_array_i8
*);
546 export_proto(fstat_i8
);
549 fstat_i8 (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
)
552 fstat_i8_sub (unit
, sarray
, &val
);