1 /* Implementation of the STAT and FSTAT intrinsics.
2 Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
3 Contributed by Steven G. Kargl <kargls@comcast.net>.
5 This file is part of the GNU Fortran 95 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 2 of the License, or (at your option) any later version.
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
21 Libgfortran is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public
27 License along with libgfortran; see the file COPYING. If not,
28 write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA. */
32 #include "libgfortran.h"
34 #ifdef HAVE_SYS_TYPES_H
35 #include <sys/types.h>
38 #ifdef HAVE_SYS_STAT_H
52 /* SUBROUTINE STAT(FILE, SARRAY, STATUS)
53 CHARACTER(len=*), INTENT(IN) :: FILE
54 INTEGER, INTENT(OUT), :: SARRAY(13)
55 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
57 FUNCTION STAT(FILE, SARRAY)
59 CHARACTER(len=*), INTENT(IN) :: FILE
60 INTEGER, INTENT(OUT), :: SARRAY(13) */
62 /*extern void stat_i4_sub_0 (char *, gfc_array_i4 *, GFC_INTEGER_4 *,
63 gfc_charlen_type, int);
64 internal_proto(stat_i4_sub_0);*/
67 stat_i4_sub_0 (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
68 gfc_charlen_type name_len
, int is_lstat
)
74 /* If the rank of the array is not 1, abort. */
75 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
76 runtime_error ("Array rank of SARRAY is not 1.");
78 /* If the array is too small, abort. */
79 if (sarray
->dim
[0].ubound
+ 1 - sarray
->dim
[0].lbound
< 13)
80 runtime_error ("Array size of SARRAY is too small.");
82 /* Trim trailing spaces from name. */
83 while (name_len
> 0 && name
[name_len
- 1] == ' ')
86 /* Make a null terminated copy of the string. */
87 str
= gfc_alloca (name_len
+ 1);
88 memcpy (str
, name
, name_len
);
92 val
= lstat(str
, &sb
);
99 sarray
->data
[0 * sarray
->dim
[0].stride
] = sb
.st_dev
;
102 sarray
->data
[1 * sarray
->dim
[0].stride
] = sb
.st_ino
;
105 sarray
->data
[2 * sarray
->dim
[0].stride
] = sb
.st_mode
;
107 /* Number of (hard) links */
108 sarray
->data
[3 * sarray
->dim
[0].stride
] = sb
.st_nlink
;
111 sarray
->data
[4 * sarray
->dim
[0].stride
] = sb
.st_uid
;
114 sarray
->data
[5 * sarray
->dim
[0].stride
] = sb
.st_gid
;
116 /* ID of device containing directory entry for file (0 if not available) */
117 #if HAVE_STRUCT_STAT_ST_RDEV
118 sarray
->data
[6 * sarray
->dim
[0].stride
] = sb
.st_rdev
;
120 sarray
->data
[6 * sarray
->dim
[0].stride
] = 0;
123 /* File size (bytes) */
124 sarray
->data
[7 * sarray
->dim
[0].stride
] = sb
.st_size
;
126 /* Last access time */
127 sarray
->data
[8 * sarray
->dim
[0].stride
] = sb
.st_atime
;
129 /* Last modification time */
130 sarray
->data
[9 * sarray
->dim
[0].stride
] = sb
.st_mtime
;
132 /* Last file status change time */
133 sarray
->data
[10 * sarray
->dim
[0].stride
] = sb
.st_ctime
;
135 /* Preferred I/O block size (-1 if not available) */
136 #if HAVE_STRUCT_STAT_ST_BLKSIZE
137 sarray
->data
[11 * sarray
->dim
[0].stride
] = sb
.st_blksize
;
139 sarray
->data
[11 * sarray
->dim
[0].stride
] = -1;
142 /* Number of blocks allocated (-1 if not available) */
143 #if HAVE_STRUCT_STAT_ST_BLOCKS
144 sarray
->data
[12 * sarray
->dim
[0].stride
] = sb
.st_blocks
;
146 sarray
->data
[12 * sarray
->dim
[0].stride
] = -1;
151 *status
= (val
== 0) ? 0 : errno
;
155 extern void stat_i4_sub (char *, gfc_array_i4
*, GFC_INTEGER_4
*,
157 iexport_proto(stat_i4_sub
);
160 stat_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
, 0);
165 iexport(stat_i4_sub
);
168 extern void lstat_i4_sub (char *, gfc_array_i4
*, GFC_INTEGER_4
*,
170 iexport_proto(lstat_i4_sub
);
173 lstat_i4_sub (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
174 gfc_charlen_type name_len
)
176 stat_i4_sub_0 (name
, sarray
, status
, name_len
, 1);
178 iexport(lstat_i4_sub
);
183 stat_i8_sub_0 (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
184 gfc_charlen_type name_len
, int is_lstat
)
190 /* If the rank of the array is not 1, abort. */
191 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
192 runtime_error ("Array rank of SARRAY is not 1.");
194 /* If the array is too small, abort. */
195 if (sarray
->dim
[0].ubound
+ 1 - sarray
->dim
[0].lbound
< 13)
196 runtime_error ("Array size of SARRAY is too small.");
198 /* Trim trailing spaces from name. */
199 while (name_len
> 0 && name
[name_len
- 1] == ' ')
202 /* Make a null terminated copy of the string. */
203 str
= gfc_alloca (name_len
+ 1);
204 memcpy (str
, name
, name_len
);
205 str
[name_len
] = '\0';
208 val
= lstat(str
, &sb
);
210 val
= stat(str
, &sb
);
215 sarray
->data
[0] = sb
.st_dev
;
218 sarray
->data
[sarray
->dim
[0].stride
] = sb
.st_ino
;
221 sarray
->data
[2 * sarray
->dim
[0].stride
] = sb
.st_mode
;
223 /* Number of (hard) links */
224 sarray
->data
[3 * sarray
->dim
[0].stride
] = sb
.st_nlink
;
227 sarray
->data
[4 * sarray
->dim
[0].stride
] = sb
.st_uid
;
230 sarray
->data
[5 * sarray
->dim
[0].stride
] = sb
.st_gid
;
232 /* ID of device containing directory entry for file (0 if not available) */
233 #if HAVE_STRUCT_STAT_ST_RDEV
234 sarray
->data
[6 * sarray
->dim
[0].stride
] = sb
.st_rdev
;
236 sarray
->data
[6 * sarray
->dim
[0].stride
] = 0;
239 /* File size (bytes) */
240 sarray
->data
[7 * sarray
->dim
[0].stride
] = sb
.st_size
;
242 /* Last access time */
243 sarray
->data
[8 * sarray
->dim
[0].stride
] = sb
.st_atime
;
245 /* Last modification time */
246 sarray
->data
[9 * sarray
->dim
[0].stride
] = sb
.st_mtime
;
248 /* Last file status change time */
249 sarray
->data
[10 * sarray
->dim
[0].stride
] = sb
.st_ctime
;
251 /* Preferred I/O block size (-1 if not available) */
252 #if HAVE_STRUCT_STAT_ST_BLKSIZE
253 sarray
->data
[11 * sarray
->dim
[0].stride
] = sb
.st_blksize
;
255 sarray
->data
[11 * sarray
->dim
[0].stride
] = -1;
258 /* Number of blocks allocated (-1 if not available) */
259 #if HAVE_STRUCT_STAT_ST_BLOCKS
260 sarray
->data
[12 * sarray
->dim
[0].stride
] = sb
.st_blocks
;
262 sarray
->data
[12 * sarray
->dim
[0].stride
] = -1;
267 *status
= (val
== 0) ? 0 : errno
;
271 extern void stat_i8_sub (char *, gfc_array_i8
*, GFC_INTEGER_8
*,
273 iexport_proto(stat_i8_sub
);
276 stat_i8_sub (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
277 gfc_charlen_type name_len
)
279 stat_i8_sub_0 (name
, sarray
, status
, name_len
, 0);
282 iexport(stat_i8_sub
);
285 extern void lstat_i8_sub (char *, gfc_array_i8
*, GFC_INTEGER_8
*,
287 iexport_proto(lstat_i8_sub
);
290 lstat_i8_sub (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
291 gfc_charlen_type name_len
)
293 stat_i8_sub_0 (name
, sarray
, status
, name_len
, 1);
296 iexport(lstat_i8_sub
);
299 extern GFC_INTEGER_4
stat_i4 (char *, gfc_array_i4
*, gfc_charlen_type
);
300 export_proto(stat_i4
);
303 stat_i4 (char *name
, gfc_array_i4
*sarray
, gfc_charlen_type name_len
)
306 stat_i4_sub (name
, sarray
, &val
, name_len
);
310 extern GFC_INTEGER_8
stat_i8 (char *, gfc_array_i8
*, gfc_charlen_type
);
311 export_proto(stat_i8
);
314 stat_i8 (char *name
, gfc_array_i8
*sarray
, gfc_charlen_type name_len
)
317 stat_i8_sub (name
, sarray
, &val
, name_len
);
322 /* SUBROUTINE STAT(FILE, SARRAY, STATUS)
323 CHARACTER(len=*), INTENT(IN) :: FILE
324 INTEGER, INTENT(OUT), :: SARRAY(13)
325 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
327 FUNCTION STAT(FILE, SARRAY)
329 CHARACTER(len=*), INTENT(IN) :: FILE
330 INTEGER, INTENT(OUT), :: SARRAY(13) */
332 extern GFC_INTEGER_4
lstat_i4 (char *, gfc_array_i4
*, gfc_charlen_type
);
333 export_proto(lstat_i4
);
336 lstat_i4 (char *name
, gfc_array_i4
*sarray
, gfc_charlen_type name_len
)
339 lstat_i4_sub (name
, sarray
, &val
, name_len
);
343 extern GFC_INTEGER_8
lstat_i8 (char *, gfc_array_i8
*, gfc_charlen_type
);
344 export_proto(lstat_i8
);
347 lstat_i8 (char *name
, gfc_array_i8
*sarray
, gfc_charlen_type name_len
)
350 lstat_i8_sub (name
, sarray
, &val
, name_len
);
356 /* SUBROUTINE FSTAT(UNIT, SARRAY, STATUS)
357 INTEGER, INTENT(IN) :: UNIT
358 INTEGER, INTENT(OUT) :: SARRAY(13)
359 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
361 FUNCTION FSTAT(UNIT, SARRAY)
363 INTEGER, INTENT(IN) :: UNIT
364 INTEGER, INTENT(OUT) :: SARRAY(13) */
366 extern void fstat_i4_sub (GFC_INTEGER_4
*, gfc_array_i4
*, GFC_INTEGER_4
*);
367 iexport_proto(fstat_i4_sub
);
370 fstat_i4_sub (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
)
375 /* If the rank of the array is not 1, abort. */
376 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
377 runtime_error ("Array rank of SARRAY is not 1.");
379 /* If the array is too small, abort. */
380 if (sarray
->dim
[0].ubound
+ 1 - sarray
->dim
[0].lbound
< 13)
381 runtime_error ("Array size of SARRAY is too small.");
383 /* Convert Fortran unit number to C file descriptor. */
384 val
= unit_to_fd (*unit
);
386 val
= fstat(val
, &sb
);
391 sarray
->data
[0 * sarray
->dim
[0].stride
] = sb
.st_dev
;
394 sarray
->data
[1 * sarray
->dim
[0].stride
] = sb
.st_ino
;
397 sarray
->data
[2 * sarray
->dim
[0].stride
] = sb
.st_mode
;
399 /* Number of (hard) links */
400 sarray
->data
[3 * sarray
->dim
[0].stride
] = sb
.st_nlink
;
403 sarray
->data
[4 * sarray
->dim
[0].stride
] = sb
.st_uid
;
406 sarray
->data
[5 * sarray
->dim
[0].stride
] = sb
.st_gid
;
408 /* ID of device containing directory entry for file (0 if not available) */
409 #if HAVE_STRUCT_STAT_ST_RDEV
410 sarray
->data
[6 * sarray
->dim
[0].stride
] = sb
.st_rdev
;
412 sarray
->data
[6 * sarray
->dim
[0].stride
] = 0;
415 /* File size (bytes) */
416 sarray
->data
[7 * sarray
->dim
[0].stride
] = sb
.st_size
;
418 /* Last access time */
419 sarray
->data
[8 * sarray
->dim
[0].stride
] = sb
.st_atime
;
421 /* Last modification time */
422 sarray
->data
[9 * sarray
->dim
[0].stride
] = sb
.st_mtime
;
424 /* Last file status change time */
425 sarray
->data
[10 * sarray
->dim
[0].stride
] = sb
.st_ctime
;
427 /* Preferred I/O block size (-1 if not available) */
428 #if HAVE_STRUCT_STAT_ST_BLKSIZE
429 sarray
->data
[11 * sarray
->dim
[0].stride
] = sb
.st_blksize
;
431 sarray
->data
[11 * sarray
->dim
[0].stride
] = -1;
434 /* Number of blocks allocated (-1 if not available) */
435 #if HAVE_STRUCT_STAT_ST_BLOCKS
436 sarray
->data
[12 * sarray
->dim
[0].stride
] = sb
.st_blocks
;
438 sarray
->data
[12 * sarray
->dim
[0].stride
] = -1;
443 *status
= (val
== 0) ? 0 : errno
;
445 iexport(fstat_i4_sub
);
447 extern void fstat_i8_sub (GFC_INTEGER_8
*, gfc_array_i8
*, GFC_INTEGER_8
*);
448 iexport_proto(fstat_i8_sub
);
451 fstat_i8_sub (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
)
456 /* If the rank of the array is not 1, abort. */
457 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
458 runtime_error ("Array rank of SARRAY is not 1.");
460 /* If the array is too small, abort. */
461 if (sarray
->dim
[0].ubound
+ 1 - sarray
->dim
[0].lbound
< 13)
462 runtime_error ("Array size of SARRAY is too small.");
464 /* Convert Fortran unit number to C file descriptor. */
465 val
= unit_to_fd ((int) *unit
);
467 val
= fstat(val
, &sb
);
472 sarray
->data
[0] = sb
.st_dev
;
475 sarray
->data
[sarray
->dim
[0].stride
] = sb
.st_ino
;
478 sarray
->data
[2 * sarray
->dim
[0].stride
] = sb
.st_mode
;
480 /* Number of (hard) links */
481 sarray
->data
[3 * sarray
->dim
[0].stride
] = sb
.st_nlink
;
484 sarray
->data
[4 * sarray
->dim
[0].stride
] = sb
.st_uid
;
487 sarray
->data
[5 * sarray
->dim
[0].stride
] = sb
.st_gid
;
489 /* ID of device containing directory entry for file (0 if not available) */
490 #if HAVE_STRUCT_STAT_ST_RDEV
491 sarray
->data
[6 * sarray
->dim
[0].stride
] = sb
.st_rdev
;
493 sarray
->data
[6 * sarray
->dim
[0].stride
] = 0;
496 /* File size (bytes) */
497 sarray
->data
[7 * sarray
->dim
[0].stride
] = sb
.st_size
;
499 /* Last access time */
500 sarray
->data
[8 * sarray
->dim
[0].stride
] = sb
.st_atime
;
502 /* Last modification time */
503 sarray
->data
[9 * sarray
->dim
[0].stride
] = sb
.st_mtime
;
505 /* Last file status change time */
506 sarray
->data
[10 * sarray
->dim
[0].stride
] = sb
.st_ctime
;
508 /* Preferred I/O block size (-1 if not available) */
509 #if HAVE_STRUCT_STAT_ST_BLKSIZE
510 sarray
->data
[11 * sarray
->dim
[0].stride
] = sb
.st_blksize
;
512 sarray
->data
[11 * sarray
->dim
[0].stride
] = -1;
515 /* Number of blocks allocated (-1 if not available) */
516 #if HAVE_STRUCT_STAT_ST_BLOCKS
517 sarray
->data
[12 * sarray
->dim
[0].stride
] = sb
.st_blocks
;
519 sarray
->data
[12 * sarray
->dim
[0].stride
] = -1;
524 *status
= (val
== 0) ? 0 : errno
;
526 iexport(fstat_i8_sub
);
528 extern GFC_INTEGER_4
fstat_i4 (GFC_INTEGER_4
*, gfc_array_i4
*);
529 export_proto(fstat_i4
);
532 fstat_i4 (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
)
535 fstat_i4_sub (unit
, sarray
, &val
);
539 extern GFC_INTEGER_8
fstat_i8 (GFC_INTEGER_8
*, gfc_array_i8
*);
540 export_proto(fstat_i8
);
543 fstat_i8 (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
)
546 fstat_i8_sub (unit
, sarray
, &val
);