add multiple dlopen emulation for Darwin

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@6604 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
master
Jacques Garrigue 2004-08-18 05:03:23 +00:00
parent 2c9f41ab42
commit 54aeaa6db4
1 changed files with 59 additions and 6 deletions

View File

@ -170,16 +170,57 @@ char * caml_search_dll_in_path(struct ext_table * path, char * name)
static char *dlerror_string = "No error";
/* Need to emulate dlopen behaviour by caching open libraries */
typedef struct bundle_entry {
struct bundle_entry *next;
char *name;
void *handle;
int count;
} entry_t;
entry_t bundle_list = {NULL,NULL,NULL,0};
entry_t *caml_lookup_bundle(const char *name)
{
entry_t *current = bundle_list.next, *last = &bundle_list;
while (current !=NULL) {
if (!strcmp(name,current->name))
return current;
last = current;
current = current->next;
}
current = (entry_t*) malloc(sizeof(entry_t)+strlen(name)+1);
current->name = (char*)(current+1);
strcpy(current->name, name);
current->count = 0;
current->next = NULL;
last->next = current;
return current;
}
void * caml_dlopen(char * libname)
{
NSObjectFileImage image;
NSObjectFileImageReturnCode retCode =
NSCreateObjectFileImageFromFile(libname, &image);
entry_t *bentry = caml_lookup_bundle(libname);
NSObjectFileImageReturnCode retCode;
void *result = NULL;
if (bentry->count > 0)
return bentry->handle;
retCode = NSCreateObjectFileImageFromFile(libname, &image);
switch (retCode) {
case NSObjectFileImageSuccess:
dlerror_string = NULL;
return (void*)NSLinkModule(image, libname, NSLINKMODULE_OPTION_BINDNOW
| NSLINKMODULE_OPTION_RETURN_ON_ERROR);
result = (void*)NSLinkModule(image, libname, NSLINKMODULE_OPTION_BINDNOW
| NSLINKMODULE_OPTION_RETURN_ON_ERROR);
if (result != NULL) {
bentry->count++;
bentry->handle = result;
}
else NSDestroyObjectFileImage(image);
break;
case NSObjectFileImageAccess:
dlerror_string = "cannot access this bundle"; break;
case NSObjectFileImageArch:
@ -190,13 +231,25 @@ void * caml_dlopen(char * libname)
default:
dlerror_string = "could not read object file"; break;
}
return NULL;
return result;
}
void caml_dlclose(void * handle)
{
entry_t *current = bundle_list.next;
int close = 1;
dlerror_string = NULL;
NSUnLinkModule((NSModule)handle, NSUNLINKMODULE_OPTION_NONE);
while (current != NULL) {
if (current->handle == handle) {
current->count--;
close = (current->count == 0);
break;
}
current = current->next;
}
if (close)
NSUnLinkModule((NSModule)handle, NSUNLINKMODULE_OPTION_NONE);
}
void * caml_dlsym(void * handle, char * name)