diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2001-08-28 14:47:48 +0000 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 2001-08-28 14:47:48 +0000 |
commit | ddd99c7e5d2f0f8e7364e8521fa7e8308999344e (patch) | |
tree | 3c0158d035a52c0cf185c08c3288c3c76d6718d0 /byterun/unix.c | |
parent | c345611817d76ccc3bbd02db1f942774220739f9 (diff) |
Chargement dynamique de primitives C
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@3677 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'byterun/unix.c')
-rw-r--r-- | byterun/unix.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/byterun/unix.c b/byterun/unix.c new file mode 100644 index 000000000..5926391b1 --- /dev/null +++ b/byterun/unix.c @@ -0,0 +1,198 @@ +/***********************************************************************/ +/* */ +/* Objective Caml */ +/* */ +/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ +/* */ +/* Copyright 2001 Institut National de Recherche en Informatique et */ +/* en Automatique. All rights reserved. This file is distributed */ +/* under the terms of the GNU Library General Public License. */ +/* */ +/***********************************************************************/ + +/* $Id$ */ + +/* Unix-specific stuff */ + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "config.h" +#ifdef SUPPORT_DYNAMIC_LINKING +#include <dlfcn.h> +#endif +#include "memory.h" +#include "misc.h" +#include "osdeps.h" + +#ifndef S_ISREG +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif + +char * decompose_path(struct ext_table * tbl, char * path) +{ + char * p, * q; + int n; + + if (path == NULL) return NULL; + p = stat_alloc(strlen(path) + 1); + strcpy(p, path); + q = p; + while (1) { + for (n = 0; q[n] != 0 && q[n] != ':'; n++) /*nothing*/; + ext_table_add(tbl, q); + q = q + n; + if (*q == 0) break; + *q = 0; + q += 1; + } + return p; +} + +char * search_in_path(struct ext_table * path, char * name) +{ + char * p, * fullname; + int i; + struct stat st; + + for (p = name; *p != 0; p++) { + if (*p == '/') goto not_found; + } + for (i = 0; i < path->size; i++) { + fullname = stat_alloc(strlen((char *)(path->contents[i])) + + strlen(name) + 2); + strcpy(fullname, (char *)(path->contents[i])); + if (fullname[0] != 0) strcat(fullname, "/"); + strcat(fullname, name); + if (stat(fullname, &st) == 0 && S_ISREG(st.st_mode)) return fullname; + stat_free(fullname); + } + not_found: + fullname = stat_alloc(strlen(name) + 1); + strcpy(fullname, name); + return fullname; +} + +#ifdef __CYGWIN32__ + +/* Cygwin needs special treatment because of the implicit ".exe" at the + end of executable file names */ + +static int cygwin_file_exists(char * name) +{ + int fd; + /* Cannot use stat() here because it adds ".exe" implicitly */ + fd = open(name, O_RDONLY); + if (fd == -1) return 0; + close(fd); + return 1; +} + +static char * cygwin_search_exe_in_path(struct ext_table * path, char * name) +{ + char * p, * fullname; + int i; + + for (p = name; *p != 0; p++) { + if (*p == '/' || *p == '\\') goto not_found; + } + for (i = 0; i < path->size; i++) { + fullname = stat_alloc(strlen((char *)(path->contents[i])) + + strlen(name) + 6); + strcpy(fullname, (char *)(path->contents[i])); + strcat(fullname, "/"); + strcat(fullname, name); + if (cygwin_file_exists(fullname)) return fullname; + strcat(fullname, ".exe"); + if (cygwin_file_exists(fullname)) return fullname; + stat_free(fullname); + } + not_found: + fullname = stat_alloc(strlen(name) + 5); + strcpy(fullname, name); + if (cygwin_file_exists(fullname)) return fullname; + strcat(fullname, ".exe"); + if (cygwin_file_exists(fullname)) return fullname; + strcpy(fullname, name); + return fullname; +} + +#endif + +char * search_exe_in_path(char * name) +{ + struct ext_table path; + char * tofree; + char * res; + + ext_table_init(&path, 8); + tofree = decompose_path(&path, getenv("PATH")); +#ifndef __CYGWIN32__ + res = search_in_path(&path, name); +#else + res = cygwin_search_exe_in_path(&path, name); +#endif + stat_free(tofree); + ext_table_free(&path, 0); + return res; +} + +char * search_dll_in_path(struct ext_table * path, char * name) +{ + char * dllname = stat_alloc(strlen(name) + 4); + char * res; + strcpy(dllname, name); + strcat(dllname, ".so"); + res = search_in_path(path, dllname); + stat_free(dllname); + return res; +} + +#ifdef SUPPORT_DYNAMIC_LINKING + +void * caml_dlopen(char * libname) +{ + return dlopen(libname, RTLD_NOW); +} + +void caml_dlclose(void * handle) +{ + dlclose(handle); +} + +void * caml_dlsym(void * handle, char * name) +{ + return dlsym(handle, name); +} + +char * caml_dlerror(void) +{ + return dlerror(); +} + +#else + +void * caml_dlopen(char * libname) +{ + return NULL; +} + +void caml_dlclose(void * handle) +{ +} + +void * caml_dlsym(void * handle, char * name) +{ + return NULL; +} + +char * caml_dlerror(void) +{ + return "dynamic loading not supported on this platform"; +} + +#endif + |