📄 ltdl.c
字号:
{ ++errors; goto cleanup; } strncpy (dir, canonical, dirlen); dir[dirlen] = LT_EOS_CHAR; ++base_name; } else MEMREASSIGN (base_name, canonical); assert (base_name && *base_name); if (!ext) { ext = base_name + LT_STRLEN (base_name); } ext = strrchr (base_name, '.'); /* extract the module name from the file name */ name = MALLOC (char, ext - base_name + 1); if (!name) { ++errors; goto cleanup; } /* canonicalize the module name */ { int i; for (i = 0; i < ext - base_name; ++i) { if (isalnum ((unsigned char)(base_name[i]))) { name[i] = base_name[i]; } else { name[i] = '_'; } } name[ext - base_name] = LT_EOS_CHAR; } /* Before trawling through the filesystem in search of a module, check whether we are opening a preloaded module. */ if (!dir) { const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen"); if (vtable) { *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle)); if (*phandle == NULL) { ++errors; goto cleanup; } newhandle = *phandle; if (tryall_dlopen (&newhandle, attempt, advise, vtable) == 0) { goto register_handle; } /* If we're still here, there was no matching preloaded module, so put things back as we found them, and continue searching. */ FREE (*phandle); newhandle = NULL; } } /* Check whether we are opening a libtool module (.la extension). */ if (ext && streq (ext, archive_ext)) { /* this seems to be a libtool module */ FILE * file = 0; char * dlname = 0; char * old_name = 0; char * libdir = 0; char * deplibs = 0; /* if we can't find the installed flag, it is probably an installed libtool archive, produced with an old version of libtool */ int installed = 1; /* Now try to open the .la file. If there is no directory name component, try to find it first in user_search_path and then other prescribed paths. Otherwise (or in any case if the module was not yet found) try opening just the module name as passed. */ if (!dir) { const char *search_path = user_search_path; if (search_path) file = find_file (user_search_path, base_name, &dir); if (!file) { search_path = getenv (LTDL_SEARCHPATH_VAR); if (search_path) file = find_file (search_path, base_name, &dir); }#if defined(LT_MODULE_PATH_VAR) if (!file) { search_path = getenv (LT_MODULE_PATH_VAR); if (search_path) file = find_file (search_path, base_name, &dir); }#endif#if defined(LT_DLSEARCH_PATH) if (!file && sys_dlsearch_path) { file = find_file (sys_dlsearch_path, base_name, &dir); }#endif } if (!file) { file = fopen (attempt, LT_READTEXT_MODE); } /* If we didn't find the file by now, it really isn't there. Set the status flag, and bail out. */ if (!file) { LT__SETERROR (FILE_NOT_FOUND); ++errors; goto cleanup; } /* read the .la file */ if (parse_dotla_file(file, &dlname, &libdir, &deplibs, &old_name, &installed) != 0) ++errors; fclose (file); /* allocate the handle */ *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle)); if (*phandle == 0) ++errors; if (errors) { FREE (dlname); FREE (old_name); FREE (libdir); FREE (deplibs); FREE (*phandle); goto cleanup; } assert (*phandle); if (load_deplibs (*phandle, deplibs) == 0) { newhandle = *phandle; /* find_module may replace newhandle */ if (find_module (&newhandle, dir, libdir, dlname, old_name, installed, advise)) { unload_deplibs (*phandle); ++errors; } } else { ++errors; } FREE (dlname); FREE (old_name); FREE (libdir); FREE (deplibs); if (errors) { FREE (*phandle); goto cleanup; } if (*phandle != newhandle) { unload_deplibs (*phandle); } } else { /* not a libtool module */ *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle)); if (*phandle == 0) { ++errors; goto cleanup; } newhandle = *phandle; /* If the module has no directory name component, try to find it first in user_search_path and then other prescribed paths. Otherwise (or in any case if the module was not yet found) try opening just the module name as passed. */ if ((dir || (!find_handle (user_search_path, base_name, &newhandle, advise) && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, &newhandle, advise)#if defined(LT_MODULE_PATH_VAR) && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name, &newhandle, advise)#endif#if defined(LT_DLSEARCH_PATH) && !find_handle (sys_dlsearch_path, base_name, &newhandle, advise)#endif ))) { if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0) { newhandle = NULL; } } if (!newhandle) { FREE (*phandle); ++errors; goto cleanup; } } register_handle: MEMREASSIGN (*phandle, newhandle); if (((lt__handle *) *phandle)->info.ref_count == 0) { ((lt__handle *) *phandle)->info.ref_count = 1; MEMREASSIGN (((lt__handle *) *phandle)->info.name, name); ((lt__handle *) *phandle)->next = (lt__handle *) handles; handles = *phandle; } LT__SETERRORSTR (saved_error); cleanup: FREE (dir); FREE (attempt); FREE (name); if (!canonical) /* was MEMREASSIGNed */ FREE (base_name); FREE (canonical); return errors;}/* If the last error messge store was `FILE_NOT_FOUND', then return non-zero. */static intfile_not_found (void){ const char *error = 0; LT__GETERROR (error); if (error == LT__STRERROR (FILE_NOT_FOUND)) return 1; return 0;}/* Unless FILENAME already bears a suitable library extension, then return 0. */static inthas_library_ext (const char *filename){ char * ext = 0; size_t len; assert (filename); len = LT_STRLEN (filename); ext = strrchr (filename, '.'); if (ext && ((streq (ext, archive_ext))#if defined(LT_MODULE_EXT) || (streq (ext, shlib_ext))#endif )) { return 1; } return 0;}/* Initialise and configure a user lt_dladvise opaque object. */intlt_dladvise_init (lt_dladvise *padvise){ lt__advise *advise = (lt__advise *) lt__zalloc (sizeof (lt__advise)); *padvise = advise; return (advise ? 0 : 1);}intlt_dladvise_destroy (lt_dladvise *padvise){ if (padvise) FREE(*padvise); return 0;}intlt_dladvise_ext (lt_dladvise *padvise){ assert (padvise && *padvise); ((lt__advise *) *padvise)->try_ext = 1; return 0;}intlt_dladvise_resident (lt_dladvise *padvise){ assert (padvise && *padvise); ((lt__advise *) *padvise)->is_resident = 1; return 0;}intlt_dladvise_local (lt_dladvise *padvise){ assert (padvise && *padvise); ((lt__advise *) *padvise)->is_symlocal = 1; return 0;}intlt_dladvise_global (lt_dladvise *padvise){ assert (padvise && *padvise); ((lt__advise *) *padvise)->is_symglobal = 1; return 0;}/* Libtool-1.5.x interface for loading a new module named FILENAME. */lt_dlhandlelt_dlopen (const char *filename){ return lt_dlopenadvise (filename, NULL);}/* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, and if a file is still not found try again with MODULE_EXT appended instead. */lt_dlhandlelt_dlopenext (const char *filename){ lt_dlhandle handle = 0; lt_dladvise advise; if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise)) handle = lt_dlopenadvise (filename, advise); lt_dladvise_destroy (&advise); return handle;}lt_dlhandlelt_dlopenadvise (const char *filename, lt_dladvise advise){ lt_dlhandle handle = 0; int errors = 0; /* Can't have symbols hidden and visible at the same time! */ if (advise && ((lt__advise *) advise)->is_symlocal && ((lt__advise *) advise)->is_symglobal) { LT__SETERROR (CONFLICTING_FLAGS); return 0; } if (!filename || !advise || !((lt__advise *) advise)->try_ext || has_library_ext (filename)) { /* Just incase we missed a code path in try_dlopen() that reports an error, but forgot to reset handle... */ if (try_dlopen (&handle, filename, NULL, advise) != 0) return 0; return handle; } else { assert (filename); /* First try appending ARCHIVE_EXT. */ errors += try_dlopen (&handle, filename, archive_ext, advise); /* If we found FILENAME, stop searching -- whether we were able to load the file as a module or not. If the file exists but loading failed, it is better to return an error message here than to report FILE_NOT_FOUND when the alternatives (foo.so etc) are not in the module search path. */ if (handle || ((errors > 0) && !file_not_found ())) return handle;#if defined(LT_MODULE_EXT) /* Try appending SHLIB_EXT. */ errors = try_dlopen (&handle, filename, shlib_ext, advise); /* As before, if the file was found but loading failed, return now with the current error message. */ if (handle || ((errors > 0) && !file_not_found ())) return handle;#endif } /* Still here? Then we really did fail to locate any of the file names we tried. */ LT__SETERROR (FILE_NOT_FOUND); return 0;}static intlt_argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry){ error_t error; /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz, pargz_len, NULL, entry) failed with EINVAL. */ if (before) error = argz_insert (pargz, pargz_len, before, entry); else error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry)); if (error) { switch (error) { case ENOMEM: LT__SETERROR (NO_MEMORY); break; default: LT__SETERROR (UNKNOWN); break; } return 1; } return 0;}static intlt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry){ char *before = 0; assert (pargz); assert (pargz_len); assert (entry && *entry); if (*pargz) while ((before = argz_next (*pargz, *pargz_len, before))) { int cmp = strcmp (entry, before); if (cmp < 0) break; if (cmp == 0) return 0; /* No duplicates! */ } return lt_argz_insert (pargz, pargz_len, before, entry);}static intlt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam, struct dirent *dp){ char *buf = 0; size_t buf_len = 0; char *end = 0; size_t end_offset = 0; size_t dir_len = 0; int errors = 0; assert (pargz); assert (pargz_len); assert (dp); dir_len = LT_STRLEN (dirnam); end = dp->d_name + D_NAMLEN(dp); /* Ignore version numbers. */ { char *p; for (p = end; p -1 > dp->d_name; --p) if (strchr (".0123456789", p[-1]) == 0) break; if (*p == '.') end = p; } /* Ignore filename extension. */ { char *p; for (p = end -1; p > dp->d_name; --p) if (*p == '.') { end = p; break; } } /* Prepend the directory name. */ end_offset = end - dp->d_name; buf_len = dir_len + 1+ end_offset; buf = MALLOC (char, 1+ buf_len); if (!buf) return ++errors; assert (buf); strcpy (buf, dirnam); strcat (buf, "/"); strncat (buf, dp->d_name, end_offset); buf[buf_len] = LT_EOS_CHAR; /* Try to insert (in order) into ARGZ/ARGZ_LEN. */ if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0) ++errors; FREE (buf); return errors;}static intlist_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len){ DIR *dirp = 0; int errors = 0; assert (dirnam && *dirnam); assert (pargz); assert (pargz_len); assert (dirnam[LT_STRLEN(dirnam) -1] != '/'); dirp = opendir (dirnam); if (dirp) { struct dirent *dp = 0; while ((dp = readdir (dirp))) if (dp->d_name[0] != '.') if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp)) { ++errors; break; } closedir (dirp); } else ++errors; return errors;}/* If there are any files in DIRNAME, call the function passed in DATA1 (with the name of each file and DATA2 as arguments). */static intforeachfile_callback (char *dirname, void *data1, void *data2){ file_worker_func *func = *(file_worker_func **) data1; int is_done = 0; char *argz = 0; size_t argz_len = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -