1 /***********************************************************************/
5 /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
7 /* Copyright 1996 Institut National de Recherche en Informatique et */
8 /* en Automatique. All rights reserved. This file is distributed */
9 /* under the terms of the GNU Library General Public License, with */
10 /* the special exception on linking described in file ../../LICENSE. */
12 /***********************************************************************/
20 #include "unixsupport.h"
21 #include "cst2constr.h"
22 #include <sys/types.h>
40 #define EOVERFLOW ERANGE
43 static int file_kind_table
[] = {
44 S_IFREG
, S_IFDIR
, S_IFCHR
, S_IFBLK
, S_IFLNK
, S_IFIFO
, S_IFSOCK
47 static value
stat_aux(int use_64
, struct stat
*buf
)
50 CAMLlocal5(atime
, mtime
, ctime
, offset
, v
);
52 atime
= copy_double((double) buf
->st_atime
);
53 mtime
= copy_double((double) buf
->st_mtime
);
54 ctime
= copy_double((double) buf
->st_ctime
);
55 offset
= use_64
? Val_file_offset(buf
->st_size
) : Val_int (buf
->st_size
);
56 v
= alloc_small(12, 0);
57 Field (v
, 0) = Val_int (buf
->st_dev
);
58 Field (v
, 1) = Val_int (buf
->st_ino
);
59 Field (v
, 2) = cst_to_constr(buf
->st_mode
& S_IFMT
, file_kind_table
,
60 sizeof(file_kind_table
) / sizeof(int), 0);
61 Field (v
, 3) = Val_int (buf
->st_mode
& 07777);
62 Field (v
, 4) = Val_int (buf
->st_nlink
);
63 Field (v
, 5) = Val_int (buf
->st_uid
);
64 Field (v
, 6) = Val_int (buf
->st_gid
);
65 Field (v
, 7) = Val_int (buf
->st_rdev
);
66 Field (v
, 8) = offset
;
68 Field (v
, 10) = mtime
;
69 Field (v
, 11) = ctime
;
73 CAMLprim value
unix_stat(value path
)
77 ret
= stat(String_val(path
), &buf
);
78 if (ret
== -1) uerror("stat", path
);
79 if (buf
.st_size
> Max_long
&& (buf
.st_mode
& S_IFMT
) == S_IFREG
)
80 unix_error(EOVERFLOW
, "stat", path
);
81 return stat_aux(0, &buf
);
84 CAMLprim value
unix_lstat(value path
)
89 ret
= lstat(String_val(path
), &buf
);
91 ret
= stat(String_val(path
), &buf
);
93 if (ret
== -1) uerror("lstat", path
);
94 if (buf
.st_size
> Max_long
&& (buf
.st_mode
& S_IFMT
) == S_IFREG
)
95 unix_error(EOVERFLOW
, "lstat", path
);
96 return stat_aux(0, &buf
);
99 CAMLprim value
unix_fstat(value fd
)
103 ret
= fstat(Int_val(fd
), &buf
);
104 if (ret
== -1) uerror("fstat", Nothing
);
105 if (buf
.st_size
> Max_long
&& (buf
.st_mode
& S_IFMT
) == S_IFREG
)
106 unix_error(EOVERFLOW
, "fstat", Nothing
);
107 return stat_aux(0, &buf
);
110 CAMLprim value
unix_stat_64(value path
)
114 ret
= stat(String_val(path
), &buf
);
115 if (ret
== -1) uerror("stat", path
);
116 return stat_aux(1, &buf
);
119 CAMLprim value
unix_lstat_64(value path
)
124 ret
= lstat(String_val(path
), &buf
);
126 ret
= stat(String_val(path
), &buf
);
128 if (ret
== -1) uerror("lstat", path
);
129 return stat_aux(1, &buf
);
132 CAMLprim value
unix_fstat_64(value fd
)
136 ret
= fstat(Int_val(fd
), &buf
);
137 if (ret
== -1) uerror("fstat", Nothing
);
138 return stat_aux(1, &buf
);