summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--byterun/osdeps.h5
-rw-r--r--byterun/sys.c14
-rw-r--r--byterun/unix.c33
-rw-r--r--byterun/win32.c23
-rw-r--r--stdlib/sys.ml1
-rw-r--r--stdlib/sys.mli17
6 files changed, 89 insertions, 4 deletions
diff --git a/byterun/osdeps.h b/byterun/osdeps.h
index a066547f0..02be9eacc 100644
--- a/byterun/osdeps.h
+++ b/byterun/osdeps.h
@@ -50,6 +50,11 @@ extern void * caml_dlsym(void * handle, char * name);
/* Return an error message describing the most recent dynlink failure. */
extern char * caml_dlerror(void);
+/* Add to [contents] the (short) names of the files contained in
+ the directory named [dirname]. No entries are added for [.] and [..].
+ Return 0 on success, -1 on error; set errno in the case of error. */
+extern int caml_read_directory(char * dirname, struct ext_table * contents);
+
#ifdef __linux__
/* Recover executable name from /proc/self/exe if possible */
extern int executable_name(char * name, int name_len);
diff --git a/byterun/sys.c b/byterun/sys.c
index e0f8ec8bd..01184b908 100644
--- a/byterun/sys.c
+++ b/byterun/sys.c
@@ -47,6 +47,7 @@
#include "fail.h"
#include "instruct.h"
#include "mlvalues.h"
+#include "osdeps.h"
#include "signals.h"
#include "stacks.h"
#include "sys.h"
@@ -336,3 +337,16 @@ CAMLprim value sys_get_config(value unit)
CAMLreturn (result);
}
+CAMLprim value sys_read_directory(value path)
+{
+ CAMLparam1(path);
+ CAMLlocal1(result);
+ struct ext_table tbl;
+
+ ext_table_init(&tbl, 50);
+ if (caml_read_directory(String_val(path), &tbl) == -1) sys_error(path);
+ ext_table_add(&tbl, NULL);
+ result = copy_string_array((char const **) tbl.contents);
+ ext_table_free(&tbl, 1);
+ CAMLreturn(result);
+}
diff --git a/byterun/unix.c b/byterun/unix.c
index 65c960a3b..c47544217 100644
--- a/byterun/unix.c
+++ b/byterun/unix.c
@@ -32,6 +32,11 @@
#ifdef HAS_UNISTD
#include <unistd.h>
#endif
+#ifdef HAS_DIRENT
+#include <dirent.h>
+#else
+#include <sys/dir.h>
+#endif
#include "memory.h"
#include "misc.h"
#include "osdeps.h"
@@ -322,6 +327,34 @@ void aligned_munmap (char * addr, asize_t size)
#endif
+/* Add to [contents] the (short) names of the files contained in
+ the directory named [dirname]. No entries are added for [.] and [..].
+ Return 0 on success, -1 on error; set errno in the case of error. */
+
+int caml_read_directory(char * dirname, struct ext_table * contents)
+{
+ DIR * d;
+#ifdef HAS_DIRENT
+ struct dirent * e;
+#else
+ struct direct * e;
+#endif
+ char * p;
+
+ d = opendir(dirname);
+ if (d == NULL) return -1;
+ while (1) {
+ e = readdir(d);
+ if (e == NULL) break;
+ if (strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0) continue;
+ p = stat_alloc(strlen(e->d_name) + 1);
+ strcpy(p, e->d_name);
+ ext_table_add(contents, p);
+ }
+ closedir(d);
+ return 0;
+}
+
/* Recover executable name from /proc/self/exe if possible */
#ifdef __linux__
diff --git a/byterun/win32.c b/byterun/win32.c
index 013a8dbff..f4349f2b9 100644
--- a/byterun/win32.c
+++ b/byterun/win32.c
@@ -371,6 +371,29 @@ int win32_system(char * cmdline)
}
}
+/* Add to [contents] the (short) names of the files contained in
+ the directory named [dirname]. No entries are added for [.] and [..].
+ Return 0 on success, -1 on error; set errno in the case of error. */
+
+int caml_read_directory(char * dirname, struct ext_table * contents)
+{
+ int d;
+ struct _finddata_t fileinfo;
+ char * p;
+
+ h = _findfirst(dirname, &fileinfo);
+ if (h == -1) return errno == ENOENT ? 0 : -1;
+ do {
+ if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) {
+ p = stat_alloc(strlen(fileinfo.name) + 1);
+ strcpy(p, fileinfo.name);
+ ext_table_add(contents, p);
+ }
+ } while (_findnext(h, &fileinfo) == 0);
+ _findclose(h);
+ return 0;
+}
+
#ifndef NATIVE_CODE
/* Set up a new thread for control-C emulation and termination */
diff --git a/stdlib/sys.ml b/stdlib/sys.ml
index 0b87b4189..77d91abb7 100644
--- a/stdlib/sys.ml
+++ b/stdlib/sys.ml
@@ -31,6 +31,7 @@ external command: string -> int = "sys_system_command"
external time: unit -> float = "sys_time"
external chdir: string -> unit = "sys_chdir"
external getcwd: unit -> string = "sys_getcwd"
+external readdir : string -> string array = "sys_read_directory"
let interactive = ref false
diff --git a/stdlib/sys.mli b/stdlib/sys.mli
index ff5c43502..551e958a6 100644
--- a/stdlib/sys.mli
+++ b/stdlib/sys.mli
@@ -51,6 +51,15 @@ external chdir : string -> unit = "sys_chdir"
external getcwd : unit -> string = "sys_getcwd"
(** Return the current working directory of the process. *)
+external readdir : string -> string array = "sys_read_directory"
+(** Return the names of all files present in the given directory.
+ Names denoting the current directory and the parent directory
+ (["."] and [".."] in Unix) are not returned. Each string in the
+ result is a file name rather than a complete path. There is no
+ guarantee that the name strings in the resulting array will appear
+ in any specific order; they are not, in particular, guaranteed to
+ appear in alphabetical order. *)
+
val interactive : bool ref
(** This reference is initially set to [false] in standalone
programs and to [true] if the code is being executed under
@@ -58,10 +67,10 @@ val interactive : bool ref
val os_type : string
(** Operating system currently executing the Caml program. One of
- ["Unix"] (for all Unix versions, including Linux and Mac OS X),
- ["Win32"] (for MS-Windows, OCaml compiled with MSVC++),
- ["Cygwin"] (for MS-Windows, OCaml compiled with Cygwin),
- ["MacOS"] (for MacOS 9). *)
+- ["Unix"] (for all Unix versions, including Linux and Mac OS X),
+- ["Win32"] (for MS-Windows, OCaml compiled with MSVC++ or Mingw),
+- ["Cygwin"] (for MS-Windows, OCaml compiled with Cygwin),
+- ["MacOS"] (for MacOS 9). *)
val word_size : int
(** Size of one word on the machine currently executing the Caml