2005-04-06 Kelley Cook <kcook@gcc.gnu.org>
[official-gcc.git] / libgfortran / intrinsics / stat.c
blobd7ed7610bb086d82cf6469f8b397d9688bd13566
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
19 executable.)
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. */
31 #include "config.h"
32 #include "libgfortran.h"
34 #ifdef HAVE_SYS_TYPES_H
35 #include <sys/types.h>
36 #endif
38 #ifdef HAVE_SYS_STAT_H
39 #include <sys/stat.h>
40 #endif
42 #ifdef HAVE_STDLIB_H
43 #include <stdlib.h>
44 #endif
46 #ifdef HAVE_STRING_H
47 #include <string.h>
48 #endif
50 #include <errno.h>
52 #include "../io/io.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)
60 INTEGER STAT
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 *,
65 gfc_charlen_type);
66 iexport_proto(stat_i4_sub);
68 void
69 stat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status,
70 gfc_charlen_type name_len)
72 int val;
73 char *str;
74 struct stat sb;
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] == ' ')
91 name_len--;
93 /* Make a null terminated copy of the string. */
94 str = gfc_alloca (name_len + 1);
95 memcpy (str, name, name_len);
96 str[name_len] = '\0';
98 val = stat(str, &sb);
100 if (val == 0)
102 /* Device ID */
103 sarray->data[0 * sarray->dim[0].stride] = sb.st_dev;
105 /* Inode number */
106 sarray->data[1 * sarray->dim[0].stride] = sb.st_ino;
108 /* File mode */
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;
114 /* Owner's uid */
115 sarray->data[4 * sarray->dim[0].stride] = sb.st_uid;
117 /* Owner's gid */
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;
123 #else
124 sarray->data[6 * sarray->dim[0].stride] = 0;
125 #endif
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;
142 #else
143 sarray->data[11 * sarray->dim[0].stride] = -1;
144 #endif
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;
149 #else
150 sarray->data[12 * sarray->dim[0].stride] = -1;
151 #endif
154 if (status != NULL)
155 *status = (val == 0) ? 0 : errno;
157 iexport(stat_i4_sub);
159 extern void stat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *,
160 gfc_charlen_type);
161 iexport_proto(stat_i8_sub);
163 void
164 stat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status,
165 gfc_charlen_type name_len)
167 int val;
168 char *str;
169 struct stat sb;
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] == ' ')
186 name_len--;
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);
195 if (val == 0)
197 /* Device ID */
198 sarray->data[0] = sb.st_dev;
200 /* Inode number */
201 sarray->data[sarray->dim[0].stride] = sb.st_ino;
203 /* File mode */
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;
209 /* Owner's uid */
210 sarray->data[4 * sarray->dim[0].stride] = sb.st_uid;
212 /* Owner's gid */
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;
218 #else
219 sarray->data[6 * sarray->dim[0].stride] = 0;
220 #endif
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;
237 #else
238 sarray->data[11 * sarray->dim[0].stride] = -1;
239 #endif
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;
244 #else
245 sarray->data[12 * sarray->dim[0].stride] = -1;
246 #endif
249 if (status != NULL)
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);
257 GFC_INTEGER_4
258 stat_i4 (char *name, gfc_array_i4 *sarray, gfc_charlen_type name_len)
260 GFC_INTEGER_4 val;
261 stat_i4_sub (name, sarray, &val, name_len);
262 return val;
265 extern GFC_INTEGER_8 stat_i8 (char *, gfc_array_i8 *, gfc_charlen_type);
266 export_proto(stat_i8);
268 GFC_INTEGER_8
269 stat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len)
271 GFC_INTEGER_8 val;
272 stat_i8_sub (name, sarray, &val, name_len);
273 return val;
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)
283 INTEGER FSTAT
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);
290 void
291 fstat_i4_sub (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray, GFC_INTEGER_4 *status)
293 int val;
294 struct stat sb;
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);
311 if (val >= 0)
312 val = fstat(val, &sb);
314 if (val == 0)
316 /* Device ID */
317 sarray->data[0 * sarray->dim[0].stride] = sb.st_dev;
319 /* Inode number */
320 sarray->data[1 * sarray->dim[0].stride] = sb.st_ino;
322 /* File mode */
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;
328 /* Owner's uid */
329 sarray->data[4 * sarray->dim[0].stride] = sb.st_uid;
331 /* Owner's gid */
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;
337 #else
338 sarray->data[6 * sarray->dim[0].stride] = 0;
339 #endif
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;
356 #else
357 sarray->data[11 * sarray->dim[0].stride] = -1;
358 #endif
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;
363 #else
364 sarray->data[12 * sarray->dim[0].stride] = -1;
365 #endif
368 if (status != NULL)
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);
376 void
377 fstat_i8_sub (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray, GFC_INTEGER_8 *status)
379 int val;
380 struct stat sb;
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);
397 if (val >= 0)
398 val = fstat(val, &sb);
400 if (val == 0)
402 /* Device ID */
403 sarray->data[0] = sb.st_dev;
405 /* Inode number */
406 sarray->data[sarray->dim[0].stride] = sb.st_ino;
408 /* File mode */
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;
414 /* Owner's uid */
415 sarray->data[4 * sarray->dim[0].stride] = sb.st_uid;
417 /* Owner's gid */
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;
423 #else
424 sarray->data[6 * sarray->dim[0].stride] = 0;
425 #endif
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;
442 #else
443 sarray->data[11 * sarray->dim[0].stride] = -1;
444 #endif
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;
449 #else
450 sarray->data[12 * sarray->dim[0].stride] = -1;
451 #endif
454 if (status != NULL)
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);
462 GFC_INTEGER_4
463 fstat_i4 (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray)
465 GFC_INTEGER_4 val;
466 fstat_i4_sub (unit, sarray, &val);
467 return val;
470 extern GFC_INTEGER_8 fstat_i8 (GFC_INTEGER_8 *, gfc_array_i8 *);
471 export_proto(fstat_i8);
473 GFC_INTEGER_8
474 fstat_i8 (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray)
476 GFC_INTEGER_8 val;
477 fstat_i8_sub (unit, sarray, &val);
478 return val;