/* pub funs */ fixc_eng_t fixc_open_eng(const char *file) { static int mod_initted_p = 0; fixc_eng_t res; fixc_eng_f fun; /* speed-dating singleton */ if (!mod_initted_p) { /* initialise the dl system */ lt_dlinit(); /* add moddir to search path */ add_myself(); /* and just so we are a proper singleton */ mod_initted_p = 1; } if (UNLIKELY((res = my_dlopen(file)) == NULL)) { return NULL; } if ((fun = eng_sym(res, "fixc_get_cid")) != NULL) { __get_cid = (fixc_comp_t(*)())fun; } if ((fun = eng_sym(res, "fixc_get_aid")) != NULL) { __get_aid = (fixc_attr_t(*)())fun; } if ((fun = eng_sym(res, "fixc_get_mty")) != NULL) { __get_mty = (fixc_msgt_t(*)())fun; } if ((fun = eng_sym(res, "fixc_msgt_fixmlify")) != NULL) { __msgt_fixmlify = (const char*(*)())fun; } if ((fun = eng_sym(res, "fixc_comp_fixmlify")) != NULL) { __comp_fixmlify = (const char*(*)())fun; } if ((fun = eng_sym(res, "fixc_attr_fixmlify")) != NULL) { __attr_fixmlify = (const char*(*)())fun; } if ((fun = eng_sym(res, "fixc_comp_rptb")) != NULL) { __comp_rptb = (fixc_attr_t(*)())fun; } if ((fun = eng_sym(res, "fixc_get_comp_orb")) != NULL) { __get_comp_orb = (fixc_comp_t(*)())fun; } if ((fun = eng_sym(res, "fixc_get_comp_sub")) != NULL) { __get_comp_sub = (fixc_comp_sub_t(*)())fun; } if ((fun = eng_sym(res, "fixc_get_fld_ctx")) != NULL) { __get_fld_ctx = (fixc_fld_ctx_t(*)())fun; } return res; }
static void ffi_open_fn(VMState *state, CallInfo *info) { VM_ASSERT(info->args_len == 1, "wrong arity: expected 1, got %i", info->args_len); Object *root = state->root; Object *string_base = state->shared->vcache.string_base; Object *array_base = state->shared->vcache.array_base; Object *ffi = AS_OBJ(OBJECT_LOOKUP(root, ffi)); Object *handle_base = AS_OBJ(OBJECT_LOOKUP(ffi, handle)); StringObject *sarg = (StringObject*) obj_instance_of(OBJ_OR_NULL(load_arg(state->frame, INFO_ARGS_PTR(info)[0])), string_base); VM_ASSERT(sarg, "argument to ffi.open must be string!"); Object *libmap = AS_OBJ(OBJECT_LOOKUP(ffi, library_map)); char *file = sarg->value; bool file_found = false; FastKey file_key = prepare_key(file, strlen(file)); Value mapping = object_lookup_p(libmap, &file_key, &file_found); const char **file_list_ptr = NULL; int file_list_len = 0; if (file_found) { ArrayObject *aobj = (ArrayObject*) obj_instance_of(OBJ_OR_NULL(mapping), array_base); StringObject *sobj = (StringObject*) obj_instance_of(OBJ_OR_NULL(mapping), string_base); if (aobj) { file_list_len = aobj->length; file_list_ptr = malloc(sizeof(char*) * file_list_len); for (int i = 0; i < file_list_len; i++) { StringObject *file = (StringObject*) obj_instance_of(OBJ_OR_NULL(aobj->ptr[i]), string_base); VM_ASSERT(file, "library_map sub-entries must be string"); file_list_ptr[i] = my_asprintf("%s", file->value); // outside gc, make copy } } else if (sobj) { file_list_len = 1; file_list_ptr = malloc(sizeof(char*) * 1); file_list_ptr[0] = my_asprintf("%s", sobj->value); } else VM_ASSERT(false, "library_map entries must be string or array"); } else { file_list_len = 1; file_list_ptr = malloc(sizeof(char*) * 1); file_list_ptr[0] = file; } void *dlptr = my_dlopen(file_list_len, file_list_ptr); Object *handle_obj = AS_OBJ(make_object(state, handle_base, false)); handle_obj->flags |= OBJ_FROZEN; OBJECT_SET(state, handle_obj, pointer, make_ptr(state, dlptr)); vm_return(state, info, OBJ2VAL(handle_obj)); }
/** * Open NAME, call `init(CLO)' there. */ ud_mod_t ud_mod_open(const char *name) { static int mod_initted_p = 0; /* speed-dating singleton */ if (!mod_initted_p) { /* initialise the dl system */ lt_dlinit(); /* add moddir to search path */ add_myself(); /* and just so we are a proper singleton */ mod_initted_p = 1; } return my_dlopen(name); }
static dbi_driver_t *_get_driver(const char *filename, dbi_inst_t *inst) { dbi_driver_t *driver; void *dlhandle; void *symhandle; const char **custom_functions_list; unsigned int idx = 0; dbi_custom_function_t *prevcustom = NULL; dbi_custom_function_t *custom = NULL; const char* error; dlhandle = my_dlopen(filename, DLOPEN_FLAG); /* DLOPEN_FLAG defined by autoconf */ if (dlhandle == NULL) { fprintf(stderr, "%s\n", my_dlerror()); return NULL; } else { driver = malloc(sizeof(dbi_driver_t)); if (!driver) return NULL; driver->dlhandle = dlhandle; driver->filename = strdup(filename); driver->dbi_inst = inst; driver->next = NULL; driver->caps = NULL; driver->functions = malloc(sizeof(dbi_functions_t)); if (_dbi_driver_load_symbols(dlhandle, driver) != 0) { fprintf(stderr, "libdbi error: driver %s " "did not define all required methods\n", driver->filename); free(driver->functions); free(driver->filename); free(driver); return NULL; } driver->functions->register_driver(&driver->info, &custom_functions_list, &driver->reserved_words); driver->custom_functions = NULL; /* in case no custom functions are available */ /* this is a weird hack for the sake of dlsym portability. I can't imagine why using dlhandle fails on FreeBSD except that dlsym may expect a leading underscore in front of the function names. But then, why does RTLD_NEXT work? */ /* update 2008-11-28: this is most likely a FreeBSD bug which was fixed in 6.3. TODO: follow up on this once I have a 6.3 or later box */ if (DLSYM_HANDLE) { /* most OSes */ symhandle = dlhandle; } else { /* the BSDs */ symhandle = RTLD_NEXT; } while (custom_functions_list && custom_functions_list[idx] != NULL) { custom = malloc(sizeof(dbi_custom_function_t)); if (!custom) { _free_custom_functions(driver); free(driver->functions); free(driver->filename); free(driver); return NULL; } custom->next = NULL; custom->name = custom_functions_list[idx]; /* snprintf(function_name, 256, DLSYM_PREFIX "dbd_%s", custom->name); */ /* printf("loading %s<<\n", custom->name); */ my_dlerror(); /* clear any previous errors */ custom->function_pointer = my_dlsym(symhandle, custom->name); /* if (!custom->function_pointer) { */ if ((error = my_dlerror()) != NULL) { /* fprintf(STDERR, error); */ /* this usually fails because a function was renamed, is no longer available, or not yet available. Simply skip this function */ free(custom); /* not linked into the list yet */ idx++; continue; } if (driver->custom_functions == NULL) { driver->custom_functions = custom; } else { prevcustom->next = custom; } prevcustom = custom; idx++; } } return driver; }