📄 ltdl.c
字号:
{ /* Append a `.' to stop Windows from adding an implicit `.dll' extension. */ searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename)); if (searchname) sprintf (searchname, "%s.", filename); } if (!searchname) return 0;#if __CYGWIN__ { char wpath[MAX_PATH]; cygwin_conv_to_full_win32_path(searchname, wpath); module = LoadLibrary(wpath); }#else module = LoadLibrary (searchname);#endif LT_DLFREE (searchname); /* libltdl expects this function to fail if it is unable to physically load the library. Sadly, LoadLibrary will search the loaded libraries for a match and return one of them if the path search load fails. We check whether LoadLibrary is returning a handle to an already loaded module, and simulate failure if we find one. */ LT_DLMUTEX_LOCK (); cur = handles; while (cur) { if (!cur->module) { cur = 0; break; } if (cur->module == module) { break; } cur = cur->next; } LT_DLMUTEX_UNLOCK (); if (cur || !module) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); module = 0; } return module;}static intsys_wll_close (loader_data, module) lt_user_data loader_data; lt_module module;{ int errors = 0; if (FreeLibrary(module) == 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } return errors;}static lt_ptrsys_wll_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_ptr address = GetProcAddress (module, symbol); if (!address) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); } return address;}static struct lt_user_dlloader sys_wll = { 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0};#endif /* __WINDOWS__ *//* --- LOAD_ADD_ON() INTERFACE LOADER --- */#ifdef __BEOS__/* dynamic linking for BeOS */#include <kernel/image.h>static lt_modulesys_bedl_open (loader_data, filename) lt_user_data loader_data; const char *filename;{ image_id image = 0; if (filename) { image = load_add_on (filename); } else { image_info info; int32 cookie = 0; if (get_next_image_info (0, &cookie, &info) == B_OK) image = load_add_on (info.name); } if (image <= 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); image = 0; } return (lt_module) image;}static intsys_bedl_close (loader_data, module) lt_user_data loader_data; lt_module module;{ int errors = 0; if (unload_add_on ((image_id) module) != B_OK) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } return errors;}static lt_ptrsys_bedl_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_ptr address = 0; image_id image = (image_id) module; if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); address = 0; } return address;}static struct lt_user_dlloader sys_bedl = { 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0};#endif /* __BEOS__ *//* --- DLD_LINK() INTERFACE LOADER --- */#if HAVE_DLD/* dynamic linking with dld */#if HAVE_DLD_H#include <dld.h>#endifstatic lt_modulesys_dld_open (loader_data, filename) lt_user_data loader_data; const char *filename;{ lt_module module = strdup (filename); if (dld_link (filename) != 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); LT_DLFREE (module); module = 0; } return module;}static intsys_dld_close (loader_data, module) lt_user_data loader_data; lt_module module;{ int errors = 0; if (dld_unlink_by_file ((char*)(module), 1) != 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } else { LT_DLFREE (module); } return errors;}static lt_ptrsys_dld_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_ptr address = dld_get_func (symbol); if (!address) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); } return address;}static struct lt_user_dlloader sys_dld = { 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0};#endif /* HAVE_DLD *//* --- DLPREOPEN() INTERFACE LOADER --- *//* emulate dynamic linking using preloaded_symbols */typedef struct lt_dlsymlists_t{ struct lt_dlsymlists_t *next; const lt_dlsymlist *syms;} lt_dlsymlists_t;static const lt_dlsymlist *default_preloaded_symbols = 0;static lt_dlsymlists_t *preloaded_symbols = 0;static intpresym_init (loader_data) lt_user_data loader_data;{ int errors = 0; LT_DLMUTEX_LOCK (); preloaded_symbols = 0; if (default_preloaded_symbols) { errors = lt_dlpreload (default_preloaded_symbols); } LT_DLMUTEX_UNLOCK (); return errors;}static intpresym_free_symlists (){ lt_dlsymlists_t *lists; LT_DLMUTEX_LOCK (); lists = preloaded_symbols; while (lists) { lt_dlsymlists_t *tmp = lists; lists = lists->next; LT_DLFREE (tmp); } preloaded_symbols = 0; LT_DLMUTEX_UNLOCK (); return 0;}static intpresym_exit (loader_data) lt_user_data loader_data;{ presym_free_symlists (); return 0;}static intpresym_add_symlist (preloaded) const lt_dlsymlist *preloaded;{ lt_dlsymlists_t *tmp; lt_dlsymlists_t *lists; int errors = 0; LT_DLMUTEX_LOCK (); lists = preloaded_symbols; while (lists) { if (lists->syms == preloaded) { goto done; } lists = lists->next; } tmp = LT_EMALLOC (lt_dlsymlists_t, 1); if (tmp) { memset (tmp, 0, sizeof(lt_dlsymlists_t)); tmp->syms = preloaded; tmp->next = preloaded_symbols; preloaded_symbols = tmp; } else { ++errors; } done: LT_DLMUTEX_UNLOCK (); return errors;}static lt_modulepresym_open (loader_data, filename) lt_user_data loader_data; const char *filename;{ lt_dlsymlists_t *lists; lt_module module = (lt_module) 0; LT_DLMUTEX_LOCK (); lists = preloaded_symbols; if (!lists) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS)); goto done; } /* Can't use NULL as the reflective symbol header, as NULL is used to mark the end of the entire symbol list. Self-dlpreopened symbols follow this magic number, chosen to be an unlikely clash with a real module name. */ if (!filename) { filename = "@PROGRAM@"; } while (lists) { const lt_dlsymlist *syms = lists->syms; while (syms->name) { if (!syms->address && strcmp(syms->name, filename) == 0) { module = (lt_module) syms; goto done; } ++syms; } lists = lists->next; } LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); done: LT_DLMUTEX_UNLOCK (); return module;}static intpresym_close (loader_data, module) lt_user_data loader_data; lt_module module;{ /* Just to silence gcc -Wall */ module = 0; return 0;}static lt_ptrpresym_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol;{ lt_dlsymlist *syms = (lt_dlsymlist*) module; ++syms; while (syms->address) { if (strcmp(syms->name, symbol) == 0) { return syms->address; } ++syms; } LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); return 0;}static struct lt_user_dlloader presym = { 0, presym_open, presym_close, presym_sym, presym_exit, 0};/* --- DYNAMIC MODULE LOADING --- *//* The type of a function used at each iteration of foreach_dirinpath(). */typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1, lt_ptr data2));static int foreach_dirinpath LT_PARAMS((const char *search_path, const char *base_name, foreach_callback_func *func, lt_ptr data1, lt_ptr data2));static int find_file_callback LT_PARAMS((char *filename, lt_ptr data, lt_ptr ignored));static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data, lt_ptr ignored));static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1, lt_ptr data2));static int canonicalize_path LT_PARAMS((const char *path, char **pcanonical));static int argzize_path LT_PARAMS((const char *path, char **pargz, size_t *pargz_len));static FILE *find_file LT_PARAMS((const char *search_path, const char *base_name, char **pdir));static lt_dlhandle *find_handle LT_PARAMS((const char *search_path, const char *base_name, lt_dlhandle *handle));static int find_module LT_PARAMS((lt_dlhandle *handle, const char *dir, const char *libdir, const char *dlname, const char *old_name, int installed));static int free_vars LT_PARAMS((char *dlname, char *oldname, char *libdir, char *deplibs));static int load_deplibs LT_PARAMS((lt_dlhandle handle, char *deplibs));static int trim LT_PARAMS((char **dest, const char *str));static int try_dlopen LT_PARAMS((lt_dlhandle *handle, const char *filename));static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, const char *filename));static int unload_deplibs LT_PARAMS((lt_dlhandle handle));static int lt_argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, char *before, const char *entry));static int lt_argz_insertinorder LT_PARAMS((char **pargz, size_t *pargz_len, const char *entry));static int lt_argz_insertdir LT_PARAMS((char **pargz, size_t *pargz_len, const char *dirnam, struct dirent *dp));static int lt_dlpath_insertdir LT_PARAMS((char **ppath, char *before, const char *dir));static int list_files_by_dir LT_PARAMS((const char *dirnam, char **pargz, size_t *pargz_len));static int file_not_found LT_PARAMS((void));static char *user_search_path= 0;static lt_dlloader *loaders = 0;static lt_dlhandle handles = 0;static int initialized = 0;/* Initialize libltdl. */intlt_dlinit (){ int errors = 0; LT_DLMUTEX_LOCK (); /* Initialize only at first call. */ if (++initialized == 1) { handles = 0; user_search_path = 0; /* empty search path */#if HAVE_LIBDL && !defined(__CYGWIN__) errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");#endif#if HAVE_SHL_LOAD errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");#endif#ifdef __WINDOWS__ errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");#endif#ifdef __BEOS__ errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");#endif#if HAVE_DLD errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");#endif errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload"); if (presym_init (presym.dlloader_data)) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); ++errors; } else if (errors != 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED)); ++errors; } } LT_DLMUTEX_UNLOCK (); return errors;}intlt_dlpreload (preloaded) const lt_dlsymlist *preloaded;{ int errors = 0; if (preloaded) { errors = presym_add_symlist (preloaded); } else { presym_free_symlists(); LT_DLMUTEX_LOCK (); if (default_preloaded_symbols) { errors = lt_dlpreload (default_preloaded_symbols); } LT_DLMUTEX_UNLOCK (); } return errors;}intlt_dlpreload_default (preloaded) const lt_dlsymlist *preloaded;{ LT_DLMUTEX_LOCK (); default_preloaded_symbols = preloaded; LT_DLMUTEX_UNLOCK (); return 0;}intlt_dlexit (){ /* shut down libltdl */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -