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 /***********************************************************************/
16 /* Basic system calls */
25 #include <sys/types.h>
35 #include <sys/times.h>
39 #include <sys/resource.h>
41 #ifdef HAS_GETTIMEOFDAY
58 static char * error_message(void)
60 return strerror(errno
);
67 #define EWOULDBLOCK (-1)
70 CAMLexport
void caml_sys_error(value arg
)
76 err
= error_message();
78 str
= caml_copy_string(err
);
80 int err_len
= strlen(err
);
81 int arg_len
= caml_string_length(arg
);
82 str
= caml_alloc_string(arg_len
+ 2 + err_len
);
83 memmove(&Byte(str
, 0), String_val(arg
), arg_len
);
84 memmove(&Byte(str
, arg_len
), ": ", 2);
85 memmove(&Byte(str
, arg_len
+ 2), err
, err_len
);
87 caml_raise_sys_error(str
);
91 CAMLexport
void caml_sys_io_error(value arg
)
93 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
) {
94 caml_raise_sys_blocked_io();
100 CAMLprim value
caml_sys_exit(value retcode
)
103 caml_debugger(PROGRAM_EXIT
);
105 exit(Int_val(retcode
));
117 #define O_NONBLOCK O_NDELAY
123 static int sys_open_flags
[] = {
124 O_RDONLY
, O_WRONLY
, O_APPEND
| O_WRONLY
, O_CREAT
, O_TRUNC
, O_EXCL
,
125 O_BINARY
, O_TEXT
, O_NONBLOCK
128 CAMLprim value
caml_sys_open(value path
, value vflags
, value vperm
)
130 CAMLparam3(path
, vflags
, vperm
);
134 p
= caml_stat_alloc(caml_string_length(path
) + 1);
135 strcpy(p
, String_val(path
));
136 flags
= caml_convert_flag_list(vflags
, sys_open_flags
);
137 perm
= Int_val(vperm
);
138 /* open on a named FIFO can block (PR#1533) */
139 caml_enter_blocking_section();
140 fd
= open(p
, flags
, perm
);
141 caml_leave_blocking_section();
143 if (fd
== -1) caml_sys_error(path
);
144 #if defined(F_SETFD) && defined(FD_CLOEXEC)
145 fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
147 CAMLreturn(Val_long(fd
));
150 CAMLprim value
caml_sys_close(value fd
)
156 CAMLprim value
caml_sys_file_exists(value name
)
159 return Val_bool(stat(String_val(name
), &st
) == 0);
162 CAMLprim value
caml_sys_is_directory(value name
)
165 if (stat(String_val(name
), &st
) == -1) caml_sys_error(name
);
167 return Val_bool(S_ISDIR(st
.st_mode
));
169 return Val_bool(st
.st_mode
& S_IFDIR
);
173 CAMLprim value
caml_sys_remove(value name
)
176 ret
= unlink(String_val(name
));
177 if (ret
!= 0) caml_sys_error(name
);
181 CAMLprim value
caml_sys_rename(value oldname
, value newname
)
183 if (rename(String_val(oldname
), String_val(newname
)) != 0)
184 caml_sys_error(NO_ARG
);
188 CAMLprim value
caml_sys_chdir(value dirname
)
190 if (chdir(String_val(dirname
)) != 0) caml_sys_error(dirname
);
194 CAMLprim value
caml_sys_getcwd(value unit
)
198 if (getcwd(buff
, sizeof(buff
)) == 0) caml_sys_error(NO_ARG
);
200 if (getwd(buff
) == 0) caml_sys_error(NO_ARG
);
201 #endif /* HAS_GETCWD */
202 return caml_copy_string(buff
);
205 CAMLprim value
caml_sys_getenv(value var
)
209 res
= getenv(String_val(var
));
210 if (res
== 0) caml_raise_not_found();
211 return caml_copy_string(res
);
214 char * caml_exe_name
;
215 static char ** caml_main_argv
;
217 CAMLprim value
caml_sys_get_argv(value unit
)
219 CAMLparam0 (); /* unit is unused */
220 CAMLlocal3 (exe_name
, argv
, res
);
221 exe_name
= caml_copy_string(caml_exe_name
);
222 argv
= caml_copy_string_array((char const **) caml_main_argv
);
223 res
= caml_alloc_small(2, 0);
224 Field(res
, 0) = exe_name
;
225 Field(res
, 1) = argv
;
229 void caml_sys_init(char * exe_name
, char **argv
)
231 caml_exe_name
= exe_name
;
232 caml_main_argv
= argv
;
236 #define WIFEXITED(status) 1
237 #define WEXITSTATUS(status) (status)
239 #if !(defined(WIFEXITED) && defined(WEXITSTATUS))
240 /* Assume old-style V7 status word */
241 #define WIFEXITED(status) (((status) & 0xFF) == 0)
242 #define WEXITSTATUS(status) (((status) >> 8) & 0xFF)
246 CAMLprim value
caml_sys_system_command(value command
)
248 CAMLparam1 (command
);
253 len
= caml_string_length (command
);
254 buf
= caml_stat_alloc (len
+ 1);
255 memmove (buf
, String_val (command
), len
+ 1);
256 caml_enter_blocking_section ();
257 status
= system(buf
);
258 caml_leave_blocking_section ();
260 if (status
== -1) caml_sys_error(command
);
261 if (WIFEXITED(status
))
262 retcode
= WEXITSTATUS(status
);
265 CAMLreturn (Val_int(retcode
));
268 CAMLprim value
caml_sys_time(value unit
)
273 getrusage (RUSAGE_SELF
, &ru
);
274 return caml_copy_double (ru
.ru_utime
.tv_sec
+ ru
.ru_utime
.tv_usec
/ 1e6
275 + ru
.ru_stime
.tv_sec
+ ru
.ru_stime
.tv_usec
/ 1e6
);
287 return caml_copy_double((double)(t
.tms_utime
+ t
.tms_stime
) / CLK_TCK
);
289 /* clock() is standard ANSI C */
290 return caml_copy_double((double)clock() / CLOCKS_PER_SEC
);
296 extern intnat
caml_win32_random_seed (void);
299 CAMLprim value
caml_sys_random_seed (value unit
)
302 return Val_long(caml_win32_random_seed());
305 #ifdef HAS_GETTIMEOFDAY
307 gettimeofday(&tv
, NULL
);
308 seed
= tv
.tv_sec
^ tv
.tv_usec
;
313 seed
^= (getppid() << 16) ^ getpid();
315 return Val_long(seed
);
319 CAMLprim value
caml_sys_get_config(value unit
)
321 CAMLparam0 (); /* unit is unused */
322 CAMLlocal2 (result
, ostype
);
324 ostype
= caml_copy_string(OCAML_OS_TYPE
);
325 result
= caml_alloc_small (2, 0);
326 Field(result
, 0) = ostype
;
327 Field(result
, 1) = Val_long (8 * sizeof(value
));
331 CAMLprim value
caml_sys_read_directory(value path
)
335 struct ext_table tbl
;
337 caml_ext_table_init(&tbl
, 50);
338 if (caml_read_directory(String_val(path
), &tbl
) == -1){
339 caml_ext_table_free(&tbl
, 1);
340 caml_sys_error(path
);
342 caml_ext_table_add(&tbl
, NULL
);
343 result
= caml_copy_string_array((char const **) tbl
.contents
);
344 caml_ext_table_free(&tbl
, 1);