1 /* Implementation of the STAT and FSTAT intrinsics.
2 Copyright (C) 2004 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., 59 Temple Place - Suite 330,
29 Boston, MA 02111-1307, USA. */
32 #include "libgfortran.h"
34 #ifdef HAVE_SYS_TYPES_H
35 #include <sys/types.h>
38 #ifdef HAVE_SYS_STAT_H
54 /* SUBROUTINE STAT(FILE, SARRAY, STATUS)
55 CHARACTER(len=*), INTENT(IN) :: FILE
56 INTEGER, INTENT(OUT), :: SARRAY(13)
57 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
59 FUNCTION STAT(FILE, SARRAY)
61 CHARACTER(len=*), INTENT(IN) :: FILE
62 INTEGER, INTENT(OUT), :: SARRAY(13) */
64 extern void stat_i4_sub (char *, gfc_array_i4
*, GFC_INTEGER_4
*,
66 iexport_proto(stat_i4_sub
);
69 stat_i4_sub (char *name
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
,
70 gfc_charlen_type name_len
)
76 index_type stride
[GFC_MAX_DIMENSIONS
- 1];
78 /* If the rank of the array is not 1, abort. */
79 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
80 runtime_error ("Array rank of SARRAY is not 1.");
82 /* If the array is too small, abort. */
83 if (sarray
->dim
[0].ubound
+ 1 - sarray
->dim
[0].lbound
< 13)
84 runtime_error ("Array size of SARRAY is too small.");
86 if (sarray
->dim
[0].stride
== 0)
87 sarray
->dim
[0].stride
= 1;
89 /* Trim trailing spaces from name. */
90 while (name_len
> 0 && name
[name_len
- 1] == ' ')
93 /* Make a null terminated copy of the string. */
94 str
= gfc_alloca (name_len
+ 1);
95 memcpy (str
, name
, name_len
);
103 sarray
->data
[0 * sarray
->dim
[0].stride
] = sb
.st_dev
;
106 sarray
->data
[1 * sarray
->dim
[0].stride
] = sb
.st_ino
;
109 sarray
->data
[2 * sarray
->dim
[0].stride
] = sb
.st_mode
;
111 /* Number of (hard) links */
112 sarray
->data
[3 * sarray
->dim
[0].stride
] = sb
.st_nlink
;
115 sarray
->data
[4 * sarray
->dim
[0].stride
] = sb
.st_uid
;
118 sarray
->data
[5 * sarray
->dim
[0].stride
] = sb
.st_gid
;
120 /* ID of device containing directory entry for file (0 if not available) */
121 #if HAVE_STRUCT_STAT_ST_RDEV
122 sarray
->data
[6 * sarray
->dim
[0].stride
] = sb
.st_rdev
;
124 sarray
->data
[6 * sarray
->dim
[0].stride
] = 0;
127 /* File size (bytes) */
128 sarray
->data
[7 * sarray
->dim
[0].stride
] = sb
.st_size
;
130 /* Last access time */
131 sarray
->data
[8 * sarray
->dim
[0].stride
] = sb
.st_atime
;
133 /* Last modification time */
134 sarray
->data
[9 * sarray
->dim
[0].stride
] = sb
.st_mtime
;
136 /* Last file status change time */
137 sarray
->data
[10 * sarray
->dim
[0].stride
] = sb
.st_ctime
;
139 /* Preferred I/O block size (-1 if not available) */
140 #if HAVE_STRUCT_STAT_ST_BLKSIZE
141 sarray
->data
[11 * sarray
->dim
[0].stride
] = sb
.st_blksize
;
143 sarray
->data
[11 * sarray
->dim
[0].stride
] = -1;
146 /* Number of blocks allocated (-1 if not available) */
147 #if HAVE_STRUCT_STAT_ST_BLOCKS
148 sarray
->data
[12 * sarray
->dim
[0].stride
] = sb
.st_blocks
;
150 sarray
->data
[12 * sarray
->dim
[0].stride
] = -1;
155 *status
= (val
== 0) ? 0 : errno
;
157 iexport(stat_i4_sub
);
159 extern void stat_i8_sub (char *, gfc_array_i8
*, GFC_INTEGER_8
*,
161 iexport_proto(stat_i8_sub
);
164 stat_i8_sub (char *name
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
,
165 gfc_charlen_type name_len
)
171 index_type stride
[GFC_MAX_DIMENSIONS
- 1];
173 /* If the rank of the array is not 1, abort. */
174 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
175 runtime_error ("Array rank of SARRAY is not 1.");
177 /* If the array is too small, abort. */
178 if (sarray
->dim
[0].ubound
+ 1 - sarray
->dim
[0].lbound
< 13)
179 runtime_error ("Array size of SARRAY is too small.");
181 if (sarray
->dim
[0].stride
== 0)
182 sarray
->dim
[0].stride
= 1;
184 /* Trim trailing spaces from name. */
185 while (name_len
> 0 && name
[name_len
- 1] == ' ')
188 /* Make a null terminated copy of the string. */
189 str
= gfc_alloca (name_len
+ 1);
190 memcpy (str
, name
, name_len
);
191 str
[name_len
] = '\0';
193 val
= stat(str
, &sb
);
198 sarray
->data
[0] = sb
.st_dev
;
201 sarray
->data
[sarray
->dim
[0].stride
] = sb
.st_ino
;
204 sarray
->data
[2 * sarray
->dim
[0].stride
] = sb
.st_mode
;
206 /* Number of (hard) links */
207 sarray
->data
[3 * sarray
->dim
[0].stride
] = sb
.st_nlink
;
210 sarray
->data
[4 * sarray
->dim
[0].stride
] = sb
.st_uid
;
213 sarray
->data
[5 * sarray
->dim
[0].stride
] = sb
.st_gid
;
215 /* ID of device containing directory entry for file (0 if not available) */
216 #if HAVE_STRUCT_STAT_ST_RDEV
217 sarray
->data
[6 * sarray
->dim
[0].stride
] = sb
.st_rdev
;
219 sarray
->data
[6 * sarray
->dim
[0].stride
] = 0;
222 /* File size (bytes) */
223 sarray
->data
[7 * sarray
->dim
[0].stride
] = sb
.st_size
;
225 /* Last access time */
226 sarray
->data
[8 * sarray
->dim
[0].stride
] = sb
.st_atime
;
228 /* Last modification time */
229 sarray
->data
[9 * sarray
->dim
[0].stride
] = sb
.st_mtime
;
231 /* Last file status change time */
232 sarray
->data
[10 * sarray
->dim
[0].stride
] = sb
.st_ctime
;
234 /* Preferred I/O block size (-1 if not available) */
235 #if HAVE_STRUCT_STAT_ST_BLKSIZE
236 sarray
->data
[11 * sarray
->dim
[0].stride
] = sb
.st_blksize
;
238 sarray
->data
[11 * sarray
->dim
[0].stride
] = -1;
241 /* Number of blocks allocated (-1 if not available) */
242 #if HAVE_STRUCT_STAT_ST_BLOCKS
243 sarray
->data
[12 * sarray
->dim
[0].stride
] = sb
.st_blocks
;
245 sarray
->data
[12 * sarray
->dim
[0].stride
] = -1;
250 *status
= (val
== 0) ? 0 : errno
;
252 iexport(stat_i8_sub
);
254 extern GFC_INTEGER_4
stat_i4 (char *, gfc_array_i4
*, gfc_charlen_type
);
255 export_proto(stat_i4
);
258 stat_i4 (char *name
, gfc_array_i4
*sarray
, gfc_charlen_type name_len
)
261 stat_i4_sub (name
, sarray
, &val
, name_len
);
265 extern GFC_INTEGER_8
stat_i8 (char *, gfc_array_i8
*, gfc_charlen_type
);
266 export_proto(stat_i8
);
269 stat_i8 (char *name
, gfc_array_i8
*sarray
, gfc_charlen_type name_len
)
272 stat_i8_sub (name
, sarray
, &val
, name_len
);
277 /* SUBROUTINE FSTAT(UNIT, SARRAY, STATUS)
278 INTEGER, INTENT(IN) :: UNIT
279 INTEGER, INTENT(OUT) :: SARRAY(13)
280 INTEGER, INTENT(OUT), OPTIONAL :: STATUS
282 FUNCTION FSTAT(UNIT, SARRAY)
284 INTEGER, INTENT(IN) :: UNIT
285 INTEGER, INTENT(OUT) :: SARRAY(13) */
287 extern void fstat_i4_sub (GFC_INTEGER_4
*, gfc_array_i4
*, GFC_INTEGER_4
*);
288 iexport_proto(fstat_i4_sub
);
291 fstat_i4_sub (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
, GFC_INTEGER_4
*status
)
296 index_type stride
[GFC_MAX_DIMENSIONS
- 1];
298 /* If the rank of the array is not 1, abort. */
299 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
300 runtime_error ("Array rank of SARRAY is not 1.");
302 /* If the array is too small, abort. */
303 if (sarray
->dim
[0].ubound
+ 1 - sarray
->dim
[0].lbound
< 13)
304 runtime_error ("Array size of SARRAY is too small.");
306 if (sarray
->dim
[0].stride
== 0)
307 sarray
->dim
[0].stride
= 1;
309 /* Convert Fortran unit number to C file descriptor. */
310 val
= unit_to_fd (*unit
);
312 val
= fstat(val
, &sb
);
317 sarray
->data
[0 * sarray
->dim
[0].stride
] = sb
.st_dev
;
320 sarray
->data
[1 * sarray
->dim
[0].stride
] = sb
.st_ino
;
323 sarray
->data
[2 * sarray
->dim
[0].stride
] = sb
.st_mode
;
325 /* Number of (hard) links */
326 sarray
->data
[3 * sarray
->dim
[0].stride
] = sb
.st_nlink
;
329 sarray
->data
[4 * sarray
->dim
[0].stride
] = sb
.st_uid
;
332 sarray
->data
[5 * sarray
->dim
[0].stride
] = sb
.st_gid
;
334 /* ID of device containing directory entry for file (0 if not available) */
335 #if HAVE_STRUCT_STAT_ST_RDEV
336 sarray
->data
[6 * sarray
->dim
[0].stride
] = sb
.st_rdev
;
338 sarray
->data
[6 * sarray
->dim
[0].stride
] = 0;
341 /* File size (bytes) */
342 sarray
->data
[7 * sarray
->dim
[0].stride
] = sb
.st_size
;
344 /* Last access time */
345 sarray
->data
[8 * sarray
->dim
[0].stride
] = sb
.st_atime
;
347 /* Last modification time */
348 sarray
->data
[9 * sarray
->dim
[0].stride
] = sb
.st_mtime
;
350 /* Last file status change time */
351 sarray
->data
[10 * sarray
->dim
[0].stride
] = sb
.st_ctime
;
353 /* Preferred I/O block size (-1 if not available) */
354 #if HAVE_STRUCT_STAT_ST_BLKSIZE
355 sarray
->data
[11 * sarray
->dim
[0].stride
] = sb
.st_blksize
;
357 sarray
->data
[11 * sarray
->dim
[0].stride
] = -1;
360 /* Number of blocks allocated (-1 if not available) */
361 #if HAVE_STRUCT_STAT_ST_BLOCKS
362 sarray
->data
[12 * sarray
->dim
[0].stride
] = sb
.st_blocks
;
364 sarray
->data
[12 * sarray
->dim
[0].stride
] = -1;
369 *status
= (val
== 0) ? 0 : errno
;
371 iexport(fstat_i4_sub
);
373 extern void fstat_i8_sub (GFC_INTEGER_8
*, gfc_array_i8
*, GFC_INTEGER_8
*);
374 iexport_proto(fstat_i8_sub
);
377 fstat_i8_sub (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
, GFC_INTEGER_8
*status
)
382 index_type stride
[GFC_MAX_DIMENSIONS
- 1];
384 /* If the rank of the array is not 1, abort. */
385 if (GFC_DESCRIPTOR_RANK (sarray
) != 1)
386 runtime_error ("Array rank of SARRAY is not 1.");
388 /* If the array is too small, abort. */
389 if (sarray
->dim
[0].ubound
+ 1 - sarray
->dim
[0].lbound
< 13)
390 runtime_error ("Array size of SARRAY is too small.");
392 if (sarray
->dim
[0].stride
== 0)
393 sarray
->dim
[0].stride
= 1;
395 /* Convert Fortran unit number to C file descriptor. */
396 val
= unit_to_fd ((int) *unit
);
398 val
= fstat(val
, &sb
);
403 sarray
->data
[0] = sb
.st_dev
;
406 sarray
->data
[sarray
->dim
[0].stride
] = sb
.st_ino
;
409 sarray
->data
[2 * sarray
->dim
[0].stride
] = sb
.st_mode
;
411 /* Number of (hard) links */
412 sarray
->data
[3 * sarray
->dim
[0].stride
] = sb
.st_nlink
;
415 sarray
->data
[4 * sarray
->dim
[0].stride
] = sb
.st_uid
;
418 sarray
->data
[5 * sarray
->dim
[0].stride
] = sb
.st_gid
;
420 /* ID of device containing directory entry for file (0 if not available) */
421 #if HAVE_STRUCT_STAT_ST_RDEV
422 sarray
->data
[6 * sarray
->dim
[0].stride
] = sb
.st_rdev
;
424 sarray
->data
[6 * sarray
->dim
[0].stride
] = 0;
427 /* File size (bytes) */
428 sarray
->data
[7 * sarray
->dim
[0].stride
] = sb
.st_size
;
430 /* Last access time */
431 sarray
->data
[8 * sarray
->dim
[0].stride
] = sb
.st_atime
;
433 /* Last modification time */
434 sarray
->data
[9 * sarray
->dim
[0].stride
] = sb
.st_mtime
;
436 /* Last file status change time */
437 sarray
->data
[10 * sarray
->dim
[0].stride
] = sb
.st_ctime
;
439 /* Preferred I/O block size (-1 if not available) */
440 #if HAVE_STRUCT_STAT_ST_BLKSIZE
441 sarray
->data
[11 * sarray
->dim
[0].stride
] = sb
.st_blksize
;
443 sarray
->data
[11 * sarray
->dim
[0].stride
] = -1;
446 /* Number of blocks allocated (-1 if not available) */
447 #if HAVE_STRUCT_STAT_ST_BLOCKS
448 sarray
->data
[12 * sarray
->dim
[0].stride
] = sb
.st_blocks
;
450 sarray
->data
[12 * sarray
->dim
[0].stride
] = -1;
455 *status
= (val
== 0) ? 0 : errno
;
457 iexport(fstat_i8_sub
);
459 extern GFC_INTEGER_4
fstat_i4 (GFC_INTEGER_4
*, gfc_array_i4
*);
460 export_proto(fstat_i4
);
463 fstat_i4 (GFC_INTEGER_4
*unit
, gfc_array_i4
*sarray
)
466 fstat_i4_sub (unit
, sarray
, &val
);
470 extern GFC_INTEGER_8
fstat_i8 (GFC_INTEGER_8
*, gfc_array_i8
*);
471 export_proto(fstat_i8
);
474 fstat_i8 (GFC_INTEGER_8
*unit
, gfc_array_i8
*sarray
)
477 fstat_i8_sub (unit
, sarray
, &val
);