29 |
# include <config.h> |
# include <config.h> |
30 |
#endif |
#endif |
31 |
|
|
32 |
|
#if HAVE_UNISTD_H |
33 |
|
# include <unistd.h> |
34 |
|
#endif |
35 |
|
|
36 |
#if HAVE_STDIO_H |
#if HAVE_STDIO_H |
37 |
# include <stdio.h> |
# include <stdio.h> |
38 |
#endif |
#endif |
117 |
/* --- MANIFEST CONSTANTS --- */ |
/* --- MANIFEST CONSTANTS --- */ |
118 |
|
|
119 |
|
|
120 |
|
/* Standard libltdl search path environment variable name */ |
121 |
|
#undef LTDL_SEARCHPATH_VAR |
122 |
|
#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" |
123 |
|
|
124 |
|
/* Standard libtool archive file extension. */ |
125 |
|
#undef LTDL_ARCHIVE_EXT |
126 |
|
#define LTDL_ARCHIVE_EXT ".la" |
127 |
|
|
128 |
/* max. filename length */ |
/* max. filename length */ |
129 |
#ifndef LT_FILENAME_MAX |
#ifndef LT_FILENAME_MAX |
130 |
# define LT_FILENAME_MAX 1024 |
# define LT_FILENAME_MAX 1024 |
418 |
assert (pargz); |
assert (pargz); |
419 |
assert (pargz_len); |
assert (pargz_len); |
420 |
assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); |
assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); |
421 |
|
|
422 |
/* If nothing needs to be appended, no more work is required. */ |
/* If nothing needs to be appended, no more work is required. */ |
423 |
if (buf_len == 0) |
if (buf_len == 0) |
424 |
return 0; |
return 0; |
428 |
argz = LT_DLREALLOC (char, *pargz, argz_len); |
argz = LT_DLREALLOC (char, *pargz, argz_len); |
429 |
if (!argz) |
if (!argz) |
430 |
return ENOMEM; |
return ENOMEM; |
431 |
|
|
432 |
/* Copy characters from BUF after terminating '\0' in ARGZ. */ |
/* Copy characters from BUF after terminating '\0' in ARGZ. */ |
433 |
memcpy (argz + *pargz_len, buf, buf_len); |
memcpy (argz + *pargz_len, buf, buf_len); |
434 |
|
|
494 |
/* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ |
/* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ |
495 |
if (!argz_len) |
if (!argz_len) |
496 |
LT_DLFREE (argz); |
LT_DLFREE (argz); |
497 |
|
|
498 |
/* Assign new values. */ |
/* Assign new values. */ |
499 |
*pargz = argz; |
*pargz = argz; |
500 |
*pargz_len = argz_len; |
*pargz_len = argz_len; |
560 |
*pargz = argz; |
*pargz = argz; |
561 |
*pargz_len = argz_len; |
*pargz_len = argz_len; |
562 |
} |
} |
563 |
|
|
564 |
return 0; |
return 0; |
565 |
} |
} |
566 |
#endif /* !HAVE_ARGZ_INSERT */ |
#endif /* !HAVE_ARGZ_INSERT */ |
567 |
|
|
705 |
#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] |
#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] |
706 |
|
|
707 |
static const char objdir[] = LTDL_OBJDIR; |
static const char objdir[] = LTDL_OBJDIR; |
708 |
|
static const char archive_ext[] = LTDL_ARCHIVE_EXT; |
709 |
#ifdef LTDL_SHLIB_EXT |
#ifdef LTDL_SHLIB_EXT |
710 |
static const char shlib_ext[] = LTDL_SHLIB_EXT; |
static const char shlib_ext[] = LTDL_SHLIB_EXT; |
711 |
#endif |
#endif |
719 |
/* --- MUTEX LOCKING --- */ |
/* --- MUTEX LOCKING --- */ |
720 |
|
|
721 |
|
|
722 |
/* Macros to make it easier to run the lock functions only if they have |
/* Macros to make it easier to run the lock functions only if they have |
723 |
been registered. The reason for the complicated lock macro is to |
been registered. The reason for the complicated lock macro is to |
724 |
ensure that the stored error message from the last error is not |
ensure that the stored error message from the last error is not |
725 |
accidentally erased if the current function doesn't generate an |
accidentally erased if the current function doesn't generate an |
726 |
error of its own. */ |
error of its own. */ |
727 |
#define LT_DLMUTEX_LOCK() LT_STMT_START { \ |
#define LT_DLMUTEX_LOCK() LT_STMT_START { \ |
765 |
/* Lock using the old lock() callback, if any. */ |
/* Lock using the old lock() callback, if any. */ |
766 |
LT_DLMUTEX_LOCK (); |
LT_DLMUTEX_LOCK (); |
767 |
|
|
768 |
if ((lock && unlock && seterror && geterror) |
if ((lock && unlock && seterror && geterror) |
769 |
|| !(lock || unlock || seterror || geterror)) |
|| !(lock || unlock || seterror || geterror)) |
770 |
{ |
{ |
771 |
lt_dlmutex_lock_func = lock; |
lt_dlmutex_lock_func = lock; |
1065 |
{ |
{ |
1066 |
static shl_t self = (shl_t) 0; |
static shl_t self = (shl_t) 0; |
1067 |
lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); |
lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); |
1068 |
|
|
1069 |
/* Since searching for a symbol against a NULL module handle will also |
/* Since searching for a symbol against a NULL module handle will also |
1070 |
look in everything else that was already loaded and exported with |
look in everything else that was already loaded and exported with |
1071 |
the -E compiler flag, we always cache a handle saved before any |
the -E compiler flag, we always cache a handle saved before any |
1072 |
modules are loaded. */ |
modules are loaded. */ |
1073 |
if (!self) |
if (!self) |
1075 |
lt_ptr address; |
lt_ptr address; |
1076 |
shl_findsym (&self, "main", TYPE_UNDEFINED, &address); |
shl_findsym (&self, "main", TYPE_UNDEFINED, &address); |
1077 |
} |
} |
1078 |
|
|
1079 |
if (!filename) |
if (!filename) |
1080 |
{ |
{ |
1081 |
module = self; |
module = self; |
1089 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); |
1090 |
} |
} |
1091 |
} |
} |
1092 |
|
|
1093 |
return module; |
return module; |
1094 |
} |
} |
1095 |
|
|
1129 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); |
1130 |
} |
} |
1131 |
} |
} |
1132 |
|
|
1133 |
return address; |
return address; |
1134 |
} |
} |
1135 |
|
|
1529 |
{ |
{ |
1530 |
++errors; |
++errors; |
1531 |
} |
} |
1532 |
|
|
1533 |
done: |
done: |
1534 |
LT_DLMUTEX_UNLOCK (); |
LT_DLMUTEX_UNLOCK (); |
1535 |
return errors; |
return errors; |
1670 |
char *deplibs)); |
char *deplibs)); |
1671 |
static int trim LT_PARAMS((char **dest, |
static int trim LT_PARAMS((char **dest, |
1672 |
const char *str)); |
const char *str)); |
1673 |
|
static int try_dlopen LT_PARAMS((lt_dlhandle *handle, |
1674 |
|
const char *filename)); |
1675 |
static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, |
static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, |
1676 |
const char *filename)); |
const char *filename)); |
1677 |
static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); |
static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); |
1752 |
else |
else |
1753 |
{ |
{ |
1754 |
presym_free_symlists(); |
presym_free_symlists(); |
1755 |
|
|
1756 |
LT_DLMUTEX_LOCK (); |
LT_DLMUTEX_LOCK (); |
1757 |
if (default_preloaded_symbols) |
if (default_preloaded_symbols) |
1758 |
{ |
{ |
1924 |
|
|
1925 |
cur->loader = loader; |
cur->loader = loader; |
1926 |
LT_DLMUTEX_SETERROR (saved_error); |
LT_DLMUTEX_SETERROR (saved_error); |
1927 |
|
|
1928 |
done: |
done: |
1929 |
LT_DLMUTEX_UNLOCK (); |
LT_DLMUTEX_UNLOCK (); |
1930 |
|
|
1951 |
should make it into this function: */ |
should make it into this function: */ |
1952 |
assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); |
assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); |
1953 |
#endif |
#endif |
1954 |
|
|
1955 |
if (dirname[dirname_len -1] == '/') |
if (dirname[dirname_len -1] == '/') |
1956 |
--dirname_len; |
--dirname_len; |
1957 |
filename_len = dirname_len + 1 + LT_STRLEN (dlname); |
filename_len = dirname_len + 1 + LT_STRLEN (dlname); |
1975 |
{ |
{ |
1976 |
++error; |
++error; |
1977 |
} |
} |
1978 |
|
|
1979 |
LT_DLFREE (filename); |
LT_DLFREE (filename); |
1980 |
return error; |
return error; |
1981 |
} |
} |
2031 |
char **pcanonical; |
char **pcanonical; |
2032 |
{ |
{ |
2033 |
char *canonical = 0; |
char *canonical = 0; |
2034 |
|
|
2035 |
assert (path && *path); |
assert (path && *path); |
2036 |
assert (pcanonical); |
assert (pcanonical); |
2037 |
|
|
2095 |
size_t *pargz_len; |
size_t *pargz_len; |
2096 |
{ |
{ |
2097 |
error_t error; |
error_t error; |
2098 |
|
|
2099 |
assert (path); |
assert (path); |
2100 |
assert (pargz); |
assert (pargz); |
2101 |
assert (pargz_len); |
assert (pargz_len); |
2174 |
filename[lendir++] = '/'; |
filename[lendir++] = '/'; |
2175 |
strcpy (filename +lendir, base_name); |
strcpy (filename +lendir, base_name); |
2176 |
} |
} |
2177 |
|
|
2178 |
if ((result = (*func) (filename, data1, data2))) |
if ((result = (*func) (filename, data1, data2))) |
2179 |
{ |
{ |
2180 |
break; |
break; |
2188 |
LT_DLFREE (filename); |
LT_DLFREE (filename); |
2189 |
|
|
2190 |
LT_DLMUTEX_UNLOCK (); |
LT_DLMUTEX_UNLOCK (); |
2191 |
|
|
2192 |
return result; |
return result; |
2193 |
} |
} |
2194 |
|
|
2244 |
lt_ptr ignored; |
lt_ptr ignored; |
2245 |
{ |
{ |
2246 |
lt_dlhandle *handle = (lt_dlhandle *) data; |
lt_dlhandle *handle = (lt_dlhandle *) data; |
2247 |
int is_done = 0; |
int found = access (filename, R_OK); |
2248 |
|
|
2249 |
if (tryall_dlopen (handle, filename) == 0) |
/* Bail out if file cannot be read... */ |
2250 |
{ |
if (!found) |
2251 |
is_done = 1; |
return 0; |
|
} |
|
2252 |
|
|
2253 |
return is_done; |
/* Try to dlopen the file, but do not continue searching in any |
2254 |
|
case. */ |
2255 |
|
if (tryall_dlopen (handle, filename) != 0) |
2256 |
|
*handle = 0; |
2257 |
|
|
2258 |
|
return 1; |
2259 |
} |
} |
2260 |
|
|
2261 |
|
/* If HANDLE was found return it, otherwise return 0. If HANDLE was |
2262 |
|
found but could not be opened, *HANDLE will be set to 0. */ |
2263 |
static lt_dlhandle * |
static lt_dlhandle * |
2264 |
find_handle (search_path, base_name, handle) |
find_handle (search_path, base_name, handle) |
2265 |
const char *search_path; |
const char *search_path; |
2266 |
const char *base_name; |
const char *base_name; |
2267 |
lt_dlhandle *handle; |
lt_dlhandle *handle; |
2268 |
{ |
{ |
2269 |
|
if (!search_path) |
2270 |
|
return 0; |
2271 |
|
|
2272 |
if (!foreach_dirinpath (search_path, base_name, find_handle_callback, |
if (!foreach_dirinpath (search_path, base_name, find_handle_callback, |
2273 |
handle, 0)) |
handle, 0)) |
2274 |
return 0; |
return 0; |
2505 |
return 0; |
return 0; |
2506 |
} |
} |
2507 |
|
|
2508 |
lt_dlhandle |
int |
2509 |
lt_dlopen (filename) |
try_dlopen (phandle, filename) |
2510 |
|
lt_dlhandle *phandle; |
2511 |
const char *filename; |
const char *filename; |
2512 |
{ |
{ |
2513 |
lt_dlhandle handle = 0, newhandle; |
const char * ext = 0; |
2514 |
const char *ext; |
const char * saved_error = 0; |
2515 |
const char *saved_error; |
char * canonical = 0; |
2516 |
char *canonical = 0, *base_name = 0, *dir = 0, *name = 0; |
char * base_name = 0; |
2517 |
|
char * dir = 0; |
2518 |
|
char * name = 0; |
2519 |
|
int errors = 0; |
2520 |
|
lt_dlhandle newhandle; |
2521 |
|
|
2522 |
/* Doing this immediately allows internal functions to safely |
assert (phandle); |
2523 |
assume only canonicalized paths are passed. */ |
assert (*phandle == 0); |
|
if (filename && (canonicalize_path (filename, &canonical) != 0)) |
|
|
return 0; |
|
2524 |
|
|
2525 |
LT_DLMUTEX_GETERROR (saved_error); |
LT_DLMUTEX_GETERROR (saved_error); |
2526 |
|
|
2527 |
/* dlopen self? */ |
/* dlopen self? */ |
2528 |
if (!filename) |
if (!filename) |
2529 |
{ |
{ |
2530 |
handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
2531 |
if (!handle) |
if (*phandle == 0) |
2532 |
return 0; |
return 1; |
2533 |
|
|
2534 |
memset (handle, 0, 1*sizeof(struct lt_dlhandle_struct)); |
memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); |
2535 |
newhandle = handle; |
newhandle = *phandle; |
2536 |
|
|
2537 |
/* lt_dlclose()ing yourself is very bad! Disallow it. */ |
/* lt_dlclose()ing yourself is very bad! Disallow it. */ |
2538 |
LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); |
LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG); |
2539 |
|
|
2540 |
if (tryall_dlopen (&newhandle, 0) != 0) |
if (tryall_dlopen (&newhandle, 0) != 0) |
2541 |
{ |
{ |
2542 |
LT_DLFREE (handle); |
LT_DLFREE (*phandle); |
2543 |
return 0; |
return 1; |
2544 |
} |
} |
2545 |
|
|
2546 |
goto register_handle; |
goto register_handle; |
2547 |
} |
} |
2548 |
|
|
2549 |
assert (filename && *filename); |
assert (filename && *filename); |
2550 |
|
|
2551 |
|
/* Doing this immediately allows internal functions to safely |
2552 |
|
assume only canonicalized paths are passed. */ |
2553 |
|
if (canonicalize_path (filename, &canonical) != 0) |
2554 |
|
{ |
2555 |
|
++errors; |
2556 |
|
goto cleanup; |
2557 |
|
} |
2558 |
|
|
2559 |
/* If the canonical module name is a path (relative or absolute) |
/* If the canonical module name is a path (relative or absolute) |
2560 |
then split it into a directory part and a name part. */ |
then split it into a directory part and a name part. */ |
2561 |
base_name = strrchr (canonical, '/'); |
base_name = strrchr (canonical, '/'); |
2565 |
|
|
2566 |
dir = LT_EMALLOC (char, 1+ dirlen); |
dir = LT_EMALLOC (char, 1+ dirlen); |
2567 |
if (!dir) |
if (!dir) |
2568 |
goto cleanup; |
{ |
2569 |
|
++errors; |
2570 |
|
goto cleanup; |
2571 |
|
} |
2572 |
|
|
2573 |
strncpy (dir, canonical, dirlen); |
strncpy (dir, canonical, dirlen); |
2574 |
dir[dirlen] = LT_EOS_CHAR; |
dir[dirlen] = LT_EOS_CHAR; |
2577 |
} |
} |
2578 |
else |
else |
2579 |
LT_DLMEM_REASSIGN (base_name, canonical); |
LT_DLMEM_REASSIGN (base_name, canonical); |
2580 |
|
|
2581 |
assert (base_name && *base_name); |
assert (base_name && *base_name); |
2582 |
|
|
2583 |
/* Check whether we are opening a libtool module (.la extension). */ |
/* Check whether we are opening a libtool module (.la extension). */ |
2584 |
ext = strrchr(base_name, '.'); |
ext = strrchr (base_name, '.'); |
2585 |
if (ext && strcmp(ext, ".la") == 0) |
if (ext && strcmp (ext, archive_ext) == 0) |
2586 |
{ |
{ |
2587 |
/* this seems to be a libtool module */ |
/* this seems to be a libtool module */ |
2588 |
FILE *file = 0; |
FILE * file = 0; |
2589 |
int i; |
char * dlname = 0; |
2590 |
char *dlname = 0, *old_name = 0; |
char * old_name = 0; |
2591 |
char *libdir = 0, *deplibs = 0; |
char * libdir = 0; |
2592 |
char *line; |
char * deplibs = 0; |
2593 |
|
char * line = 0; |
2594 |
size_t line_len; |
size_t line_len; |
2595 |
int error = 0; |
int i; |
2596 |
|
|
2597 |
/* if we can't find the installed flag, it is probably an |
/* if we can't find the installed flag, it is probably an |
2598 |
installed libtool archive, produced with an old version |
installed libtool archive, produced with an old version |
2602 |
/* extract the module name from the file name */ |
/* extract the module name from the file name */ |
2603 |
name = LT_EMALLOC (char, ext - base_name + 1); |
name = LT_EMALLOC (char, ext - base_name + 1); |
2604 |
if (!name) |
if (!name) |
2605 |
goto cleanup; |
{ |
2606 |
|
++errors; |
2607 |
|
goto cleanup; |
2608 |
|
} |
2609 |
|
|
2610 |
/* canonicalize the module name */ |
/* canonicalize the module name */ |
2611 |
for (i = 0; i < ext - base_name; ++i) |
for (i = 0; i < ext - base_name; ++i) |
2619 |
name[i] = '_'; |
name[i] = '_'; |
2620 |
} |
} |
2621 |
} |
} |
|
|
|
2622 |
name[ext - base_name] = LT_EOS_CHAR; |
name[ext - base_name] = LT_EOS_CHAR; |
2623 |
|
|
2624 |
/* Now try to open the .la file. If there is no directory name |
/* Now try to open the .la file. If there is no directory name |
2627 |
yet found) try opening just the module name as passed. */ |
yet found) try opening just the module name as passed. */ |
2628 |
if (!dir) |
if (!dir) |
2629 |
{ |
{ |
2630 |
file = find_file (user_search_path, base_name, &dir); |
const char *search_path; |
2631 |
|
|
2632 |
|
LT_DLMUTEX_LOCK (); |
2633 |
|
search_path = user_search_path; |
2634 |
|
if (search_path) |
2635 |
|
file = find_file (user_search_path, base_name, &dir); |
2636 |
|
LT_DLMUTEX_UNLOCK (); |
2637 |
|
|
2638 |
if (!file) |
if (!file) |
2639 |
{ |
{ |
2640 |
file = find_file (getenv("LTDL_LIBRARY_PATH"), base_name, &dir); |
search_path = getenv (LTDL_SEARCHPATH_VAR); |
2641 |
|
if (search_path) |
2642 |
|
file = find_file (search_path, base_name, &dir); |
2643 |
} |
} |
2644 |
|
|
2645 |
#ifdef LTDL_SHLIBPATH_VAR |
#ifdef LTDL_SHLIBPATH_VAR |
2646 |
if (!file) |
if (!file) |
2647 |
{ |
{ |
2648 |
file = find_file (getenv(LTDL_SHLIBPATH_VAR), base_name, &dir); |
search_path = getenv (LTDL_SHLIBPATH_VAR); |
2649 |
|
if (search_path) |
2650 |
|
file = find_file (search_path, base_name, &dir); |
2651 |
} |
} |
2652 |
#endif |
#endif |
2653 |
#ifdef LTDL_SYSSEARCHPATH |
#ifdef LTDL_SYSSEARCHPATH |
2654 |
if (!file) |
if (!file && sys_search_path) |
2655 |
{ |
{ |
2656 |
file = find_file (sys_search_path, base_name, &dir); |
file = find_file (sys_search_path, base_name, &dir); |
2657 |
} |
} |
2661 |
{ |
{ |
2662 |
file = fopen (filename, LT_READTEXT_MODE); |
file = fopen (filename, LT_READTEXT_MODE); |
2663 |
} |
} |
2664 |
|
|
2665 |
|
/* If we didn't find the file by now, it really isn't there. Set |
2666 |
|
the status flag, and bail out. */ |
2667 |
if (!file) |
if (!file) |
2668 |
{ |
{ |
2669 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); |
2670 |
|
++errors; |
2671 |
|
goto cleanup; |
2672 |
} |
} |
2673 |
|
|
|
if (!file) |
|
|
goto cleanup; |
|
|
|
|
2674 |
line_len = LT_FILENAME_MAX; |
line_len = LT_FILENAME_MAX; |
2675 |
line = LT_EMALLOC (char, line_len); |
line = LT_EMALLOC (char, line_len); |
2676 |
if (!line) |
if (!line) |
2677 |
{ |
{ |
2678 |
fclose (file); |
fclose (file); |
2679 |
|
++errors; |
2680 |
goto cleanup; |
goto cleanup; |
2681 |
} |
} |
2682 |
|
|
2683 |
/* read the .la file */ |
/* read the .la file */ |
2684 |
while (!feof(file)) |
while (!feof (file)) |
2685 |
{ |
{ |
2686 |
if (!fgets (line, line_len, file)) |
if (!fgets (line, line_len, file)) |
2687 |
{ |
{ |
2688 |
break; |
break; |
2689 |
} |
} |
2690 |
|
|
2691 |
|
/* Handle the case where we occasionally need to read a line |
|
/* Handle the case where we occasionally need to read a line |
|
2692 |
that is longer than the initial buffer size. */ |
that is longer than the initial buffer size. */ |
2693 |
while (line[LT_STRLEN(line) -1] != '\n') |
while (line[LT_STRLEN(line) -1] != '\n') |
2694 |
{ |
{ |
2709 |
#define STR_DLNAME "dlname=" |
#define STR_DLNAME "dlname=" |
2710 |
if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) |
if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) |
2711 |
{ |
{ |
2712 |
error = trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); |
errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); |
2713 |
} |
} |
2714 |
|
|
2715 |
#undef STR_OLD_LIBRARY |
#undef STR_OLD_LIBRARY |
2717 |
else if (strncmp (line, STR_OLD_LIBRARY, |
else if (strncmp (line, STR_OLD_LIBRARY, |
2718 |
sizeof (STR_OLD_LIBRARY) - 1) == 0) |
sizeof (STR_OLD_LIBRARY) - 1) == 0) |
2719 |
{ |
{ |
2720 |
error = trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); |
errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); |
2721 |
} |
} |
2722 |
#undef STR_LIBDIR |
#undef STR_LIBDIR |
2723 |
#define STR_LIBDIR "libdir=" |
#define STR_LIBDIR "libdir=" |
2724 |
else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) |
else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) |
2725 |
{ |
{ |
2726 |
error = trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); |
errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); |
2727 |
} |
} |
2728 |
|
|
2729 |
#undef STR_DL_DEPLIBS |
#undef STR_DL_DEPLIBS |
2731 |
else if (strncmp (line, STR_DL_DEPLIBS, |
else if (strncmp (line, STR_DL_DEPLIBS, |
2732 |
sizeof (STR_DL_DEPLIBS) - 1) == 0) |
sizeof (STR_DL_DEPLIBS) - 1) == 0) |
2733 |
{ |
{ |
2734 |
error = trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); |
errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); |
2735 |
} |
} |
2736 |
else if (strcmp (line, "installed=yes\n") == 0) |
else if (strcmp (line, "installed=yes\n") == 0) |
2737 |
{ |
{ |
2748 |
sizeof (STR_LIBRARY_NAMES) - 1) == 0) |
sizeof (STR_LIBRARY_NAMES) - 1) == 0) |
2749 |
{ |
{ |
2750 |
char *last_libname; |
char *last_libname; |
2751 |
error = trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); |
errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); |
2752 |
if (! error && dlname && |
if (!errors |
2753 |
(last_libname = strrchr (dlname, ' ')) != 0) |
&& dlname |
2754 |
|
&& (last_libname = strrchr (dlname, ' ')) != 0) |
2755 |
{ |
{ |
2756 |
last_libname = lt_estrdup (last_libname + 1); |
last_libname = lt_estrdup (last_libname + 1); |
2757 |
if (!last_libname) |
if (!last_libname) |
2758 |
{ |
{ |
2759 |
++error; |
++errors; |
2760 |
goto cleanup; |
goto cleanup; |
2761 |
} |
} |
2762 |
LT_DLMEM_REASSIGN (dlname, last_libname); |
LT_DLMEM_REASSIGN (dlname, last_libname); |
2763 |
} |
} |
2764 |
} |
} |
2765 |
|
|
2766 |
if (error) |
if (errors) |
2767 |
break; |
break; |
2768 |
} |
} |
2769 |
|
|
2771 |
LT_DLFREE (line); |
LT_DLFREE (line); |
2772 |
|
|
2773 |
/* allocate the handle */ |
/* allocate the handle */ |
2774 |
handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
2775 |
if (!handle) |
if (*phandle == 0) |
2776 |
++error; |
++errors; |
2777 |
|
|
2778 |
if (error) |
if (errors) |
2779 |
{ |
{ |
2780 |
free_vars (dlname, old_name, libdir, deplibs); |
free_vars (dlname, old_name, libdir, deplibs); |
2781 |
LT_DLFREE (handle); |
LT_DLFREE (*phandle); |
2782 |
goto cleanup; |
goto cleanup; |
2783 |
} |
} |
2784 |
|
|
2785 |
assert (handle); |
assert (*phandle); |
2786 |
|
|
2787 |
memset (handle, 0, sizeof(struct lt_dlhandle_struct)); |
memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); |
2788 |
if (load_deplibs (handle, deplibs) == 0) |
if (load_deplibs (*phandle, deplibs) == 0) |
2789 |
{ |
{ |
2790 |
newhandle = handle; |
newhandle = *phandle; |
2791 |
/* find_module may replace newhandle */ |
/* find_module may replace newhandle */ |
2792 |
if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) |
if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) |
2793 |
{ |
{ |
2794 |
unload_deplibs (handle); |
unload_deplibs (*phandle); |
2795 |
error = 1; |
++errors; |
2796 |
} |
} |
2797 |
} |
} |
2798 |
else |
else |
2799 |
{ |
{ |
2800 |
error = 1; |
++errors; |
2801 |
} |
} |
2802 |
|
|
2803 |
free_vars (dlname, old_name, libdir, deplibs); |
free_vars (dlname, old_name, libdir, deplibs); |
2804 |
if (error) |
if (errors) |
2805 |
{ |
{ |
2806 |
LT_DLFREE (handle); |
LT_DLFREE (*phandle); |
2807 |
goto cleanup; |
goto cleanup; |
2808 |
} |
} |
2809 |
|
|
2810 |
if (handle != newhandle) |
if (*phandle != newhandle) |
2811 |
{ |
{ |
2812 |
unload_deplibs (handle); |
unload_deplibs (*phandle); |
2813 |
} |
} |
2814 |
} |
} |
2815 |
else |
else |
2816 |
{ |
{ |
2817 |
/* not a libtool module */ |
/* not a libtool module */ |
2818 |
handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
2819 |
if (!handle) |
if (*phandle == 0) |
2820 |
goto cleanup; |
{ |
2821 |
|
++errors; |
2822 |
|
goto cleanup; |
2823 |
|
} |
2824 |
|
|
2825 |
memset (handle, 0, sizeof(struct lt_dlhandle_struct)); |
memset (*phandle, 0, sizeof (struct lt_dlhandle_struct)); |
2826 |
newhandle = handle; |
newhandle = *phandle; |
2827 |
|
|
2828 |
/* If the module has no directory name component, try to find it |
/* If the module has no directory name component, try to find it |
2829 |
first in user_search_path and then other prescribed paths. |
first in user_search_path and then other prescribed paths. |
2830 |
Otherwise (or in any case if the module was not yet found) try |
Otherwise (or in any case if the module was not yet found) try |
2831 |
opening just the module name as passed. */ |
opening just the module name as passed. */ |
2832 |
if ((dir || (!find_handle (user_search_path, base_name, &newhandle) |
if ((dir || (!find_handle (user_search_path, base_name, &newhandle) |
2833 |
&& !find_handle (getenv ("LTDL_LIBRARY_PATH"), base_name, |
&& !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, |
2834 |
&newhandle) |
&newhandle) |
2835 |
#ifdef LTDL_SHLIBPATH_VAR |
#ifdef LTDL_SHLIBPATH_VAR |
2836 |
&& !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, |
&& !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, |
2839 |
#ifdef LTDL_SYSSEARCHPATH |
#ifdef LTDL_SYSSEARCHPATH |
2840 |
&& !find_handle (sys_search_path, base_name, &newhandle) |
&& !find_handle (sys_search_path, base_name, &newhandle) |
2841 |
#endif |
#endif |
2842 |
)) && tryall_dlopen (&newhandle, filename)) |
))) |
2843 |
|
{ |
2844 |
|
tryall_dlopen (&newhandle, filename); |
2845 |
|
} |
2846 |
|
|
2847 |
|
if (!newhandle) |
2848 |
{ |
{ |
2849 |
LT_DLFREE (handle); |
LT_DLFREE (*phandle); |
2850 |
|
++errors; |
2851 |
goto cleanup; |
goto cleanup; |
2852 |
} |
} |
2853 |
} |
} |
2854 |
|
|
2855 |
register_handle: |
register_handle: |
2856 |
LT_DLMEM_REASSIGN (handle, newhandle); |
LT_DLMEM_REASSIGN (*phandle, newhandle); |
2857 |
|
|
2858 |
if (handle->info.ref_count == 0) |
if ((*phandle)->info.ref_count == 0) |
2859 |
{ |
{ |
2860 |
handle->info.ref_count = 1; |
(*phandle)->info.ref_count = 1; |
2861 |
LT_DLMEM_REASSIGN (handle->info.name, name); |
LT_DLMEM_REASSIGN ((*phandle)->info.name, name); |
2862 |
|
|
2863 |
LT_DLMUTEX_LOCK (); |
LT_DLMUTEX_LOCK (); |
2864 |
handle->next = handles; |
(*phandle)->next = handles; |
2865 |
handles = handle; |
handles = *phandle; |
2866 |
LT_DLMUTEX_UNLOCK (); |
LT_DLMUTEX_UNLOCK (); |
2867 |
} |
} |
2868 |
|
|
2873 |
LT_DLFREE (name); |
LT_DLFREE (name); |
2874 |
LT_DLFREE (canonical); |
LT_DLFREE (canonical); |
2875 |
|
|
2876 |
|
return errors; |
2877 |
|
} |
2878 |
|
|
2879 |
|
lt_dlhandle |
2880 |
|
lt_dlopen (filename) |
2881 |
|
const char *filename; |
2882 |
|
{ |
2883 |
|
lt_dlhandle handle = 0; |
2884 |
|
|
2885 |
|
/* Just incase we missed a code path in try_dlopen() that reports |
2886 |
|
an error, but forgets to reset handle... */ |
2887 |
|
if (try_dlopen (&handle, filename) != 0) |
2888 |
|
return 0; |
2889 |
|
|
2890 |
return handle; |
return handle; |
2891 |
} |
} |
2892 |
|
|
2893 |
|
/* If the last error messge store was `FILE_NOT_FOUND', then return |
2894 |
|
non-zero. */ |
2895 |
|
int |
2896 |
|
file_not_found () |
2897 |
|
{ |
2898 |
|
const char *error = 0; |
2899 |
|
|
2900 |
|
LT_DLMUTEX_GETERROR (error); |
2901 |
|
if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) |
2902 |
|
return 1; |
2903 |
|
|
2904 |
|
return 0; |
2905 |
|
} |
2906 |
|
|
2907 |
|
/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to |
2908 |
|
open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, |
2909 |
|
and if a file is still not found try again with SHLIB_EXT appended |
2910 |
|
instead. */ |
2911 |
lt_dlhandle |
lt_dlhandle |
2912 |
lt_dlopenext (filename) |
lt_dlopenext (filename) |
2913 |
const char *filename; |
const char *filename; |
2914 |
{ |
{ |
2915 |
lt_dlhandle handle; |
lt_dlhandle handle = 0; |
2916 |
char *tmp; |
char * tmp = 0; |
2917 |
int len; |
char * ext = 0; |
2918 |
const char *saved_error; |
int len; |
2919 |
|
int errors = 0; |
2920 |
LT_DLMUTEX_GETERROR (saved_error); |
int file_found = 1; /* until proven otherwise */ |
2921 |
|
|
2922 |
if (!filename) |
if (!filename) |
2923 |
{ |
{ |
2924 |
return lt_dlopen (filename); |
return lt_dlopen (filename); |
2925 |
} |
} |
2926 |
|
|
2927 |
|
assert (filename); |
2928 |
|
|
2929 |
len = LT_STRLEN (filename); |
len = LT_STRLEN (filename); |
2930 |
if (!len) |
ext = strrchr (filename, '.'); |
2931 |
|
|
2932 |
|
/* If FILENAME already bears a suitable extension, there is no need |
2933 |
|
to try appending additional extensions. */ |
2934 |
|
if (ext && ((strcmp (ext, archive_ext) == 0) |
2935 |
|
#ifdef LTDL_SHLIB_EXT |
2936 |
|
|| (strcmp (ext, shlib_ext) == 0) |
2937 |
|
#endif |
2938 |
|
)) |
2939 |
{ |
{ |
2940 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); |
return lt_dlopen (filename); |
|
return 0; |
|
2941 |
} |
} |
2942 |
|
|
2943 |
/* try "filename.la" */ |
/* First try appending ARCHIVE_EXT. */ |
2944 |
tmp = LT_EMALLOC (char, len+4); |
tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1); |
2945 |
if (!tmp) |
if (!tmp) |
2946 |
return 0; |
return 0; |
2947 |
|
|
2948 |
strcpy (tmp, filename); |
strcpy (tmp, filename); |
2949 |
strcat (tmp, ".la"); |
strcat (tmp, archive_ext); |
2950 |
handle = lt_dlopen (tmp); |
errors = try_dlopen (&handle, tmp); |
2951 |
if (handle) |
|
2952 |
|
/* If we found FILENAME, stop searching -- whether we were able to |
2953 |
|
load the file as a module or not. If the file exists but loading |
2954 |
|
failed, it is better to return an error message here than to |
2955 |
|
report FILE_NOT_FOUND when the alternatives (foo.so etc) are not |
2956 |
|
in the module search path. */ |
2957 |
|
if (handle || ((errors > 0) && file_not_found ())) |
2958 |
{ |
{ |
|
LT_DLMUTEX_SETERROR (saved_error); |
|
2959 |
LT_DLFREE (tmp); |
LT_DLFREE (tmp); |
2960 |
return handle; |
return handle; |
2961 |
} |
} |
2962 |
|
|
2963 |
#ifdef LTDL_SHLIB_EXT |
#ifdef LTDL_SHLIB_EXT |
2964 |
/* try "filename.EXT" */ |
/* Try appending SHLIB_EXT. */ |
2965 |
if (LT_STRLEN(shlib_ext) > 3) |
if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext)) |
2966 |
{ |
{ |
2967 |
LT_DLFREE (tmp); |
LT_DLFREE (tmp); |
2968 |
tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); |
tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); |
2977 |
} |
} |
2978 |
|
|
2979 |
strcat(tmp, shlib_ext); |
strcat(tmp, shlib_ext); |
2980 |
handle = lt_dlopen (tmp); |
errors = try_dlopen (&handle, tmp); |
2981 |
if (handle) |
|
2982 |
|
/* As before, if the file was found but loading failed, return now |
2983 |
|
with the current error message. */ |
2984 |
|
if (handle || ((errors > 0) && file_not_found ())) |
2985 |
{ |
{ |
|
LT_DLMUTEX_SETERROR (saved_error); |
|
2986 |
LT_DLFREE (tmp); |
LT_DLFREE (tmp); |
2987 |
return handle; |
return handle; |
2988 |
} |
} |
2989 |
#endif |
#endif |
2990 |
|
|
2991 |
/* try the normal file name */ |
/* Still here? Then we really did fail to locate any of the file |
2992 |
handle = lt_dlopen (filename); |
names we tried. */ |
|
if (handle) |
|
|
{ |
|
|
return handle; |
|
|
} |
|
|
|
|
2993 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); |
2994 |
LT_DLFREE (tmp); |
LT_DLFREE (tmp); |
2995 |
return 0; |
return 0; |
3095 |
buf = LT_EMALLOC (char, 1+ buf_len); |
buf = LT_EMALLOC (char, 1+ buf_len); |
3096 |
if (!buf) |
if (!buf) |
3097 |
return ++errors; |
return ++errors; |
3098 |
|
|
3099 |
assert (buf); |
assert (buf); |
3100 |
|
|
3101 |
strcpy (buf, dirnam); |
strcpy (buf, dirnam); |
3109 |
|
|
3110 |
LT_DLFREE (buf); |
LT_DLFREE (buf); |
3111 |
|
|
3112 |
return errors; |
return errors; |
3113 |
} |
} |
3114 |
|
|
3115 |
int |
int |
3120 |
{ |
{ |
3121 |
DIR *dirp = 0; |
DIR *dirp = 0; |
3122 |
int errors = 0; |
int errors = 0; |
3123 |
|
|
3124 |
assert (dirnam && *dirnam); |
assert (dirnam && *dirnam); |
3125 |
assert (pargz); |
assert (pargz); |
3126 |
assert (pargz_len); |
assert (pargz_len); |
3464 |
++errors; |
++errors; |
3465 |
goto cleanup; |
goto cleanup; |
3466 |
} |
} |
3467 |
|
|
3468 |
argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); |
argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); |
3469 |
LT_DLMEM_REASSIGN (*ppath, argz); |
LT_DLMEM_REASSIGN (*ppath, argz); |
3470 |
|
|
3474 |
|
|
3475 |
return errors; |
return errors; |
3476 |
} |
} |
3477 |
|
|
3478 |
int |
int |
3479 |
lt_dladdsearchdir (search_dir) |
lt_dladdsearchdir (search_dir) |
3480 |
const char *search_dir; |
const char *search_dir; |
3502 |
if (before) |
if (before) |
3503 |
{ |
{ |
3504 |
LT_DLMUTEX_LOCK (); |
LT_DLMUTEX_LOCK (); |
3505 |
if ((before < user_search_path) |
if ((before < user_search_path) |
3506 |
|| (before >= user_search_path + LT_STRLEN (user_search_path))) |
|| (before >= user_search_path + LT_STRLEN (user_search_path))) |
3507 |
{ |
{ |
3508 |
LT_DLMUTEX_UNLOCK (); |
LT_DLMUTEX_UNLOCK (); |
3515 |
if (search_dir && *search_dir) |
if (search_dir && *search_dir) |
3516 |
{ |
{ |
3517 |
LT_DLMUTEX_LOCK (); |
LT_DLMUTEX_LOCK (); |
3518 |
if (lt_dlpath_insertdir (&user_search_path, |
if (lt_dlpath_insertdir (&user_search_path, |
3519 |
(char *) before, search_dir) != 0) |
(char *) before, search_dir) != 0) |
3520 |
{ |
{ |
3521 |
++errors; |
++errors; |