94 |
|
|
95 |
#include "raw-ltdl.h" |
#include "raw-ltdl.h" |
96 |
|
|
97 |
|
#if WITH_DMALLOC |
98 |
|
# include <dmalloc.h> |
99 |
|
#endif |
100 |
|
|
101 |
|
|
102 |
/* Saves on those hard to debug '\0' typos.... */ |
/* Saves on those hard to debug '\0' typos.... */ |
103 |
#define LT_EOS_CHAR '\0' |
#define LT_EOS_CHAR '\0' |
104 |
|
|
172 |
|
|
173 |
/* The following macros reduce the amount of typing needed to cast |
/* The following macros reduce the amount of typing needed to cast |
174 |
assigned memory. */ |
assigned memory. */ |
175 |
|
#if WITH_DMALLOC |
176 |
|
|
177 |
|
#define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) |
178 |
|
#define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) |
179 |
|
#define LT_DLFREE(p) \ |
180 |
|
LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END |
181 |
|
|
182 |
|
#define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) |
183 |
|
#define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) |
184 |
|
|
185 |
|
#else |
186 |
|
|
187 |
#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp))) |
#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp))) |
188 |
#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp))) |
#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp))) |
189 |
#define LT_DLFREE(p) \ |
#define LT_DLFREE(p) \ |
192 |
#define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp))) |
#define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp))) |
193 |
#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp))) |
#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp))) |
194 |
|
|
195 |
|
#endif |
196 |
|
|
197 |
#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ |
#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ |
198 |
if ((p) != (q)) { lt_dlfree (p); (p) = (q); (q) = 0; } \ |
if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \ |
199 |
} LT_STMT_END |
} LT_STMT_END |
200 |
|
|
201 |
|
|
207 |
|
|
208 |
static char *strdup LT_PARAMS((const char *str)); |
static char *strdup LT_PARAMS((const char *str)); |
209 |
|
|
210 |
char * |
static char * |
211 |
strdup(str) |
strdup(str) |
212 |
const char *str; |
const char *str; |
213 |
{ |
{ |
214 |
char *tmp = 0; |
char *tmp = NULL; |
215 |
|
|
216 |
if (str) |
if (str) |
217 |
{ |
{ |
233 |
|
|
234 |
static int strcmp LT_PARAMS((const char *str1, const char *str2)); |
static int strcmp LT_PARAMS((const char *str1, const char *str2)); |
235 |
|
|
236 |
int |
static int |
237 |
strcmp (str1, str2) |
strcmp (str1, str2) |
238 |
const char *str1; |
const char *str1; |
239 |
const char *str2; |
const char *str2; |
240 |
{ |
{ |
241 |
if (str1 == str2) |
if (str1 == str2) |
242 |
return 0; |
return 0; |
243 |
if (str1 == 0) |
if (str1 == NULL) |
244 |
return -1; |
return -1; |
245 |
if (str2 == 0) |
if (str2 == NULL) |
246 |
return 1; |
return 1; |
247 |
|
|
248 |
for (;*str1 && *str2; ++str1, ++str2) |
for (;*str1 && *str2; ++str1, ++str2) |
265 |
|
|
266 |
static const char *strchr LT_PARAMS((const char *str, int ch)); |
static const char *strchr LT_PARAMS((const char *str, int ch)); |
267 |
|
|
268 |
const char* |
static const char* |
269 |
strchr(str, ch) |
strchr(str, ch) |
270 |
const char *str; |
const char *str; |
271 |
int ch; |
int ch; |
291 |
|
|
292 |
static const char *strrchr LT_PARAMS((const char *str, int ch)); |
static const char *strrchr LT_PARAMS((const char *str, int ch)); |
293 |
|
|
294 |
const char* |
static const char* |
295 |
strrchr(str, ch) |
strrchr(str, ch) |
296 |
const char *str; |
const char *str; |
297 |
int ch; |
int ch; |
298 |
{ |
{ |
299 |
const char *p, *q = 0; |
const char *p, *q = NULL; |
300 |
|
|
301 |
for (p = str; *p != LT_EOS_CHAR; ++p) |
for (p = str; *p != LT_EOS_CHAR; ++p) |
302 |
{ |
{ |
325 |
|
|
326 |
static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); |
static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); |
327 |
|
|
328 |
lt_ptr |
static lt_ptr |
329 |
memcpy (dest, src, size) |
memcpy (dest, src, size) |
330 |
lt_ptr dest; |
lt_ptr dest; |
331 |
const lt_ptr src; |
const lt_ptr src; |
349 |
|
|
350 |
static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); |
static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); |
351 |
|
|
352 |
lt_ptr |
static lt_ptr |
353 |
memmove (dest, src, size) |
memmove (dest, src, size) |
354 |
lt_ptr dest; |
lt_ptr dest; |
355 |
const lt_ptr src; |
const lt_ptr src; |
390 |
of the source unless you know enough about, or wrote malloc. So |
of the source unless you know enough about, or wrote malloc. So |
391 |
this code is disabled... */ |
this code is disabled... */ |
392 |
|
|
393 |
lt_ptr |
static lt_ptr |
394 |
realloc (ptr, size) |
realloc (ptr, size) |
395 |
lt_ptr ptr; |
lt_ptr ptr; |
396 |
size_t size; |
size_t size; |
397 |
{ |
{ |
398 |
if (size <= 0) |
if (size == 0) |
399 |
{ |
{ |
400 |
/* For zero or less bytes, free the original memory */ |
/* For zero or less bytes, free the original memory */ |
401 |
if (ptr != 0) |
if (ptr != NULL) |
402 |
{ |
{ |
403 |
lt_dlfree (ptr); |
lt_dlfree (ptr); |
404 |
} |
} |
405 |
|
|
406 |
return (lt_ptr) 0; |
return (lt_ptr) 0; |
407 |
} |
} |
408 |
else if (ptr == 0) |
else if (ptr == NULL) |
409 |
{ |
{ |
410 |
/* Allow reallocation of a NULL pointer. */ |
/* Allow reallocation of a NULL pointer. */ |
411 |
return lt_dlmalloc (size); |
return lt_dlmalloc (size); |
436 |
static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len, |
static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len, |
437 |
const char *buf, size_t buf_len)); |
const char *buf, size_t buf_len)); |
438 |
|
|
439 |
error_t |
static error_t |
440 |
argz_append (pargz, pargz_len, buf, buf_len) |
argz_append (pargz, pargz_len, buf, buf_len) |
441 |
char **pargz; |
char **pargz; |
442 |
size_t *pargz_len; |
size_t *pargz_len; |
478 |
static error_t argz_create_sep LT_PARAMS((const char *str, int delim, |
static error_t argz_create_sep LT_PARAMS((const char *str, int delim, |
479 |
char **pargz, size_t *pargz_len)); |
char **pargz, size_t *pargz_len)); |
480 |
|
|
481 |
error_t |
static error_t |
482 |
argz_create_sep (str, delim, pargz, pargz_len) |
argz_create_sep (str, delim, pargz, pargz_len) |
483 |
const char *str; |
const char *str; |
484 |
int delim; |
int delim; |
486 |
size_t *pargz_len; |
size_t *pargz_len; |
487 |
{ |
{ |
488 |
size_t argz_len; |
size_t argz_len; |
489 |
char *argz = 0; |
char *argz = NULL; |
490 |
|
|
491 |
assert (str); |
assert (str); |
492 |
assert (pargz); |
assert (pargz); |
541 |
static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, |
static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, |
542 |
char *before, const char *entry)); |
char *before, const char *entry)); |
543 |
|
|
544 |
error_t |
static error_t |
545 |
argz_insert (pargz, pargz_len, before, entry) |
argz_insert (pargz, pargz_len, before, entry) |
546 |
char **pargz; |
char **pargz; |
547 |
size_t *pargz_len; |
size_t *pargz_len; |
552 |
assert (pargz_len); |
assert (pargz_len); |
553 |
assert (entry && *entry); |
assert (entry && *entry); |
554 |
|
|
|
/* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL, |
|
|
or BEFORE points into an address within the ARGZ vector. */ |
|
|
assert ((!*pargz && !*pargz_len && !before) |
|
|
|| ((*pargz <= before) && (before < (*pargz + *pargz_len)))); |
|
|
|
|
555 |
/* No BEFORE address indicates ENTRY should be inserted after the |
/* No BEFORE address indicates ENTRY should be inserted after the |
556 |
current last element. */ |
current last element. */ |
557 |
if (!before) |
if (!before) |
598 |
static char *argz_next LT_PARAMS((char *argz, size_t argz_len, |
static char *argz_next LT_PARAMS((char *argz, size_t argz_len, |
599 |
const char *entry)); |
const char *entry)); |
600 |
|
|
601 |
char * |
static char * |
602 |
argz_next (argz, argz_len, entry) |
argz_next (argz, argz_len, entry) |
603 |
char *argz; |
char *argz; |
604 |
size_t argz_len; |
size_t argz_len; |
643 |
static void argz_stringify LT_PARAMS((char *argz, size_t argz_len, |
static void argz_stringify LT_PARAMS((char *argz, size_t argz_len, |
644 |
int sep)); |
int sep)); |
645 |
|
|
646 |
void |
static void |
647 |
argz_stringify (argz, argz_len, sep) |
argz_stringify (argz, argz_len, sep) |
648 |
char *argz; |
char *argz; |
649 |
size_t argz_len; |
size_t argz_len; |
767 |
|
|
768 |
/* The mutex functions stored here are global, and are necessarily the |
/* The mutex functions stored here are global, and are necessarily the |
769 |
same for all threads that wish to share access to libltdl. */ |
same for all threads that wish to share access to libltdl. */ |
770 |
static lt_dlmutex_lock *lt_dlmutex_lock_func = 0; |
static lt_dlmutex_lock *lt_dlmutex_lock_func = NULL; |
771 |
static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0; |
static lt_dlmutex_unlock *lt_dlmutex_unlock_func = NULL; |
772 |
static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0; |
static lt_dlmutex_seterror *lt_dlmutex_seterror_func = NULL; |
773 |
static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0; |
static lt_dlmutex_geterror *lt_dlmutex_geterror_func = NULL; |
774 |
static const char *lt_dllast_error = 0; |
static const char *lt_dllast_error = NULL; |
775 |
|
|
776 |
|
|
777 |
/* Either set or reset the mutex functions. Either all the arguments must |
/* Either set or reset the mutex functions. Either all the arguments must |
819 |
|
|
820 |
/* --- ERROR HANDLING --- */ |
/* --- ERROR HANDLING --- */ |
821 |
|
|
822 |
static const char **user_error_strings = 0; |
static const char **user_error_strings = NULL; |
823 |
static int errorcount = LT_ERROR_MAX; |
static int errorcount = LT_ERROR_MAX; |
824 |
|
|
825 |
int |
int |
828 |
{ |
{ |
829 |
int errindex = 0; |
int errindex = 0; |
830 |
int result = -1; |
int result = -1; |
831 |
const char **temp = (const char **) 0; |
const char **temp = NULL; |
832 |
|
|
833 |
assert (diagnostic); |
assert (diagnostic); |
834 |
|
|
878 |
return errors; |
return errors; |
879 |
} |
} |
880 |
|
|
881 |
lt_ptr |
static lt_ptr |
882 |
lt_emalloc (size) |
lt_emalloc (size) |
883 |
size_t size; |
size_t size; |
884 |
{ |
{ |
888 |
return mem; |
return mem; |
889 |
} |
} |
890 |
|
|
891 |
lt_ptr |
static lt_ptr |
892 |
lt_erealloc (addr, size) |
lt_erealloc (addr, size) |
893 |
lt_ptr addr; |
lt_ptr addr; |
894 |
size_t size; |
size_t size; |
899 |
return mem; |
return mem; |
900 |
} |
} |
901 |
|
|
902 |
char * |
static char * |
903 |
lt_estrdup (str) |
lt_estrdup (str) |
904 |
const char *str; |
const char *str; |
905 |
{ |
{ |
906 |
char *dup = strdup (str); |
char *copy = strdup (str); |
907 |
if (LT_STRLEN (str) && !dup) |
if (LT_STRLEN (str) && !copy) |
908 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); |
909 |
return dup; |
return copy; |
910 |
} |
} |
911 |
|
|
912 |
|
|
1140 |
lt_module module; |
lt_module module; |
1141 |
const char *symbol; |
const char *symbol; |
1142 |
{ |
{ |
1143 |
lt_ptr address = 0; |
lt_ptr address = NULL; |
1144 |
|
|
1145 |
/* sys_shl_open should never return a NULL module handle */ |
/* sys_shl_open should never return a NULL module handle */ |
1146 |
if (module == (lt_module) 0) |
if (module == (lt_module) 0) |
1184 |
const char *filename; |
const char *filename; |
1185 |
{ |
{ |
1186 |
lt_dlhandle cur; |
lt_dlhandle cur; |
1187 |
lt_module module = 0; |
lt_module module = NULL; |
1188 |
const char *errormsg = 0; |
const char *errormsg = NULL; |
1189 |
char *searchname = 0; |
char *searchname = NULL; |
1190 |
char *ext; |
char *ext; |
1191 |
char self_name_buf[MAX_PATH]; |
char self_name_buf[MAX_PATH]; |
1192 |
|
|
1193 |
if (!filename) |
if (!filename) |
1194 |
{ |
{ |
1195 |
/* Get the name of main module */ |
/* Get the name of main module */ |
1196 |
*self_name_buf = 0; |
*self_name_buf = '\0'; |
1197 |
GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf)); |
GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf)); |
1198 |
filename = ext = self_name_buf; |
filename = ext = self_name_buf; |
1199 |
} |
} |
1243 |
{ |
{ |
1244 |
if (!cur->module) |
if (!cur->module) |
1245 |
{ |
{ |
1246 |
cur = 0; |
cur = NULL; |
1247 |
break; |
break; |
1248 |
} |
} |
1249 |
|
|
1259 |
if (cur || !module) |
if (cur || !module) |
1260 |
{ |
{ |
1261 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); |
1262 |
module = 0; |
module = NULL; |
1263 |
} |
} |
1264 |
|
|
1265 |
return module; |
return module; |
1365 |
lt_module module; |
lt_module module; |
1366 |
const char *symbol; |
const char *symbol; |
1367 |
{ |
{ |
1368 |
lt_ptr address = 0; |
lt_ptr address = NULL; |
1369 |
image_id image = (image_id) module; |
image_id image = (image_id) module; |
1370 |
|
|
1371 |
if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) |
if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) |
1372 |
{ |
{ |
1373 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); |
1374 |
address = 0; |
address = NULL; |
1375 |
} |
} |
1376 |
|
|
1377 |
return address; |
return address; |
1408 |
{ |
{ |
1409 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); |
1410 |
LT_DLFREE (module); |
LT_DLFREE (module); |
1411 |
module = 0; |
module = NULL; |
1412 |
} |
} |
1413 |
|
|
1414 |
return module; |
return module; |
1470 |
const lt_dlsymlist *syms; |
const lt_dlsymlist *syms; |
1471 |
} lt_dlsymlists_t; |
} lt_dlsymlists_t; |
1472 |
|
|
1473 |
static const lt_dlsymlist *default_preloaded_symbols = 0; |
static const lt_dlsymlist *default_preloaded_symbols = NULL; |
1474 |
static lt_dlsymlists_t *preloaded_symbols = 0; |
static lt_dlsymlists_t *preloaded_symbols = NULL; |
1475 |
|
|
1476 |
static int |
static int |
1477 |
presym_init (loader_data) |
presym_init (loader_data) |
1481 |
|
|
1482 |
LT_DLMUTEX_LOCK (); |
LT_DLMUTEX_LOCK (); |
1483 |
|
|
1484 |
preloaded_symbols = 0; |
preloaded_symbols = NULL; |
1485 |
if (default_preloaded_symbols) |
if (default_preloaded_symbols) |
1486 |
{ |
{ |
1487 |
errors = lt_dlpreload (default_preloaded_symbols); |
errors = lt_dlpreload (default_preloaded_symbols); |
1507 |
lists = lists->next; |
lists = lists->next; |
1508 |
LT_DLFREE (tmp); |
LT_DLFREE (tmp); |
1509 |
} |
} |
1510 |
preloaded_symbols = 0; |
preloaded_symbols = NULL; |
1511 |
|
|
1512 |
LT_DLMUTEX_UNLOCK (); |
LT_DLMUTEX_UNLOCK (); |
1513 |
|
|
1616 |
lt_module module; |
lt_module module; |
1617 |
{ |
{ |
1618 |
/* Just to silence gcc -Wall */ |
/* Just to silence gcc -Wall */ |
1619 |
module = 0; |
module = NULL; |
1620 |
return 0; |
return 0; |
1621 |
} |
} |
1622 |
|
|
1707 |
static int lt_argz_insertinorder LT_PARAMS((char **pargz, |
static int lt_argz_insertinorder LT_PARAMS((char **pargz, |
1708 |
size_t *pargz_len, |
size_t *pargz_len, |
1709 |
const char *entry)); |
const char *entry)); |
1710 |
|
static int lt_argz_insertdir LT_PARAMS((char **pargz, |
1711 |
|
size_t *pargz_len, |
1712 |
|
const char *dirnam, |
1713 |
|
struct dirent *dp)); |
1714 |
static int lt_dlpath_insertdir LT_PARAMS((char **ppath, |
static int lt_dlpath_insertdir LT_PARAMS((char **ppath, |
1715 |
char *before, |
char *before, |
1716 |
const char *dir)); |
const char *dir)); |
1717 |
|
static int list_files_by_dir LT_PARAMS((const char *dirnam, |
1718 |
|
char **pargz, |
1719 |
|
size_t *pargz_len)); |
1720 |
|
static int file_not_found LT_PARAMS((void)); |
1721 |
|
|
1722 |
static char *user_search_path= 0; |
static char *user_search_path= NULL; |
1723 |
static lt_dlloader *loaders = 0; |
static lt_dlloader *loaders = NULL; |
1724 |
static lt_dlhandle handles = 0; |
static lt_dlhandle handles = NULL; |
1725 |
static int initialized = 0; |
static int initialized = 0; |
1726 |
|
|
1727 |
/* Initialize libltdl. */ |
/* Initialize libltdl. */ |
1735 |
/* Initialize only at first call. */ |
/* Initialize only at first call. */ |
1736 |
if (++initialized == 1) |
if (++initialized == 1) |
1737 |
{ |
{ |
1738 |
handles = 0; |
handles = NULL; |
1739 |
user_search_path = 0; /* empty search path */ |
user_search_path = NULL; /* empty search path */ |
1740 |
|
|
1741 |
#if HAVE_LIBDL && !defined(__CYGWIN__) |
#if HAVE_LIBDL && !defined(__CYGWIN__) |
1742 |
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen"); |
errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen"); |
1871 |
|
|
1872 |
LT_DLMEM_REASSIGN (loader, next); |
LT_DLMEM_REASSIGN (loader, next); |
1873 |
} |
} |
1874 |
loaders = 0; |
loaders = NULL; |
1875 |
} |
} |
1876 |
|
|
1877 |
done: |
done: |
1932 |
} |
} |
1933 |
else |
else |
1934 |
{ |
{ |
1935 |
cur->info.filename = 0; |
cur->info.filename = NULL; |
1936 |
} |
} |
1937 |
|
|
1938 |
while (loader) |
while (loader) |
1941 |
|
|
1942 |
cur->module = loader->module_open (data, filename); |
cur->module = loader->module_open (data, filename); |
1943 |
|
|
1944 |
if (cur->module != 0) |
if (cur->module != NULL) |
1945 |
{ |
{ |
1946 |
break; |
break; |
1947 |
} |
} |
1972 |
const char *dlname; |
const char *dlname; |
1973 |
{ |
{ |
1974 |
int error = 0; |
int error = 0; |
1975 |
char *filename = 0; |
char *filename = NULL; |
1976 |
size_t filename_len = 0; |
size_t filename_len = 0; |
1977 |
size_t dirname_len = LT_STRLEN (dirname); |
size_t dirname_len = LT_STRLEN (dirname); |
1978 |
|
|
1982 |
#ifdef LT_DIRSEP_CHAR |
#ifdef LT_DIRSEP_CHAR |
1983 |
/* Only canonicalized names (i.e. with DIRSEP chars already converted) |
/* Only canonicalized names (i.e. with DIRSEP chars already converted) |
1984 |
should make it into this function: */ |
should make it into this function: */ |
1985 |
assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); |
assert (strchr (dirname, LT_DIRSEP_CHAR) == NULL); |
1986 |
#endif |
#endif |
1987 |
|
|
1988 |
if (dirname_len > 0) |
if (dirname_len > 0) |
2067 |
const char *path; |
const char *path; |
2068 |
char **pcanonical; |
char **pcanonical; |
2069 |
{ |
{ |
2070 |
char *canonical = 0; |
char *canonical = NULL; |
2071 |
|
|
2072 |
assert (path && *path); |
assert (path && *path); |
2073 |
assert (pcanonical); |
assert (pcanonical); |
2169 |
{ |
{ |
2170 |
int result = 0; |
int result = 0; |
2171 |
int filenamesize = 0; |
int filenamesize = 0; |
2172 |
int lenbase = LT_STRLEN (base_name); |
size_t lenbase = LT_STRLEN (base_name); |
2173 |
size_t argz_len = 0; |
size_t argz_len = 0; |
2174 |
char * argz = 0; |
char *argz = NULL; |
2175 |
char * filename = 0; |
char *filename = NULL; |
2176 |
char * canonical = 0; |
char *canonical = NULL; |
2177 |
|
|
2178 |
LT_DLMUTEX_LOCK (); |
LT_DLMUTEX_LOCK (); |
2179 |
|
|
2190 |
goto cleanup; |
goto cleanup; |
2191 |
|
|
2192 |
{ |
{ |
2193 |
char *dir_name = 0; |
char *dir_name = NULL; |
2194 |
while ((dir_name = argz_next (argz, argz_len, dir_name))) |
while ((dir_name = argz_next (argz, argz_len, dir_name))) |
2195 |
{ |
{ |
2196 |
int lendir = LT_STRLEN (dir_name); |
size_t lendir = LT_STRLEN (dir_name); |
2197 |
|
|
2198 |
if (lendir +1 +lenbase >= filenamesize) |
if (lendir +1 +lenbase >= filenamesize) |
2199 |
{ |
{ |
2204 |
goto cleanup; |
goto cleanup; |
2205 |
} |
} |
2206 |
|
|
2207 |
strncpy (filename, dir_name, lendir); |
assert (filenamesize > lendir); |
2208 |
|
strcpy (filename, dir_name); |
2209 |
|
|
2210 |
if (base_name && *base_name) |
if (base_name && *base_name) |
2211 |
{ |
{ |
2212 |
if (filename[lendir -1] != '/') |
if (filename[lendir -1] != '/') |
2257 |
|
|
2258 |
LT_DLFREE (*pdir); |
LT_DLFREE (*pdir); |
2259 |
*pdir = lt_estrdup (filename); |
*pdir = lt_estrdup (filename); |
2260 |
is_done = (*pdir == 0) ? -1 : 1; |
is_done = (*pdir == NULL) ? -1 : 1; |
2261 |
} |
} |
2262 |
|
|
2263 |
return is_done; |
return is_done; |
2269 |
const char *base_name; |
const char *base_name; |
2270 |
char **pdir; |
char **pdir; |
2271 |
{ |
{ |
2272 |
FILE *file = 0; |
FILE *file = NULL; |
2273 |
|
|
2274 |
foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); |
foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); |
2275 |
|
|
2282 |
lt_ptr data; |
lt_ptr data; |
2283 |
lt_ptr ignored; |
lt_ptr ignored; |
2284 |
{ |
{ |
2285 |
lt_dlhandle *handle = (lt_dlhandle *) data; |
lt_dlhandle *handle = (lt_dlhandle *) data; |
2286 |
int found = !access (filename, F_OK); |
int notfound = access (filename, R_OK); |
2287 |
|
|
2288 |
/* Bail out if file cannot be read... */ |
/* Bail out if file cannot be read... */ |
2289 |
if (!found) |
if (notfound) |
2290 |
return 0; |
return 0; |
2291 |
|
|
2292 |
/* Try to dlopen the file, but do not continue searching in any |
/* Try to dlopen the file, but do not continue searching in any |
2293 |
case. */ |
case. */ |
2294 |
if (tryall_dlopen (handle, filename) != 0) |
if (tryall_dlopen (handle, filename) != 0) |
2295 |
*handle = 0; |
*handle = NULL; |
2296 |
|
|
2297 |
return 1; |
return 1; |
2298 |
} |
} |
2321 |
char *deplibs; |
char *deplibs; |
2322 |
{ |
{ |
2323 |
#if LTDL_DLOPEN_DEPLIBS |
#if LTDL_DLOPEN_DEPLIBS |
2324 |
char *p, *save_search_path = 0; |
char *p, *save_search_path = NULL; |
2325 |
int depcount = 0; |
int depcount = 0; |
2326 |
int i; |
int i; |
2327 |
char **names = 0; |
char **names = NULL; |
2328 |
#endif |
#endif |
2329 |
int errors = 0; |
int errors = 0; |
2330 |
|
|
2360 |
if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) |
if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) |
2361 |
{ |
{ |
2362 |
char save = *end; |
char save = *end; |
2363 |
*end = 0; /* set a temporary string terminator */ |
*end = '\0'; /* set a temporary string terminator */ |
2364 |
if (lt_dladdsearchdir(p+2)) |
if (lt_dladdsearchdir(p+2)) |
2365 |
{ |
{ |
2366 |
goto cleanup; |
goto cleanup; |
2417 |
{ |
{ |
2418 |
char *name; |
char *name; |
2419 |
char save = *end; |
char save = *end; |
2420 |
*end = 0; /* set a temporary string terminator */ |
*end = '\0'; /* set a temporary string terminator */ |
2421 |
if (strncmp(p, "-l", 2) == 0) |
if (strncmp(p, "-l", 2) == 0) |
2422 |
{ |
{ |
2423 |
size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); |
size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); |
2506 |
/* remove the leading and trailing "'" from str |
/* remove the leading and trailing "'" from str |
2507 |
and store the result in dest */ |
and store the result in dest */ |
2508 |
const char *end = strrchr (str, '\''); |
const char *end = strrchr (str, '\''); |
2509 |
int len = LT_STRLEN (str); |
size_t len = LT_STRLEN (str); |
2510 |
char *tmp; |
char *tmp; |
2511 |
|
|
2512 |
LT_DLFREE (*dest); |
LT_DLFREE (*dest); |
2523 |
} |
} |
2524 |
else |
else |
2525 |
{ |
{ |
2526 |
*dest = 0; |
*dest = NULL; |
2527 |
} |
} |
2528 |
|
|
2529 |
return 0; |
return 0; |
2544 |
return 0; |
return 0; |
2545 |
} |
} |
2546 |
|
|
2547 |
int |
static int |
2548 |
try_dlopen (phandle, filename) |
try_dlopen (phandle, filename) |
2549 |
lt_dlhandle *phandle; |
lt_dlhandle *phandle; |
2550 |
const char *filename; |
const char *filename; |
2551 |
{ |
{ |
2552 |
const char * ext = 0; |
const char * ext = NULL; |
2553 |
const char * saved_error = 0; |
const char * saved_error = NULL; |
2554 |
char * canonical = 0; |
char * canonical = NULL; |
2555 |
char * base_name = 0; |
char * base_name = NULL; |
2556 |
char * dir = 0; |
char * dir = NULL; |
2557 |
char * name = 0; |
char * name = NULL; |
2558 |
int errors = 0; |
int errors = 0; |
2559 |
lt_dlhandle newhandle; |
lt_dlhandle newhandle; |
2560 |
|
|
2561 |
assert (phandle); |
assert (phandle); |
2562 |
assert (*phandle == 0); |
assert (*phandle == NULL); |
2563 |
|
|
2564 |
LT_DLMUTEX_GETERROR (saved_error); |
LT_DLMUTEX_GETERROR (saved_error); |
2565 |
|
|
2567 |
if (!filename) |
if (!filename) |
2568 |
{ |
{ |
2569 |
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
2570 |
if (*phandle == 0) |
if (*phandle == NULL) |
2571 |
return 1; |
return 1; |
2572 |
|
|
2573 |
memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); |
memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); |
2624 |
if (ext && strcmp (ext, archive_ext) == 0) |
if (ext && strcmp (ext, archive_ext) == 0) |
2625 |
{ |
{ |
2626 |
/* this seems to be a libtool module */ |
/* this seems to be a libtool module */ |
2627 |
FILE * file = 0; |
FILE * file = NULL; |
2628 |
char * dlname = 0; |
char * dlname = NULL; |
2629 |
char * old_name = 0; |
char * old_name = NULL; |
2630 |
char * libdir = 0; |
char * libdir = NULL; |
2631 |
char * deplibs = 0; |
char * deplibs = NULL; |
2632 |
char * line = 0; |
char * line = NULL; |
2633 |
size_t line_len; |
size_t line_len; |
|
int i; |
|
2634 |
|
|
2635 |
/* if we can't find the installed flag, it is probably an |
/* if we can't find the installed flag, it is probably an |
2636 |
installed libtool archive, produced with an old version |
installed libtool archive, produced with an old version |
2646 |
} |
} |
2647 |
|
|
2648 |
/* canonicalize the module name */ |
/* canonicalize the module name */ |
2649 |
for (i = 0; i < ext - base_name; ++i) |
{ |
2650 |
{ |
size_t i; |
2651 |
if (isalnum ((int)(base_name[i]))) |
for (i = 0; i < ext - base_name; ++i) |
2652 |
{ |
{ |
2653 |
name[i] = base_name[i]; |
if (isalnum ((int)(base_name[i]))) |
2654 |
} |
{ |
2655 |
else |
name[i] = base_name[i]; |
2656 |
{ |
} |
2657 |
name[i] = '_'; |
else |
2658 |
} |
{ |
2659 |
} |
name[i] = '_'; |
2660 |
name[ext - base_name] = LT_EOS_CHAR; |
} |
2661 |
|
} |
2662 |
|
name[ext - base_name] = LT_EOS_CHAR; |
2663 |
|
} |
2664 |
|
|
2665 |
/* 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 |
2666 |
component, try to find it first in user_search_path and then other |
component, try to find it first in user_search_path and then other |
2667 |
prescribed paths. Otherwise (or in any case if the module was not |
prescribed paths. Otherwise (or in any case if the module was not |
2668 |
yet found) try opening just the module name as passed. */ |
yet found) try opening just the module name as passed. */ |
2669 |
if (!dir) |
if (!dir) |
2670 |
{ |
{ |
2671 |
const char *search_path; |
const char *search_path; |
2724 |
/* read the .la file */ |
/* read the .la file */ |
2725 |
while (!feof (file)) |
while (!feof (file)) |
2726 |
{ |
{ |
2727 |
if (!fgets (line, line_len, file)) |
if (!fgets (line, (int) line_len, file)) |
2728 |
{ |
{ |
2729 |
break; |
break; |
2730 |
} |
} |
2734 |
while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file))) |
while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file))) |
2735 |
{ |
{ |
2736 |
line = LT_DLREALLOC (char, line, line_len *2); |
line = LT_DLREALLOC (char, line, line_len *2); |
2737 |
if (!fgets (&line[line_len -1], line_len +1, file)) |
if (!fgets (&line[line_len -1], (int) line_len +1, file)) |
2738 |
{ |
{ |
2739 |
break; |
break; |
2740 |
} |
} |
2792 |
errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); |
errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); |
2793 |
if (!errors |
if (!errors |
2794 |
&& dlname |
&& dlname |
2795 |
&& (last_libname = strrchr (dlname, ' ')) != 0) |
&& (last_libname = strrchr (dlname, ' ')) != NULL) |
2796 |
{ |
{ |
2797 |
last_libname = lt_estrdup (last_libname + 1); |
last_libname = lt_estrdup (last_libname + 1); |
2798 |
if (!last_libname) |
if (!last_libname) |
2813 |
|
|
2814 |
/* allocate the handle */ |
/* allocate the handle */ |
2815 |
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
2816 |
if (*phandle == 0) |
if (*phandle == NULL) |
2817 |
++errors; |
++errors; |
2818 |
|
|
2819 |
if (errors) |
if (errors) |
2857 |
{ |
{ |
2858 |
/* not a libtool module */ |
/* not a libtool module */ |
2859 |
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
*phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); |
2860 |
if (*phandle == 0) |
if (*phandle == NULL) |
2861 |
{ |
{ |
2862 |
++errors; |
++errors; |
2863 |
goto cleanup; |
goto cleanup; |
2882 |
#endif |
#endif |
2883 |
))) |
))) |
2884 |
{ |
{ |
2885 |
if (tryall_dlopen (&newhandle, filename) != 0) |
if (tryall_dlopen (&newhandle, filename) != 0) |
2886 |
newhandle = 0; |
{ |
2887 |
|
newhandle = NULL; |
2888 |
|
} |
2889 |
} |
} |
2890 |
|
|
2891 |
if (!newhandle) |
if (!newhandle) |
2924 |
lt_dlopen (filename) |
lt_dlopen (filename) |
2925 |
const char *filename; |
const char *filename; |
2926 |
{ |
{ |
2927 |
lt_dlhandle handle = 0; |
lt_dlhandle handle = NULL; |
2928 |
|
|
2929 |
/* Just incase we missed a code path in try_dlopen() that reports |
/* Just incase we missed a code path in try_dlopen() that reports |
2930 |
an error, but forgets to reset handle... */ |
an error, but forgets to reset handle... */ |
2939 |
static int |
static int |
2940 |
file_not_found () |
file_not_found () |
2941 |
{ |
{ |
2942 |
const char *error = 0; |
const char *error = NULL; |
2943 |
|
|
2944 |
LT_DLMUTEX_GETERROR (error); |
LT_DLMUTEX_GETERROR (error); |
2945 |
if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) |
if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) |
2956 |
lt_dlopenext (filename) |
lt_dlopenext (filename) |
2957 |
const char *filename; |
const char *filename; |
2958 |
{ |
{ |
2959 |
lt_dlhandle handle = 0; |
lt_dlhandle handle = NULL; |
2960 |
char * tmp = 0; |
char * tmp = NULL; |
2961 |
char * ext = 0; |
char * ext = NULL; |
2962 |
int len; |
size_t len; |
2963 |
int errors = 0; |
int errors = 0; |
2964 |
|
|
2965 |
if (!filename) |
if (!filename) |
3039 |
} |
} |
3040 |
|
|
3041 |
|
|
3042 |
int |
static int |
3043 |
lt_argz_insert (pargz, pargz_len, before, entry) |
lt_argz_insert (pargz, pargz_len, before, entry) |
3044 |
char **pargz; |
char **pargz; |
3045 |
size_t *pargz_len; |
size_t *pargz_len; |
3065 |
return 0; |
return 0; |
3066 |
} |
} |
3067 |
|
|
3068 |
int |
static int |
3069 |
lt_argz_insertinorder (pargz, pargz_len, entry) |
lt_argz_insertinorder (pargz, pargz_len, entry) |
3070 |
char **pargz; |
char **pargz; |
3071 |
size_t *pargz_len; |
size_t *pargz_len; |
3072 |
const char *entry; |
const char *entry; |
3073 |
{ |
{ |
3074 |
char *before = 0; |
char *before = NULL; |
3075 |
|
|
3076 |
assert (pargz); |
assert (pargz); |
3077 |
assert (pargz_len); |
assert (pargz_len); |
3096 |
const char *dirnam; |
const char *dirnam; |
3097 |
struct dirent *dp; |
struct dirent *dp; |
3098 |
{ |
{ |
3099 |
char *buf = 0; |
char *buf = NULL; |
3100 |
size_t buf_len = 0; |
size_t buf_len = 0; |
3101 |
char *end = 0; |
char *end = NULL; |
3102 |
size_t end_offset = 0; |
size_t end_offset = 0; |
3103 |
size_t dir_len = 0; |
size_t dir_len = 0; |
3104 |
int errors = 0; |
int errors = 0; |
3161 |
char **pargz; |
char **pargz; |
3162 |
size_t *pargz_len; |
size_t *pargz_len; |
3163 |
{ |
{ |
3164 |
DIR *dirp = 0; |
DIR *dirp = NULL; |
3165 |
int errors = 0; |
int errors = 0; |
3166 |
|
|
3167 |
assert (dirnam && *dirnam); |
assert (dirnam && *dirnam); |
3172 |
dirp = opendir (dirnam); |
dirp = opendir (dirnam); |
3173 |
if (dirp) |
if (dirp) |
3174 |
{ |
{ |
3175 |
struct dirent *dp = 0; |
struct dirent *dp = NULL; |
3176 |
|
|
3177 |
while ((dp = readdir (dirp))) |
while ((dp = readdir (dirp))) |
3178 |
if (dp->d_name[0] != '.') |
if (dp->d_name[0] != '.') |
3203 |
= (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1; |
= (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1; |
3204 |
|
|
3205 |
int is_done = 0; |
int is_done = 0; |
3206 |
char *argz = 0; |
char *argz = NULL; |
3207 |
size_t argz_len = 0; |
size_t argz_len = 0; |
3208 |
|
|
3209 |
if (list_files_by_dir (dirname, &argz, &argz_len) != 0) |
if (list_files_by_dir (dirname, &argz, &argz_len) != 0) |
3212 |
goto cleanup; |
goto cleanup; |
3213 |
|
|
3214 |
{ |
{ |
3215 |
char *filename = 0; |
char *filename = NULL; |
3216 |
while ((filename = argz_next (argz, argz_len, filename))) |
while ((filename = argz_next (argz, argz_len, filename))) |
3217 |
if ((is_done = (*func) (filename, data2))) |
if ((is_done = (*func) (filename, data2))) |
3218 |
break; |
break; |
3322 |
errors += handle->loader->module_close (data, handle->module); |
errors += handle->loader->module_close (data, handle->module); |
3323 |
errors += unload_deplibs(handle); |
errors += unload_deplibs(handle); |
3324 |
|
|
3325 |
|
/* It is up to the callers to free the data itself. */ |
3326 |
|
LT_DLFREE (handle->caller_data); |
3327 |
|
|
3328 |
LT_DLFREE (handle->info.filename); |
LT_DLFREE (handle->info.filename); |
3329 |
LT_DLFREE (handle->info.name); |
LT_DLFREE (handle->info.name); |
3330 |
LT_DLFREE (handle); |
LT_DLFREE (handle); |
3349 |
lt_dlhandle handle; |
lt_dlhandle handle; |
3350 |
const char *symbol; |
const char *symbol; |
3351 |
{ |
{ |
3352 |
int lensym; |
size_t lensym; |
3353 |
char lsym[LT_SYMBOL_LENGTH]; |
char lsym[LT_SYMBOL_LENGTH]; |
3354 |
char *sym; |
char *sym; |
3355 |
lt_ptr address; |
lt_ptr address; |
3449 |
return error ? error : LT_DLSTRERROR (UNKNOWN); |
return error ? error : LT_DLSTRERROR (UNKNOWN); |
3450 |
} |
} |
3451 |
|
|
3452 |
int |
static int |
3453 |
lt_dlpath_insertdir (ppath, before, dir) |
lt_dlpath_insertdir (ppath, before, dir) |
3454 |
char **ppath; |
char **ppath; |
3455 |
char *before; |
char *before; |
3456 |
const char *dir; |
const char *dir; |
3457 |
{ |
{ |
3458 |
int errors = 0; |
int errors = 0; |
3459 |
char *canonical = 0; |
char *canonical = NULL; |
3460 |
char *argz = 0; |
char *argz = NULL; |
3461 |
size_t argz_len = 0; |
size_t argz_len = 0; |
3462 |
|
|
3463 |
assert (ppath); |
assert (ppath); |
3472 |
assert (canonical && *canonical); |
assert (canonical && *canonical); |
3473 |
|
|
3474 |
/* If *PPATH is empty, set it to DIR. */ |
/* If *PPATH is empty, set it to DIR. */ |
3475 |
if (*ppath == 0) |
if (*ppath == NULL) |
3476 |
{ |
{ |
3477 |
assert (!before); /* BEFORE cannot be set without PPATH. */ |
assert (!before); /* BEFORE cannot be set without PPATH. */ |
3478 |
assert (dir); /* Without DIR, don't call this function! */ |
assert (dir); /* Without DIR, don't call this function! */ |
3479 |
|
|
3480 |
*ppath = lt_estrdup (dir); |
*ppath = lt_estrdup (dir); |
3481 |
if (*ppath == 0) |
if (*ppath == NULL) |
3482 |
++errors; |
++errors; |
3483 |
|
|
3484 |
return errors; |
return errors; |
3712 |
lt_ptr data; |
lt_ptr data; |
3713 |
{ |
{ |
3714 |
int n_elements = 0; |
int n_elements = 0; |
3715 |
lt_ptr stale = (lt_ptr) 0; |
lt_ptr stale = NULL; |
3716 |
int i; |
int i; |
3717 |
|
|
3718 |
/* This needs to be locked so that the caller data can be updated |
/* This needs to be locked so that the caller data can be updated |
3741 |
|
|
3742 |
if (!temp) |
if (!temp) |
3743 |
{ |
{ |
3744 |
stale = 0; |
stale = NULL; |
3745 |
goto done; |
goto done; |
3746 |
} |
} |
3747 |
|
|
3801 |
const char *loader_name; |
const char *loader_name; |
3802 |
{ |
{ |
3803 |
int errors = 0; |
int errors = 0; |
3804 |
lt_dlloader *node = 0, *ptr = 0; |
lt_dlloader *node = NULL, *ptr = NULL; |
3805 |
|
|
3806 |
if ((dlloader == 0) /* diagnose null parameters */ |
if ((dlloader == NULL) /* diagnose null parameters */ |
3807 |
|| (dlloader->module_open == 0) |
|| (dlloader->module_open == NULL) |
3808 |
|| (dlloader->module_close == 0) |
|| (dlloader->module_close == NULL) |
3809 |
|| (dlloader->find_sym == 0)) |
|| (dlloader->find_sym == NULL)) |
3810 |
{ |
{ |
3811 |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); |
LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); |
3812 |
return 1; |
return 1; |
3817 |
if (!node) |
if (!node) |
3818 |
return 1; |
return 1; |
3819 |
|
|
3820 |
node->next = 0; |
node->next = NULL; |
3821 |
node->loader_name = loader_name; |
node->loader_name = loader_name; |
3822 |
node->sym_prefix = dlloader->sym_prefix; |
node->sym_prefix = dlloader->sym_prefix; |
3823 |
node->dlloader_exit = dlloader->dlloader_exit; |
node->dlloader_exit = dlloader->dlloader_exit; |
3953 |
lt_dlloader_name (place) |
lt_dlloader_name (place) |
3954 |
lt_dlloader *place; |
lt_dlloader *place; |
3955 |
{ |
{ |
3956 |
const char *name = 0; |
const char *name = NULL; |
3957 |
|
|
3958 |
if (place) |
if (place) |
3959 |
{ |
{ |
3973 |
lt_dlloader_data (place) |
lt_dlloader_data (place) |
3974 |
lt_dlloader *place; |
lt_dlloader *place; |
3975 |
{ |
{ |
3976 |
lt_user_data *data = 0; |
lt_user_data *data = NULL; |
3977 |
|
|
3978 |
if (place) |
if (place) |
3979 |
{ |
{ |
3993 |
lt_dlloader_find (loader_name) |
lt_dlloader_find (loader_name) |
3994 |
const char *loader_name; |
const char *loader_name; |
3995 |
{ |
{ |
3996 |
lt_dlloader *place = 0; |
lt_dlloader *place = NULL; |
3997 |
|
|
3998 |
LT_DLMUTEX_LOCK (); |
LT_DLMUTEX_LOCK (); |
3999 |
for (place = loaders; place; place = place->next) |
for (place = loaders; place; place = place->next) |