ltdl.c 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471
  1. /* ltdl.c -- system independent dlopen wrapper
  2. Copyright (C) 1998-2000, 2004-2008, 2011-2015 Free Software
  3. Foundation, Inc.
  4. Written by Thomas Tanner, 1998
  5. NOTE: The canonical source of this file is maintained with the
  6. GNU Libtool package. Report bugs to bug-libtool@gnu.org.
  7. GNU Libltdl is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2 of the License, or (at your option) any later version.
  11. As a special exception to the GNU Lesser General Public License,
  12. if you distribute this file as part of a program or library that
  13. is built using GNU Libtool, you may include this file under the
  14. same distribution terms that you use for the rest of that program.
  15. GNU Libltdl is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. GNU Lesser General Public License for more details.
  19. You should have received a copy of the GNU Lesser General Public
  20. License along with GNU Libltdl; see the file COPYING.LIB. If not, a
  21. copy can be downloaded from http://www.gnu.org/licenses/lgpl.html,
  22. or obtained by writing to the Free Software Foundation, Inc.,
  23. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  24. */
  25. #include "lt__private.h"
  26. #include "lt_system.h"
  27. #include "lt_dlloader.h"
  28. /* --- MANIFEST CONSTANTS --- */
  29. /* Standard libltdl search path environment variable name */
  30. #undef LTDL_SEARCHPATH_VAR
  31. #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
  32. /* Standard libtool archive file extension. */
  33. #undef LT_ARCHIVE_EXT
  34. #define LT_ARCHIVE_EXT ".la"
  35. /* max. filename length */
  36. #if !defined LT_FILENAME_MAX
  37. # define LT_FILENAME_MAX 1024
  38. #endif
  39. #if !defined LT_LIBEXT
  40. # define LT_LIBEXT "a"
  41. #endif
  42. #if !defined LT_LIBPREFIX
  43. # define LT_LIBPREFIX "lib"
  44. #endif
  45. /* This is the maximum symbol size that won't require malloc/free */
  46. #undef LT_SYMBOL_LENGTH
  47. #define LT_SYMBOL_LENGTH 128
  48. /* This accounts for the _LTX_ separator */
  49. #undef LT_SYMBOL_OVERHEAD
  50. #define LT_SYMBOL_OVERHEAD 5
  51. /* Various boolean flags can be stored in the flags field of an
  52. lt_dlhandle... */
  53. #define LT_DLIS_RESIDENT(handle) ((handle)->info.is_resident)
  54. #define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal)
  55. #define LT_DLIS_SYMLOCAL(handle) ((handle)->info.is_symlocal)
  56. static const char objdir[] = LT_OBJDIR;
  57. static const char archive_ext[] = LT_ARCHIVE_EXT;
  58. static const char libext[] = LT_LIBEXT;
  59. static const char libprefix[] = LT_LIBPREFIX;
  60. #if defined LT_MODULE_EXT
  61. static const char shlib_ext[] = LT_MODULE_EXT;
  62. #endif
  63. /* If the loadable module suffix is not the same as the linkable
  64. * shared library suffix, this will be defined. */
  65. #if defined LT_SHARED_EXT
  66. static const char shared_ext[] = LT_SHARED_EXT;
  67. #endif
  68. #if defined LT_DLSEARCH_PATH
  69. static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH;
  70. #endif
  71. /* --- DYNAMIC MODULE LOADING --- */
  72. /* The type of a function used at each iteration of foreach_dirinpath(). */
  73. typedef int foreach_callback_func (char *filename, void *data1,
  74. void *data2);
  75. /* foreachfile_callback itself calls a function of this type: */
  76. typedef int file_worker_func (const char *filename, void *data);
  77. static int foreach_dirinpath (const char *search_path,
  78. const char *base_name,
  79. foreach_callback_func *func,
  80. void *data1, void *data2);
  81. static int find_file_callback (char *filename, void *data1,
  82. void *data2);
  83. static int find_handle_callback (char *filename, void *data,
  84. void *ignored);
  85. static int foreachfile_callback (char *filename, void *data1,
  86. void *data2);
  87. static int canonicalize_path (const char *path, char **pcanonical);
  88. static int argzize_path (const char *path,
  89. char **pargz, size_t *pargz_len);
  90. static FILE *find_file (const char *search_path,
  91. const char *base_name, char **pdir);
  92. static lt_dlhandle *find_handle (const char *search_path,
  93. const char *base_name,
  94. lt_dlhandle *handle,
  95. lt_dladvise advise);
  96. static int find_module (lt_dlhandle *handle, const char *dir,
  97. const char *libdir, const char *dlname,
  98. const char *old_name, int installed,
  99. lt_dladvise advise);
  100. static int has_library_ext (const char *filename);
  101. static int load_deplibs (lt_dlhandle handle, char *deplibs);
  102. static int trim (char **dest, const char *str);
  103. static int try_dlopen (lt_dlhandle *handle,
  104. const char *filename, const char *ext,
  105. lt_dladvise advise);
  106. static int tryall_dlopen (lt_dlhandle *handle,
  107. const char *filename,
  108. lt_dladvise padvise,
  109. const lt_dlvtable *vtable);
  110. static int unload_deplibs (lt_dlhandle handle);
  111. static int lt_argz_insert (char **pargz, size_t *pargz_len,
  112. char *before, const char *entry);
  113. static int lt_argz_insertinorder (char **pargz, size_t *pargz_len,
  114. const char *entry);
  115. static int lt_argz_insertdir (char **pargz, size_t *pargz_len,
  116. const char *dirnam, struct dirent *dp);
  117. static int lt_dlpath_insertdir (char **ppath, char *before,
  118. const char *dir);
  119. static int list_files_by_dir (const char *dirnam,
  120. char **pargz, size_t *pargz_len);
  121. static int file_not_found (void);
  122. #ifdef HAVE_LIBDLLOADER
  123. static int loader_init_callback (lt_dlhandle handle);
  124. #endif /* HAVE_LIBDLLOADER */
  125. static int loader_init (lt_get_vtable *vtable_func,
  126. lt_user_data data);
  127. static char *user_search_path= 0;
  128. static lt_dlhandle handles = 0;
  129. static int initialized = 0;
  130. /* Our memory failure callback sets the error message to be passed back
  131. up to the client, so we must be careful to return from mallocation
  132. callers if allocation fails (as this callback returns!!). */
  133. void
  134. lt__alloc_die_callback (void)
  135. {
  136. LT__SETERROR (NO_MEMORY);
  137. }
  138. #ifdef HAVE_LIBDLLOADER
  139. /* This function is called to initialise each preloaded module loader,
  140. and hook it into the list of loaders to be used when attempting to
  141. dlopen an application module. */
  142. static int
  143. loader_init_callback (lt_dlhandle handle)
  144. {
  145. lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable");
  146. return loader_init (vtable_func, 0);
  147. }
  148. #endif /* HAVE_LIBDLLOADER */
  149. static int
  150. loader_init (lt_get_vtable *vtable_func, lt_user_data data)
  151. {
  152. const lt_dlvtable *vtable = 0;
  153. int errors = 0;
  154. if (vtable_func)
  155. {
  156. vtable = (*vtable_func) (data);
  157. }
  158. /* lt_dlloader_add will LT__SETERROR if it fails. */
  159. errors += lt_dlloader_add (vtable);
  160. assert (errors || vtable);
  161. if ((!errors) && vtable->dlloader_init)
  162. {
  163. if ((*vtable->dlloader_init) (vtable->dlloader_data))
  164. {
  165. LT__SETERROR (INIT_LOADER);
  166. ++errors;
  167. }
  168. }
  169. return errors;
  170. }
  171. /* Bootstrap the loader loading with the preopening loader. */
  172. #define get_vtable preopen_LTX_get_vtable
  173. #define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
  174. LT_BEGIN_C_DECLS
  175. LT_SCOPE const lt_dlvtable * get_vtable (lt_user_data data);
  176. LT_END_C_DECLS
  177. #ifdef HAVE_LIBDLLOADER
  178. extern LT_DLSYM_CONST lt_dlsymlist preloaded_symbols[];
  179. #endif
  180. /* Initialize libltdl. */
  181. int
  182. lt_dlinit (void)
  183. {
  184. int errors = 0;
  185. /* Initialize only at first call. */
  186. if (++initialized == 1)
  187. {
  188. lt__alloc_die = lt__alloc_die_callback;
  189. handles = 0;
  190. user_search_path = 0; /* empty search path */
  191. /* First set up the statically loaded preload module loader, so
  192. we can use it to preopen the other loaders we linked in at
  193. compile time. */
  194. errors += loader_init (get_vtable, 0);
  195. /* Now open all the preloaded module loaders, so the application
  196. can use _them_ to lt_dlopen its own modules. */
  197. #ifdef HAVE_LIBDLLOADER
  198. if (!errors)
  199. {
  200. errors += lt_dlpreload (preloaded_symbols);
  201. }
  202. if (!errors)
  203. {
  204. errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback);
  205. }
  206. #endif /* HAVE_LIBDLLOADER */
  207. }
  208. #ifdef LT_DEBUG_LOADERS
  209. lt_dlloader_dump();
  210. #endif
  211. return errors;
  212. }
  213. int
  214. lt_dlexit (void)
  215. {
  216. /* shut down libltdl */
  217. lt_dlloader *loader = 0;
  218. lt_dlhandle handle = handles;
  219. int errors = 0;
  220. if (!initialized)
  221. {
  222. LT__SETERROR (SHUTDOWN);
  223. ++errors;
  224. goto done;
  225. }
  226. /* shut down only at last call. */
  227. if (--initialized == 0)
  228. {
  229. int level;
  230. while (handles && LT_DLIS_RESIDENT (handles))
  231. {
  232. handles = handles->next;
  233. }
  234. /* close all modules */
  235. for (level = 1; handle; ++level)
  236. {
  237. lt_dlhandle cur = handles;
  238. int saw_nonresident = 0;
  239. while (cur)
  240. {
  241. lt_dlhandle tmp = cur;
  242. cur = cur->next;
  243. if (!LT_DLIS_RESIDENT (tmp))
  244. {
  245. saw_nonresident = 1;
  246. if (tmp->info.ref_count <= level)
  247. {
  248. if (lt_dlclose (tmp))
  249. {
  250. ++errors;
  251. }
  252. /* Make sure that the handle pointed to by 'cur' still exists.
  253. lt_dlclose recursively closes dependent libraries, which removes
  254. them from the linked list. One of these might be the one
  255. pointed to by 'cur'. */
  256. if (cur)
  257. {
  258. for (tmp = handles; tmp; tmp = tmp->next)
  259. if (tmp == cur)
  260. break;
  261. if (! tmp)
  262. cur = handles;
  263. }
  264. }
  265. }
  266. }
  267. /* done if only resident modules are left */
  268. if (!saw_nonresident)
  269. break;
  270. }
  271. /* When removing loaders, we can only find out failure by testing
  272. the error string, so avoid a spurious one from an earlier
  273. failed command. */
  274. if (!errors)
  275. LT__SETERRORSTR (0);
  276. /* close all loaders */
  277. for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;)
  278. {
  279. lt_dlloader *next = (lt_dlloader *) lt_dlloader_next (loader);
  280. lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader);
  281. if ((vtable = lt_dlloader_remove ((char *) vtable->name)))
  282. {
  283. FREE (vtable);
  284. }
  285. else
  286. {
  287. /* ignore errors due to resident modules */
  288. const char *err;
  289. LT__GETERROR (err);
  290. if (err)
  291. ++errors;
  292. }
  293. loader = next;
  294. }
  295. FREE(user_search_path);
  296. }
  297. done:
  298. return errors;
  299. }
  300. /* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME.
  301. If the library is not successfully loaded, return non-zero. Otherwise,
  302. the dlhandle is stored at the address given in PHANDLE. */
  303. static int
  304. tryall_dlopen (lt_dlhandle *phandle, const char *filename,
  305. lt_dladvise advise, const lt_dlvtable *vtable)
  306. {
  307. lt_dlhandle handle = handles;
  308. const char * saved_error = 0;
  309. int errors = 0;
  310. #ifdef LT_DEBUG_LOADERS
  311. fprintf (stderr, "tryall_dlopen (%s, %s)\n",
  312. filename ? filename : "(null)",
  313. vtable ? vtable->name : "(ALL)");
  314. #endif
  315. LT__GETERROR (saved_error);
  316. /* check whether the module was already opened */
  317. for (;handle; handle = handle->next)
  318. {
  319. if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */
  320. || (handle->info.filename && filename
  321. && STREQ (handle->info.filename, filename)))
  322. {
  323. break;
  324. }
  325. }
  326. if (handle)
  327. {
  328. ++handle->info.ref_count;
  329. *phandle = handle;
  330. goto done;
  331. }
  332. handle = *phandle;
  333. if (filename)
  334. {
  335. /* Comment out the check of file permissions using access.
  336. This call seems to always return -1 with error EACCES.
  337. */
  338. /* We need to catch missing file errors early so that
  339. file_not_found() can detect what happened.
  340. if (access (filename, R_OK) != 0)
  341. {
  342. LT__SETERROR (FILE_NOT_FOUND);
  343. ++errors;
  344. goto done;
  345. } */
  346. handle->info.filename = lt__strdup (filename);
  347. if (!handle->info.filename)
  348. {
  349. ++errors;
  350. goto done;
  351. }
  352. }
  353. else
  354. {
  355. handle->info.filename = 0;
  356. }
  357. {
  358. lt_dlloader loader = lt_dlloader_next (0);
  359. const lt_dlvtable *loader_vtable;
  360. do
  361. {
  362. if (vtable)
  363. loader_vtable = vtable;
  364. else
  365. loader_vtable = lt_dlloader_get (loader);
  366. #ifdef LT_DEBUG_LOADERS
  367. fprintf (stderr, "Calling %s->module_open (%s)\n",
  368. (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)",
  369. filename ? filename : "(null)");
  370. #endif
  371. handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data,
  372. filename, advise);
  373. #ifdef LT_DEBUG_LOADERS
  374. if (!handle->module) {
  375. char *error;
  376. LT__GETERROR(error);
  377. fprintf (stderr, " Result: Failed\n"
  378. " Error message << %s >>\n",
  379. error ? error : "(null)");
  380. } else {
  381. fprintf (stderr, " Result: Success\n");
  382. }
  383. #endif
  384. if (handle->module != 0)
  385. {
  386. if (advise)
  387. {
  388. handle->info.is_resident = advise->is_resident;
  389. handle->info.is_symglobal = advise->is_symglobal;
  390. handle->info.is_symlocal = advise->is_symlocal;
  391. }
  392. break;
  393. }
  394. }
  395. while (!vtable && (loader = lt_dlloader_next (loader)));
  396. /* If VTABLE was given but couldn't open the module, or VTABLE wasn't
  397. given but we exhausted all loaders without opening the module, bail
  398. out! */
  399. if ((vtable && !handle->module)
  400. || (!vtable && !loader))
  401. {
  402. FREE (handle->info.filename);
  403. ++errors;
  404. goto done;
  405. }
  406. handle->vtable = loader_vtable;
  407. }
  408. LT__SETERRORSTR (saved_error);
  409. done:
  410. return errors;
  411. }
  412. static int
  413. tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
  414. const char *dirname, const char *dlname,
  415. lt_dladvise advise)
  416. {
  417. int error = 0;
  418. char *filename = 0;
  419. size_t filename_len = 0;
  420. size_t dirname_len = LT_STRLEN (dirname);
  421. assert (handle);
  422. assert (dirname);
  423. assert (dlname);
  424. #if defined LT_DIRSEP_CHAR
  425. /* Only canonicalized names (i.e. with DIRSEP chars already converted)
  426. should make it into this function: */
  427. assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
  428. #endif
  429. if (dirname_len > 0)
  430. if (dirname[dirname_len -1] == '/')
  431. --dirname_len;
  432. filename_len = dirname_len + 1 + LT_STRLEN (dlname);
  433. /* Allocate memory, and combine DIRNAME and MODULENAME into it.
  434. The PREFIX (if any) is handled below. */
  435. filename = MALLOC (char, filename_len + 1);
  436. if (!filename)
  437. return 1;
  438. sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
  439. /* Now that we have combined DIRNAME and MODULENAME, if there is
  440. also a PREFIX to contend with, simply recurse with the arguments
  441. shuffled. Otherwise, attempt to open FILENAME as a module. */
  442. if (prefix)
  443. {
  444. error += tryall_dlopen_module (handle, (const char *) 0,
  445. prefix, filename, advise);
  446. }
  447. else if (tryall_dlopen (handle, filename, advise, 0) != 0)
  448. {
  449. ++error;
  450. }
  451. FREE (filename);
  452. return error;
  453. }
  454. static int
  455. find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
  456. const char *dlname, const char *old_name, int installed,
  457. lt_dladvise advise)
  458. {
  459. /* Try to open the old library first; if it was dlpreopened,
  460. we want the preopened version of it, even if a dlopenable
  461. module is available. */
  462. if (old_name && tryall_dlopen (handle, old_name,
  463. advise, lt_dlloader_find ("lt_preopen") ) == 0)
  464. {
  465. return 0;
  466. }
  467. /* Try to open the dynamic library. */
  468. if (dlname)
  469. {
  470. /* try to open the installed module */
  471. if (installed && libdir)
  472. {
  473. if (tryall_dlopen_module (handle, (const char *) 0,
  474. libdir, dlname, advise) == 0)
  475. return 0;
  476. }
  477. /* try to open the not-installed module */
  478. if (!installed)
  479. {
  480. if (tryall_dlopen_module (handle, dir, objdir,
  481. dlname, advise) == 0)
  482. return 0;
  483. }
  484. /* maybe it was moved to another directory */
  485. {
  486. if (dir && (tryall_dlopen_module (handle, (const char *) 0,
  487. dir, dlname, advise) == 0))
  488. return 0;
  489. }
  490. }
  491. return 1;
  492. }
  493. static int
  494. canonicalize_path (const char *path, char **pcanonical)
  495. {
  496. char *canonical = 0;
  497. assert (path && *path);
  498. assert (pcanonical);
  499. canonical = MALLOC (char, 1+ LT_STRLEN (path));
  500. if (!canonical)
  501. return 1;
  502. {
  503. size_t dest = 0;
  504. size_t src;
  505. for (src = 0; path[src] != LT_EOS_CHAR; ++src)
  506. {
  507. /* Path separators are not copied to the beginning or end of
  508. the destination, or if another separator would follow
  509. immediately. */
  510. if (path[src] == LT_PATHSEP_CHAR)
  511. {
  512. if ((dest == 0)
  513. || (path[1+ src] == LT_PATHSEP_CHAR)
  514. || (path[1+ src] == LT_EOS_CHAR))
  515. continue;
  516. }
  517. /* Anything other than a directory separator is copied verbatim. */
  518. if ((path[src] != '/')
  519. #if defined LT_DIRSEP_CHAR
  520. && (path[src] != LT_DIRSEP_CHAR)
  521. #endif
  522. )
  523. {
  524. canonical[dest++] = path[src];
  525. }
  526. /* Directory separators are converted and copied only if they are
  527. not at the end of a path -- i.e. before a path separator or
  528. NULL terminator. */
  529. else if ((path[1+ src] != LT_PATHSEP_CHAR)
  530. && (path[1+ src] != LT_EOS_CHAR)
  531. #if defined LT_DIRSEP_CHAR
  532. && (path[1+ src] != LT_DIRSEP_CHAR)
  533. #endif
  534. && (path[1+ src] != '/'))
  535. {
  536. canonical[dest++] = '/';
  537. }
  538. }
  539. /* Add an end-of-string marker at the end. */
  540. canonical[dest] = LT_EOS_CHAR;
  541. }
  542. /* Assign new value. */
  543. *pcanonical = canonical;
  544. return 0;
  545. }
  546. static int
  547. argzize_path (const char *path, char **pargz, size_t *pargz_len)
  548. {
  549. error_t error;
  550. assert (path);
  551. assert (pargz);
  552. assert (pargz_len);
  553. if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
  554. {
  555. switch (error)
  556. {
  557. case ENOMEM:
  558. LT__SETERROR (NO_MEMORY);
  559. break;
  560. default:
  561. LT__SETERROR (UNKNOWN);
  562. break;
  563. }
  564. return 1;
  565. }
  566. return 0;
  567. }
  568. /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
  569. of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
  570. non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
  571. it is appended to each SEARCH_PATH element before FUNC is called. */
  572. static int
  573. foreach_dirinpath (const char *search_path, const char *base_name,
  574. foreach_callback_func *func, void *data1, void *data2)
  575. {
  576. int result = 0;
  577. size_t filenamesize = 0;
  578. size_t lenbase = LT_STRLEN (base_name);
  579. size_t argz_len = 0;
  580. char *argz = 0;
  581. char *filename = 0;
  582. char *canonical = 0;
  583. if (!search_path || !*search_path)
  584. {
  585. LT__SETERROR (FILE_NOT_FOUND);
  586. goto cleanup;
  587. }
  588. if (canonicalize_path (search_path, &canonical) != 0)
  589. goto cleanup;
  590. if (argzize_path (canonical, &argz, &argz_len) != 0)
  591. goto cleanup;
  592. {
  593. char *dir_name = 0;
  594. while ((dir_name = argz_next (argz, argz_len, dir_name)))
  595. {
  596. size_t lendir = LT_STRLEN (dir_name);
  597. if (1+ lendir + lenbase >= filenamesize)
  598. {
  599. FREE (filename);
  600. filenamesize = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */
  601. filename = MALLOC (char, filenamesize);
  602. if (!filename)
  603. goto cleanup;
  604. }
  605. assert (filenamesize > lendir);
  606. strcpy (filename, dir_name);
  607. if (base_name && *base_name)
  608. {
  609. if (filename[lendir -1] != '/')
  610. filename[lendir++] = '/';
  611. strcpy (filename +lendir, base_name);
  612. }
  613. if ((result = (*func) (filename, data1, data2)))
  614. {
  615. break;
  616. }
  617. }
  618. }
  619. cleanup:
  620. FREE (argz);
  621. FREE (canonical);
  622. FREE (filename);
  623. return result;
  624. }
  625. /* If FILEPATH can be opened, store the name of the directory component
  626. in DATA1, and the opened FILE* structure address in DATA2. Otherwise
  627. DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
  628. static int
  629. find_file_callback (char *filename, void *data1, void *data2)
  630. {
  631. char **pdir = (char **) data1;
  632. FILE **pfile = (FILE **) data2;
  633. int is_done = 0;
  634. assert (filename && *filename);
  635. assert (pdir);
  636. assert (pfile);
  637. if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
  638. {
  639. char *dirend = strrchr (filename, '/');
  640. if (dirend > filename)
  641. *dirend = LT_EOS_CHAR;
  642. FREE (*pdir);
  643. *pdir = lt__strdup (filename);
  644. is_done = (*pdir == 0) ? -1 : 1;
  645. }
  646. return is_done;
  647. }
  648. static FILE *
  649. find_file (const char *search_path, const char *base_name, char **pdir)
  650. {
  651. FILE *file = 0;
  652. foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
  653. return file;
  654. }
  655. static int
  656. find_handle_callback (char *filename, void *data, void *data2)
  657. {
  658. lt_dlhandle *phandle = (lt_dlhandle *) data;
  659. int notfound = access (filename, R_OK);
  660. lt_dladvise advise = (lt_dladvise) data2;
  661. /* Bail out if file cannot be read... */
  662. if (notfound)
  663. return 0;
  664. /* Try to dlopen the file, but do not continue searching in any
  665. case. */
  666. if (tryall_dlopen (phandle, filename, advise, 0) != 0)
  667. *phandle = 0;
  668. return 1;
  669. }
  670. /* If HANDLE was found return it, otherwise return 0. If HANDLE was
  671. found but could not be opened, *HANDLE will be set to 0. */
  672. static lt_dlhandle *
  673. find_handle (const char *search_path, const char *base_name,
  674. lt_dlhandle *phandle, lt_dladvise advise)
  675. {
  676. if (!search_path)
  677. return 0;
  678. if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
  679. phandle, advise))
  680. return 0;
  681. return phandle;
  682. }
  683. #if !defined LTDL_DLOPEN_DEPLIBS
  684. static int
  685. load_deplibs (lt_dlhandle handle, char * deplibs LT__UNUSED)
  686. {
  687. handle->depcount = 0;
  688. return 0;
  689. }
  690. #else /* defined LTDL_DLOPEN_DEPLIBS */
  691. static int
  692. load_deplibs (lt_dlhandle handle, char *deplibs)
  693. {
  694. char *p, *save_search_path = 0;
  695. int depcount = 0;
  696. int i;
  697. char **names = 0;
  698. int errors = 0;
  699. handle->depcount = 0;
  700. if (!deplibs)
  701. {
  702. return errors;
  703. }
  704. ++errors;
  705. if (user_search_path)
  706. {
  707. save_search_path = lt__strdup (user_search_path);
  708. if (!save_search_path)
  709. goto cleanup;
  710. }
  711. /* extract search paths and count deplibs */
  712. p = deplibs;
  713. while (*p)
  714. {
  715. if (!isspace ((unsigned char) *p))
  716. {
  717. char *end = p+1;
  718. while (*end && !isspace((unsigned char) *end))
  719. {
  720. ++end;
  721. }
  722. if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
  723. {
  724. char save = *end;
  725. *end = 0; /* set a temporary string terminator */
  726. if (lt_dladdsearchdir(p+2))
  727. {
  728. goto cleanup;
  729. }
  730. *end = save;
  731. }
  732. else
  733. {
  734. ++depcount;
  735. }
  736. p = end;
  737. }
  738. else
  739. {
  740. ++p;
  741. }
  742. }
  743. if (!depcount)
  744. {
  745. errors = 0;
  746. goto cleanup;
  747. }
  748. names = MALLOC (char *, depcount);
  749. if (!names)
  750. goto cleanup;
  751. /* now only extract the actual deplibs */
  752. depcount = 0;
  753. p = deplibs;
  754. while (*p)
  755. {
  756. if (isspace ((unsigned char) *p))
  757. {
  758. ++p;
  759. }
  760. else
  761. {
  762. char *end = p+1;
  763. while (*end && !isspace ((unsigned char) *end))
  764. {
  765. ++end;
  766. }
  767. if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
  768. {
  769. char *name;
  770. char save = *end;
  771. *end = 0; /* set a temporary string terminator */
  772. if (strncmp(p, "-l", 2) == 0)
  773. {
  774. size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
  775. name = MALLOC (char, 1+ name_len);
  776. if (name)
  777. sprintf (name, "lib%s", p+2);
  778. }
  779. else
  780. name = lt__strdup(p);
  781. if (!name)
  782. goto cleanup_names;
  783. names[depcount++] = name;
  784. *end = save;
  785. }
  786. p = end;
  787. }
  788. }
  789. /* load the deplibs (in reverse order)
  790. At this stage, don't worry if the deplibs do not load correctly,
  791. they may already be statically linked into the loading application
  792. for instance. There will be a more enlightening error message
  793. later on if the loaded module cannot resolve all of its symbols. */
  794. if (depcount)
  795. {
  796. lt_dlhandle cur = handle;
  797. int j = 0;
  798. cur->deplibs = MALLOC (lt_dlhandle, depcount);
  799. if (!cur->deplibs)
  800. goto cleanup_names;
  801. for (i = 0; i < depcount; ++i)
  802. {
  803. cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
  804. if (cur->deplibs[j])
  805. {
  806. ++j;
  807. }
  808. }
  809. cur->depcount = j; /* Number of successfully loaded deplibs */
  810. errors = 0;
  811. }
  812. cleanup_names:
  813. for (i = 0; i < depcount; ++i)
  814. {
  815. FREE (names[i]);
  816. }
  817. cleanup:
  818. FREE (names);
  819. /* restore the old search path */
  820. if (save_search_path) {
  821. MEMREASSIGN (user_search_path, save_search_path);
  822. }
  823. return errors;
  824. }
  825. #endif /* defined LTDL_DLOPEN_DEPLIBS */
  826. static int
  827. unload_deplibs (lt_dlhandle handle)
  828. {
  829. int i;
  830. int errors = 0;
  831. lt_dlhandle cur = handle;
  832. if (cur->depcount)
  833. {
  834. for (i = 0; i < cur->depcount; ++i)
  835. {
  836. if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
  837. {
  838. errors += lt_dlclose (cur->deplibs[i]);
  839. }
  840. }
  841. FREE (cur->deplibs);
  842. }
  843. return errors;
  844. }
  845. static int
  846. trim (char **dest, const char *str)
  847. {
  848. /* remove the leading and trailing "'" from str
  849. and store the result in dest */
  850. const char *end = strrchr (str, '\'');
  851. size_t len = LT_STRLEN (str);
  852. char *tmp;
  853. FREE (*dest);
  854. if (!end || end == str)
  855. return 1;
  856. if (len > 3 && str[0] == '\'')
  857. {
  858. tmp = MALLOC (char, end - str);
  859. if (!tmp)
  860. return 1;
  861. memcpy(tmp, &str[1], (end - str) - 1);
  862. tmp[(end - str) - 1] = LT_EOS_CHAR;
  863. *dest = tmp;
  864. }
  865. else
  866. {
  867. *dest = 0;
  868. }
  869. return 0;
  870. }
  871. /* Read the .la file FILE. */
  872. static int
  873. parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs,
  874. char **old_name, int *installed)
  875. {
  876. int errors = 0;
  877. size_t line_len = LT_FILENAME_MAX;
  878. char * line = MALLOC (char, line_len);
  879. if (!line)
  880. {
  881. LT__SETERROR (FILE_NOT_FOUND);
  882. return 1;
  883. }
  884. while (!feof (file))
  885. {
  886. line[line_len-2] = '\0';
  887. if (!fgets (line, (int) line_len, file))
  888. {
  889. break;
  890. }
  891. /* Handle the case where we occasionally need to read a line
  892. that is longer than the initial buffer size.
  893. Behave even if the file contains NUL bytes due to corruption. */
  894. while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file))
  895. {
  896. line = REALLOC (char, line, line_len *2);
  897. if (!line)
  898. {
  899. ++errors;
  900. goto cleanup;
  901. }
  902. line[line_len * 2 - 2] = '\0';
  903. if (!fgets (&line[line_len -1], (int) line_len +1, file))
  904. {
  905. break;
  906. }
  907. line_len *= 2;
  908. }
  909. if (line[0] == '\n' || line[0] == '#')
  910. {
  911. continue;
  912. }
  913. #undef STR_DLNAME
  914. #define STR_DLNAME "dlname="
  915. if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
  916. {
  917. errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]);
  918. }
  919. #undef STR_OLD_LIBRARY
  920. #define STR_OLD_LIBRARY "old_library="
  921. else if (strncmp (line, STR_OLD_LIBRARY,
  922. sizeof (STR_OLD_LIBRARY) - 1) == 0)
  923. {
  924. errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
  925. }
  926. /* Windows native tools do not understand the POSIX paths we store
  927. in libdir. */
  928. #undef STR_LIBDIR
  929. #define STR_LIBDIR "libdir="
  930. else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
  931. {
  932. errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]);
  933. #ifdef __WINDOWS__
  934. /* Disallow following unix-style paths on MinGW. */
  935. if (*libdir && (**libdir == '/' || **libdir == '\\'))
  936. **libdir = '\0';
  937. #endif
  938. }
  939. #undef STR_DL_DEPLIBS
  940. #define STR_DL_DEPLIBS "dependency_libs="
  941. else if (strncmp (line, STR_DL_DEPLIBS,
  942. sizeof (STR_DL_DEPLIBS) - 1) == 0)
  943. {
  944. errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
  945. }
  946. else if (STREQ (line, "installed=yes\n"))
  947. {
  948. *installed = 1;
  949. }
  950. else if (STREQ (line, "installed=no\n"))
  951. {
  952. *installed = 0;
  953. }
  954. #undef STR_LIBRARY_NAMES
  955. #define STR_LIBRARY_NAMES "library_names="
  956. else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES,
  957. sizeof (STR_LIBRARY_NAMES) - 1) == 0)
  958. {
  959. char *last_libname;
  960. errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
  961. if (!errors
  962. && *dlname
  963. && (last_libname = strrchr (*dlname, ' ')) != 0)
  964. {
  965. last_libname = lt__strdup (last_libname + 1);
  966. if (!last_libname)
  967. {
  968. ++errors;
  969. goto cleanup;
  970. }
  971. MEMREASSIGN (*dlname, last_libname);
  972. }
  973. }
  974. if (errors)
  975. break;
  976. }
  977. cleanup:
  978. FREE (line);
  979. return errors;
  980. }
  981. /* Try to open FILENAME as a module. */
  982. static int
  983. try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
  984. lt_dladvise advise)
  985. {
  986. const char * saved_error = 0;
  987. char * archive_name = 0;
  988. char * canonical = 0;
  989. char * base_name = 0;
  990. char * dir = 0;
  991. char * name = 0;
  992. char * attempt = 0;
  993. int errors = 0;
  994. lt_dlhandle newhandle;
  995. assert (phandle);
  996. assert (*phandle == 0);
  997. #ifdef LT_DEBUG_LOADERS
  998. fprintf (stderr, "try_dlopen (%s, %s)\n",
  999. filename ? filename : "(null)",
  1000. ext ? ext : "(null)");
  1001. #endif
  1002. LT__GETERROR (saved_error);
  1003. /* dlopen self? */
  1004. if (!filename)
  1005. {
  1006. *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
  1007. if (*phandle == 0)
  1008. return 1;
  1009. newhandle = *phandle;
  1010. /* lt_dlclose()ing yourself is very bad! Disallow it. */
  1011. newhandle->info.is_resident = 1;
  1012. if (tryall_dlopen (&newhandle, 0, advise, 0) != 0)
  1013. {
  1014. FREE (*phandle);
  1015. return 1;
  1016. }
  1017. goto register_handle;
  1018. }
  1019. assert (filename && *filename);
  1020. if (ext)
  1021. {
  1022. attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1);
  1023. if (!attempt)
  1024. return 1;
  1025. sprintf(attempt, "%s%s", filename, ext);
  1026. }
  1027. else
  1028. {
  1029. attempt = lt__strdup (filename);
  1030. if (!attempt)
  1031. return 1;
  1032. }
  1033. /* Doing this immediately allows internal functions to safely
  1034. assume only canonicalized paths are passed. */
  1035. if (canonicalize_path (attempt, &canonical) != 0)
  1036. {
  1037. ++errors;
  1038. goto cleanup;
  1039. }
  1040. /* If the canonical module name is a path (relative or absolute)
  1041. then split it into a directory part and a name part. */
  1042. base_name = strrchr (canonical, '/');
  1043. if (base_name)
  1044. {
  1045. size_t dirlen = (1+ base_name) - canonical;
  1046. dir = MALLOC (char, 1+ dirlen);
  1047. if (!dir)
  1048. {
  1049. ++errors;
  1050. goto cleanup;
  1051. }
  1052. strlcpy (dir, canonical, dirlen);
  1053. dir[dirlen] = LT_EOS_CHAR;
  1054. ++base_name;
  1055. }
  1056. else
  1057. MEMREASSIGN (base_name, canonical);
  1058. assert (base_name && *base_name);
  1059. ext = strrchr (base_name, '.');
  1060. if (!ext)
  1061. {
  1062. ext = base_name + LT_STRLEN (base_name);
  1063. }
  1064. /* extract the module name from the file name */
  1065. name = MALLOC (char, ext - base_name + 1);
  1066. if (!name)
  1067. {
  1068. ++errors;
  1069. goto cleanup;
  1070. }
  1071. /* canonicalize the module name */
  1072. {
  1073. int i;
  1074. for (i = 0; i < ext - base_name; ++i)
  1075. {
  1076. if (isalnum ((unsigned char)(base_name[i])))
  1077. {
  1078. name[i] = base_name[i];
  1079. }
  1080. else
  1081. {
  1082. name[i] = '_';
  1083. }
  1084. }
  1085. name[ext - base_name] = LT_EOS_CHAR;
  1086. }
  1087. /* Before trawling through the file system in search of a module,
  1088. check whether we are opening a preloaded module. */
  1089. if (!dir)
  1090. {
  1091. const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen");
  1092. if (vtable)
  1093. {
  1094. /* libprefix + name + "." + libext + NULL */
  1095. archive_name = MALLOC (char, strlen (libprefix) + LT_STRLEN (name) + strlen (libext) + 2);
  1096. *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
  1097. if ((*phandle == NULL) || (archive_name == NULL))
  1098. {
  1099. ++errors;
  1100. goto cleanup;
  1101. }
  1102. newhandle = *phandle;
  1103. /* Preloaded modules are always named according to their old
  1104. archive name. */
  1105. if (strncmp(name, "lib", 3) == 0)
  1106. {
  1107. sprintf (archive_name, "%s%s.%s", libprefix, name + 3, libext);
  1108. }
  1109. else
  1110. {
  1111. sprintf (archive_name, "%s.%s", name, libext);
  1112. }
  1113. if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0)
  1114. {
  1115. goto register_handle;
  1116. }
  1117. /* If we're still here, there was no matching preloaded module,
  1118. so put things back as we found them, and continue searching. */
  1119. FREE (*phandle);
  1120. newhandle = NULL;
  1121. }
  1122. }
  1123. /* If we are allowing only preloaded modules, and we didn't find
  1124. anything yet, give up on the search here. */
  1125. if (advise && advise->try_preload_only)
  1126. {
  1127. goto cleanup;
  1128. }
  1129. /* Check whether we are opening a libtool module (.la extension). */
  1130. if (ext && STREQ (ext, archive_ext))
  1131. {
  1132. /* this seems to be a libtool module */
  1133. FILE * file = 0;
  1134. char * dlname = 0;
  1135. char * old_name = 0;
  1136. char * libdir = 0;
  1137. char * deplibs = 0;
  1138. /* if we can't find the installed flag, it is probably an
  1139. installed libtool archive, produced with an old version
  1140. of libtool */
  1141. int installed = 1;
  1142. /* Now try to open the .la file. If there is no directory name
  1143. component, try to find it first in user_search_path and then other
  1144. prescribed paths. Otherwise (or in any case if the module was not
  1145. yet found) try opening just the module name as passed. */
  1146. if (!dir)
  1147. {
  1148. const char *search_path = user_search_path;
  1149. if (search_path)
  1150. file = find_file (user_search_path, base_name, &dir);
  1151. if (!file)
  1152. {
  1153. search_path = getenv (LTDL_SEARCHPATH_VAR);
  1154. if (search_path)
  1155. file = find_file (search_path, base_name, &dir);
  1156. }
  1157. #if defined LT_MODULE_PATH_VAR
  1158. if (!file)
  1159. {
  1160. search_path = getenv (LT_MODULE_PATH_VAR);
  1161. if (search_path)
  1162. file = find_file (search_path, base_name, &dir);
  1163. }
  1164. #endif
  1165. #if defined LT_DLSEARCH_PATH
  1166. if (!file && *sys_dlsearch_path)
  1167. {
  1168. file = find_file (sys_dlsearch_path, base_name, &dir);
  1169. }
  1170. #endif
  1171. }
  1172. else
  1173. {
  1174. file = fopen (attempt, LT_READTEXT_MODE);
  1175. }
  1176. /* If we didn't find the file by now, it really isn't there. Set
  1177. the status flag, and bail out. */
  1178. if (!file)
  1179. {
  1180. LT__SETERROR (FILE_NOT_FOUND);
  1181. ++errors;
  1182. goto cleanup;
  1183. }
  1184. /* read the .la file */
  1185. if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
  1186. &old_name, &installed) != 0)
  1187. ++errors;
  1188. fclose (file);
  1189. /* allocate the handle */
  1190. *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
  1191. if (*phandle == 0)
  1192. ++errors;
  1193. if (errors)
  1194. {
  1195. FREE (dlname);
  1196. FREE (old_name);
  1197. FREE (libdir);
  1198. FREE (deplibs);
  1199. FREE (*phandle);
  1200. goto cleanup;
  1201. }
  1202. assert (*phandle);
  1203. if (load_deplibs (*phandle, deplibs) == 0)
  1204. {
  1205. newhandle = *phandle;
  1206. /* find_module may replace newhandle */
  1207. if (find_module (&newhandle, dir, libdir, dlname, old_name,
  1208. installed, advise))
  1209. {
  1210. unload_deplibs (*phandle);
  1211. ++errors;
  1212. }
  1213. }
  1214. else
  1215. {
  1216. ++errors;
  1217. }
  1218. FREE (dlname);
  1219. FREE (old_name);
  1220. FREE (libdir);
  1221. FREE (deplibs);
  1222. if (errors)
  1223. {
  1224. FREE (*phandle);
  1225. goto cleanup;
  1226. }
  1227. if (*phandle != newhandle)
  1228. {
  1229. unload_deplibs (*phandle);
  1230. }
  1231. }
  1232. else
  1233. {
  1234. /* not a libtool module */
  1235. *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
  1236. if (*phandle == 0)
  1237. {
  1238. ++errors;
  1239. goto cleanup;
  1240. }
  1241. newhandle = *phandle;
  1242. /* If the module has no directory name component, try to find it
  1243. first in user_search_path and then other prescribed paths.
  1244. Otherwise (or in any case if the module was not yet found) try
  1245. opening just the module name as passed. */
  1246. if ((dir || (!find_handle (user_search_path, base_name,
  1247. &newhandle, advise)
  1248. && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
  1249. &newhandle, advise)
  1250. #if defined LT_MODULE_PATH_VAR
  1251. && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name,
  1252. &newhandle, advise)
  1253. #endif
  1254. #if defined LT_DLSEARCH_PATH
  1255. && !find_handle (sys_dlsearch_path, base_name,
  1256. &newhandle, advise)
  1257. #endif
  1258. )))
  1259. {
  1260. if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0)
  1261. {
  1262. newhandle = NULL;
  1263. }
  1264. }
  1265. if (!newhandle)
  1266. {
  1267. FREE (*phandle);
  1268. ++errors;
  1269. goto cleanup;
  1270. }
  1271. }
  1272. register_handle:
  1273. MEMREASSIGN (*phandle, newhandle);
  1274. if ((*phandle)->info.ref_count == 0)
  1275. {
  1276. (*phandle)->info.ref_count = 1;
  1277. MEMREASSIGN ((*phandle)->info.name, name);
  1278. (*phandle)->next = handles;
  1279. handles = *phandle;
  1280. }
  1281. LT__SETERRORSTR (saved_error);
  1282. cleanup:
  1283. FREE (dir);
  1284. FREE (attempt);
  1285. FREE (name);
  1286. if (!canonical) /* was MEMREASSIGNed */
  1287. FREE (base_name);
  1288. FREE (canonical);
  1289. FREE (archive_name);
  1290. return errors;
  1291. }
  1292. /* If the last error message stored was 'FILE_NOT_FOUND', then return
  1293. non-zero. */
  1294. static int
  1295. file_not_found (void)
  1296. {
  1297. const char *error = 0;
  1298. LT__GETERROR (error);
  1299. if (error == LT__STRERROR (FILE_NOT_FOUND))
  1300. return 1;
  1301. return 0;
  1302. }
  1303. /* Unless FILENAME already bears a suitable library extension, then
  1304. return 0. */
  1305. static int
  1306. has_library_ext (const char *filename)
  1307. {
  1308. const char * ext = 0;
  1309. assert (filename);
  1310. ext = strrchr (filename, '.');
  1311. if (ext && ((STREQ (ext, archive_ext))
  1312. #if defined LT_MODULE_EXT
  1313. || (STREQ (ext, shlib_ext))
  1314. #endif
  1315. #if defined LT_SHARED_EXT
  1316. || (STREQ (ext, shared_ext))
  1317. #endif
  1318. ))
  1319. {
  1320. return 1;
  1321. }
  1322. return 0;
  1323. }
  1324. /* Initialise and configure a user lt_dladvise opaque object. */
  1325. int
  1326. lt_dladvise_init (lt_dladvise *padvise)
  1327. {
  1328. lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise));
  1329. *padvise = advise;
  1330. return (advise ? 0 : 1);
  1331. }
  1332. int
  1333. lt_dladvise_destroy (lt_dladvise *padvise)
  1334. {
  1335. if (padvise)
  1336. FREE(*padvise);
  1337. return 0;
  1338. }
  1339. int
  1340. lt_dladvise_ext (lt_dladvise *padvise)
  1341. {
  1342. assert (padvise && *padvise);
  1343. (*padvise)->try_ext = 1;
  1344. return 0;
  1345. }
  1346. int
  1347. lt_dladvise_resident (lt_dladvise *padvise)
  1348. {
  1349. assert (padvise && *padvise);
  1350. (*padvise)->is_resident = 1;
  1351. return 0;
  1352. }
  1353. int
  1354. lt_dladvise_local (lt_dladvise *padvise)
  1355. {
  1356. assert (padvise && *padvise);
  1357. (*padvise)->is_symlocal = 1;
  1358. return 0;
  1359. }
  1360. int
  1361. lt_dladvise_global (lt_dladvise *padvise)
  1362. {
  1363. assert (padvise && *padvise);
  1364. (*padvise)->is_symglobal = 1;
  1365. return 0;
  1366. }
  1367. int
  1368. lt_dladvise_preload (lt_dladvise *padvise)
  1369. {
  1370. assert (padvise && *padvise);
  1371. (*padvise)->try_preload_only = 1;
  1372. return 0;
  1373. }
  1374. /* Libtool-1.5.x interface for loading a new module named FILENAME. */
  1375. lt_dlhandle
  1376. lt_dlopen (const char *filename)
  1377. {
  1378. return lt_dlopenadvise (filename, NULL);
  1379. }
  1380. /* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
  1381. open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
  1382. and if a file is still not found try again with MODULE_EXT appended
  1383. instead. */
  1384. lt_dlhandle
  1385. lt_dlopenext (const char *filename)
  1386. {
  1387. lt_dlhandle handle = 0;
  1388. lt_dladvise advise;
  1389. if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise))
  1390. handle = lt_dlopenadvise (filename, advise);
  1391. lt_dladvise_destroy (&advise);
  1392. return handle;
  1393. }
  1394. lt_dlhandle
  1395. lt_dlopenadvise (const char *filename, lt_dladvise advise)
  1396. {
  1397. lt_dlhandle handle = 0;
  1398. int errors = 0;
  1399. const char * saved_error = 0;
  1400. LT__GETERROR (saved_error);
  1401. /* Can't have symbols hidden and visible at the same time! */
  1402. if (advise && advise->is_symlocal && advise->is_symglobal)
  1403. {
  1404. LT__SETERROR (CONFLICTING_FLAGS);
  1405. return 0;
  1406. }
  1407. if (!filename
  1408. || !advise
  1409. || !advise->try_ext
  1410. || has_library_ext (filename))
  1411. {
  1412. /* Just incase we missed a code path in try_dlopen() that reports
  1413. an error, but forgot to reset handle... */
  1414. if (try_dlopen (&handle, filename, NULL, advise) != 0)
  1415. return 0;
  1416. return handle;
  1417. }
  1418. else if (filename && *filename)
  1419. {
  1420. /* First try appending ARCHIVE_EXT. */
  1421. errors += try_dlopen (&handle, filename, archive_ext, advise);
  1422. /* If we found FILENAME, stop searching -- whether we were able to
  1423. load the file as a module or not. If the file exists but loading
  1424. failed, it is better to return an error message here than to
  1425. report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
  1426. in the module search path. */
  1427. if (handle || ((errors > 0) && !file_not_found ()))
  1428. return handle;
  1429. #if defined LT_MODULE_EXT
  1430. /* Try appending SHLIB_EXT. */
  1431. LT__SETERRORSTR (saved_error);
  1432. errors = try_dlopen (&handle, filename, shlib_ext, advise);
  1433. /* As before, if the file was found but loading failed, return now
  1434. with the current error message. */
  1435. if (handle || ((errors > 0) && !file_not_found ()))
  1436. return handle;
  1437. #endif
  1438. #if defined LT_SHARED_EXT
  1439. /* Try appending SHARED_EXT. */
  1440. LT__SETERRORSTR (saved_error);
  1441. errors = try_dlopen (&handle, filename, shared_ext, advise);
  1442. /* As before, if the file was found but loading failed, return now
  1443. with the current error message. */
  1444. if (handle || ((errors > 0) && !file_not_found ()))
  1445. return handle;
  1446. #endif
  1447. }
  1448. /* Still here? Then we really did fail to locate any of the file
  1449. names we tried. */
  1450. LT__SETERROR (FILE_NOT_FOUND);
  1451. return 0;
  1452. }
  1453. static int
  1454. lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
  1455. const char *entry)
  1456. {
  1457. error_t error;
  1458. /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
  1459. pargz_len, NULL, entry) failed with EINVAL. */
  1460. if (before)
  1461. error = argz_insert (pargz, pargz_len, before, entry);
  1462. else
  1463. error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
  1464. if (error)
  1465. {
  1466. switch (error)
  1467. {
  1468. case ENOMEM:
  1469. LT__SETERROR (NO_MEMORY);
  1470. break;
  1471. default:
  1472. LT__SETERROR (UNKNOWN);
  1473. break;
  1474. }
  1475. return 1;
  1476. }
  1477. return 0;
  1478. }
  1479. static int
  1480. lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
  1481. {
  1482. char *before = 0;
  1483. assert (pargz);
  1484. assert (pargz_len);
  1485. assert (entry && *entry);
  1486. if (*pargz)
  1487. while ((before = argz_next (*pargz, *pargz_len, before)))
  1488. {
  1489. int cmp = strcmp (entry, before);
  1490. if (cmp < 0) break;
  1491. if (cmp == 0) return 0; /* No duplicates! */
  1492. }
  1493. return lt_argz_insert (pargz, pargz_len, before, entry);
  1494. }
  1495. static int
  1496. lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
  1497. struct dirent *dp)
  1498. {
  1499. char *buf = 0;
  1500. size_t buf_len = 0;
  1501. char *end = 0;
  1502. size_t end_offset = 0;
  1503. size_t dir_len = 0;
  1504. int errors = 0;
  1505. assert (pargz);
  1506. assert (pargz_len);
  1507. assert (dp);
  1508. dir_len = LT_STRLEN (dirnam);
  1509. end = dp->d_name + D_NAMLEN(dp);
  1510. /* Ignore version numbers. */
  1511. {
  1512. char *p;
  1513. for (p = end; p -1 > dp->d_name; --p)
  1514. if (strchr (".0123456789", p[-1]) == 0)
  1515. break;
  1516. if (*p == '.')
  1517. end = p;
  1518. }
  1519. /* Ignore filename extension. */
  1520. {
  1521. char *p;
  1522. for (p = end -1; p > dp->d_name; --p)
  1523. if (*p == '.')
  1524. {
  1525. end = p;
  1526. break;
  1527. }
  1528. }
  1529. /* Prepend the directory name. */
  1530. end_offset = end - dp->d_name;
  1531. buf_len = dir_len + 1+ end_offset;
  1532. buf = MALLOC (char, 1+ buf_len);
  1533. if (!buf)
  1534. return ++errors;
  1535. assert (buf);
  1536. strcpy (buf, dirnam);
  1537. strcat (buf, "/");
  1538. strncat (buf, dp->d_name, end_offset);
  1539. buf[buf_len] = LT_EOS_CHAR;
  1540. /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
  1541. if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
  1542. ++errors;
  1543. FREE (buf);
  1544. return errors;
  1545. }
  1546. static int
  1547. list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
  1548. {
  1549. DIR *dirp = 0;
  1550. int errors = 0;
  1551. assert (dirnam && *dirnam);
  1552. assert (pargz);
  1553. assert (pargz_len);
  1554. assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
  1555. dirp = opendir (dirnam);
  1556. if (dirp)
  1557. {
  1558. struct dirent *dp = 0;
  1559. while ((dp = readdir (dirp)))
  1560. if (dp->d_name[0] != '.')
  1561. if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
  1562. {
  1563. ++errors;
  1564. break;
  1565. }
  1566. closedir (dirp);
  1567. }
  1568. else
  1569. ++errors;
  1570. return errors;
  1571. }
  1572. /* If there are any files in DIRNAME, call the function passed in
  1573. DATA1 (with the name of each file and DATA2 as arguments). */
  1574. static int
  1575. foreachfile_callback (char *dirname, void *data1, void *data2)
  1576. {
  1577. file_worker_func *func = *(file_worker_func **) data1;
  1578. int is_done = 0;
  1579. char *argz = 0;
  1580. size_t argz_len = 0;
  1581. if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
  1582. goto cleanup;
  1583. if (!argz)
  1584. goto cleanup;
  1585. {
  1586. char *filename = 0;
  1587. while ((filename = argz_next (argz, argz_len, filename)))
  1588. if ((is_done = (*func) (filename, data2)))
  1589. break;
  1590. }
  1591. cleanup:
  1592. FREE (argz);
  1593. return is_done;
  1594. }
  1595. /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
  1596. with DATA. The filenames passed to FUNC would be suitable for
  1597. passing to lt_dlopenext. The extensions are stripped so that
  1598. individual modules do not generate several entries (e.g. libfoo.la,
  1599. libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
  1600. then the same directories that lt_dlopen would search are examined. */
  1601. int
  1602. lt_dlforeachfile (const char *search_path,
  1603. int (*func) (const char *filename, void *data),
  1604. void *data)
  1605. {
  1606. int is_done = 0;
  1607. file_worker_func **fpptr = &func;
  1608. if (search_path)
  1609. {
  1610. /* If a specific path was passed, search only the directories
  1611. listed in it. */
  1612. is_done = foreach_dirinpath (search_path, 0,
  1613. foreachfile_callback, fpptr, data);
  1614. }
  1615. else
  1616. {
  1617. /* Otherwise search the default paths. */
  1618. is_done = foreach_dirinpath (user_search_path, 0,
  1619. foreachfile_callback, fpptr, data);
  1620. if (!is_done)
  1621. {
  1622. is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
  1623. foreachfile_callback, fpptr, data);
  1624. }
  1625. #if defined LT_MODULE_PATH_VAR
  1626. if (!is_done)
  1627. {
  1628. is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
  1629. foreachfile_callback, fpptr, data);
  1630. }
  1631. #endif
  1632. #if defined LT_DLSEARCH_PATH
  1633. if (!is_done && *sys_dlsearch_path)
  1634. {
  1635. is_done = foreach_dirinpath (sys_dlsearch_path, 0,
  1636. foreachfile_callback, fpptr, data);
  1637. }
  1638. #endif
  1639. }
  1640. return is_done;
  1641. }
  1642. int
  1643. lt_dlclose (lt_dlhandle handle)
  1644. {
  1645. lt_dlhandle cur, last;
  1646. int errors = 0;
  1647. /* check whether the handle is valid */
  1648. last = cur = handles;
  1649. while (cur && handle != cur)
  1650. {
  1651. last = cur;
  1652. cur = cur->next;
  1653. }
  1654. if (!cur)
  1655. {
  1656. LT__SETERROR (INVALID_HANDLE);
  1657. ++errors;
  1658. goto done;
  1659. }
  1660. cur = handle;
  1661. cur->info.ref_count--;
  1662. /* Note that even with resident modules, we must track the ref_count
  1663. correctly incase the user decides to reset the residency flag
  1664. later (even though the API makes no provision for that at the
  1665. moment). */
  1666. if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
  1667. {
  1668. lt_user_data data = cur->vtable->dlloader_data;
  1669. if (cur != handles)
  1670. {
  1671. last->next = cur->next;
  1672. }
  1673. else
  1674. {
  1675. handles = cur->next;
  1676. }
  1677. errors += cur->vtable->module_close (data, cur->module);
  1678. errors += unload_deplibs (handle);
  1679. /* It is up to the callers to free the data itself. */
  1680. FREE (cur->interface_data);
  1681. FREE (cur->info.filename);
  1682. FREE (cur->info.name);
  1683. FREE (cur);
  1684. goto done;
  1685. }
  1686. if (LT_DLIS_RESIDENT (handle))
  1687. {
  1688. LT__SETERROR (CLOSE_RESIDENT_MODULE);
  1689. ++errors;
  1690. }
  1691. done:
  1692. return errors;
  1693. }
  1694. void *
  1695. lt_dlsym (lt_dlhandle place, const char *symbol)
  1696. {
  1697. size_t lensym;
  1698. char lsym[LT_SYMBOL_LENGTH];
  1699. char *sym;
  1700. void *address;
  1701. lt_user_data data;
  1702. lt_dlhandle handle;
  1703. if (!place)
  1704. {
  1705. LT__SETERROR (INVALID_HANDLE);
  1706. return 0;
  1707. }
  1708. handle = place;
  1709. if (!symbol)
  1710. {
  1711. LT__SETERROR (SYMBOL_NOT_FOUND);
  1712. return 0;
  1713. }
  1714. lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)
  1715. + LT_STRLEN (handle->info.name);
  1716. if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
  1717. {
  1718. sym = lsym;
  1719. }
  1720. else
  1721. {
  1722. sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
  1723. if (!sym)
  1724. {
  1725. LT__SETERROR (BUFFER_OVERFLOW);
  1726. return 0;
  1727. }
  1728. }
  1729. data = handle->vtable->dlloader_data;
  1730. if (handle->info.name)
  1731. {
  1732. const char *saved_error;
  1733. LT__GETERROR (saved_error);
  1734. /* this is a libtool module */
  1735. if (handle->vtable->sym_prefix)
  1736. {
  1737. strcpy(sym, handle->vtable->sym_prefix);
  1738. strcat(sym, handle->info.name);
  1739. }
  1740. else
  1741. {
  1742. strcpy(sym, handle->info.name);
  1743. }
  1744. strcat(sym, "_LTX_");
  1745. strcat(sym, symbol);
  1746. /* try "modulename_LTX_symbol" */
  1747. address = handle->vtable->find_sym (data, handle->module, sym);
  1748. if (address)
  1749. {
  1750. if (sym != lsym)
  1751. {
  1752. FREE (sym);
  1753. }
  1754. return address;
  1755. }
  1756. LT__SETERRORSTR (saved_error);
  1757. }
  1758. /* otherwise try "symbol" */
  1759. if (handle->vtable->sym_prefix)
  1760. {
  1761. strcpy(sym, handle->vtable->sym_prefix);
  1762. strcat(sym, symbol);
  1763. }
  1764. else
  1765. {
  1766. strcpy(sym, symbol);
  1767. }
  1768. address = handle->vtable->find_sym (data, handle->module, sym);
  1769. if (sym != lsym)
  1770. {
  1771. FREE (sym);
  1772. }
  1773. return address;
  1774. }
  1775. const char *
  1776. lt_dlerror (void)
  1777. {
  1778. const char *error;
  1779. LT__GETERROR (error);
  1780. LT__SETERRORSTR (0);
  1781. return error;
  1782. }
  1783. static int
  1784. lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
  1785. {
  1786. int errors = 0;
  1787. char *canonical = 0;
  1788. char *argz = 0;
  1789. size_t argz_len = 0;
  1790. assert (ppath);
  1791. assert (dir && *dir);
  1792. if (canonicalize_path (dir, &canonical) != 0)
  1793. {
  1794. ++errors;
  1795. goto cleanup;
  1796. }
  1797. assert (canonical && *canonical);
  1798. /* If *PPATH is empty, set it to DIR. */
  1799. if (*ppath == 0)
  1800. {
  1801. assert (!before); /* BEFORE cannot be set without PPATH. */
  1802. assert (dir); /* Without DIR, don't call this function! */
  1803. *ppath = lt__strdup (dir);
  1804. if (*ppath == 0)
  1805. ++errors;
  1806. goto cleanup;
  1807. }
  1808. assert (ppath && *ppath);
  1809. if (argzize_path (*ppath, &argz, &argz_len) != 0)
  1810. {
  1811. ++errors;
  1812. goto cleanup;
  1813. }
  1814. /* Convert BEFORE into an equivalent offset into ARGZ. This only works
  1815. if *PPATH is already canonicalized, and hence does not change length
  1816. with respect to ARGZ. We canonicalize each entry as it is added to
  1817. the search path, and don't call this function with (uncanonicalized)
  1818. user paths, so this is a fair assumption. */
  1819. if (before)
  1820. {
  1821. assert (*ppath <= before);
  1822. assert ((int) (before - *ppath) <= (int) strlen (*ppath));
  1823. before = before - *ppath + argz;
  1824. }
  1825. if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
  1826. {
  1827. ++errors;
  1828. goto cleanup;
  1829. }
  1830. argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
  1831. MEMREASSIGN(*ppath, argz);
  1832. cleanup:
  1833. FREE (argz);
  1834. FREE (canonical);
  1835. return errors;
  1836. }
  1837. int
  1838. lt_dladdsearchdir (const char *search_dir)
  1839. {
  1840. int errors = 0;
  1841. if (search_dir && *search_dir)
  1842. {
  1843. if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
  1844. ++errors;
  1845. }
  1846. return errors;
  1847. }
  1848. int
  1849. lt_dlinsertsearchdir (const char *before, const char *search_dir)
  1850. {
  1851. int errors = 0;
  1852. if (before)
  1853. {
  1854. if ((before < user_search_path)
  1855. || (before >= user_search_path + LT_STRLEN (user_search_path)))
  1856. {
  1857. LT__SETERROR (INVALID_POSITION);
  1858. return 1;
  1859. }
  1860. }
  1861. if (search_dir && *search_dir)
  1862. {
  1863. if (lt_dlpath_insertdir (&user_search_path,
  1864. (char *) before, search_dir) != 0)
  1865. {
  1866. ++errors;
  1867. }
  1868. }
  1869. return errors;
  1870. }
  1871. int
  1872. lt_dlsetsearchpath (const char *search_path)
  1873. {
  1874. int errors = 0;
  1875. FREE (user_search_path);
  1876. if (!search_path || !LT_STRLEN (search_path))
  1877. {
  1878. return errors;
  1879. }
  1880. if (canonicalize_path (search_path, &user_search_path) != 0)
  1881. ++errors;
  1882. return errors;
  1883. }
  1884. const char *
  1885. lt_dlgetsearchpath (void)
  1886. {
  1887. const char *saved_path;
  1888. saved_path = user_search_path;
  1889. return saved_path;
  1890. }
  1891. int
  1892. lt_dlmakeresident (lt_dlhandle handle)
  1893. {
  1894. int errors = 0;
  1895. if (!handle)
  1896. {
  1897. LT__SETERROR (INVALID_HANDLE);
  1898. ++errors;
  1899. }
  1900. else
  1901. {
  1902. handle->info.is_resident = 1;
  1903. }
  1904. return errors;
  1905. }
  1906. int
  1907. lt_dlisresident (lt_dlhandle handle)
  1908. {
  1909. if (!handle)
  1910. {
  1911. LT__SETERROR (INVALID_HANDLE);
  1912. return -1;
  1913. }
  1914. return LT_DLIS_RESIDENT (handle);
  1915. }
  1916. /* --- MODULE INFORMATION --- */
  1917. typedef struct {
  1918. char *id_string;
  1919. lt_dlhandle_interface *iface;
  1920. } lt__interface_id;
  1921. lt_dlinterface_id
  1922. lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
  1923. {
  1924. lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);
  1925. /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
  1926. can then be detected with lt_dlerror() if we return 0. */
  1927. if (interface_id)
  1928. {
  1929. interface_id->id_string = lt__strdup (id_string);
  1930. if (!interface_id->id_string)
  1931. FREE (interface_id);
  1932. else
  1933. interface_id->iface = iface;
  1934. }
  1935. return (lt_dlinterface_id) interface_id;
  1936. }
  1937. void lt_dlinterface_free (lt_dlinterface_id key)
  1938. {
  1939. lt__interface_id *interface_id = (lt__interface_id *)key;
  1940. FREE (interface_id->id_string);
  1941. FREE (interface_id);
  1942. }
  1943. void *
  1944. lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
  1945. {
  1946. int n_elements = 0;
  1947. void *stale = (void *) 0;
  1948. lt_dlhandle cur = handle;
  1949. int i;
  1950. if (cur->interface_data)
  1951. while (cur->interface_data[n_elements].key)
  1952. ++n_elements;
  1953. for (i = 0; i < n_elements; ++i)
  1954. {
  1955. if (cur->interface_data[i].key == key)
  1956. {
  1957. stale = cur->interface_data[i].data;
  1958. break;
  1959. }
  1960. }
  1961. /* Ensure that there is enough room in this handle's interface_data
  1962. array to accept a new element (and an empty end marker). */
  1963. if (i == n_elements)
  1964. {
  1965. lt_interface_data *temp
  1966. = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
  1967. if (!temp)
  1968. {
  1969. stale = 0;
  1970. goto done;
  1971. }
  1972. cur->interface_data = temp;
  1973. /* We only need this if we needed to allocate a new interface_data. */
  1974. cur->interface_data[i].key = key;
  1975. cur->interface_data[1+ i].key = 0;
  1976. }
  1977. cur->interface_data[i].data = data;
  1978. done:
  1979. return stale;
  1980. }
  1981. void *
  1982. lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
  1983. {
  1984. void *result = (void *) 0;
  1985. lt_dlhandle cur = handle;
  1986. /* Locate the index of the element with a matching KEY. */
  1987. if (cur->interface_data)
  1988. {
  1989. int i;
  1990. for (i = 0; cur->interface_data[i].key; ++i)
  1991. {
  1992. if (cur->interface_data[i].key == key)
  1993. {
  1994. result = cur->interface_data[i].data;
  1995. break;
  1996. }
  1997. }
  1998. }
  1999. return result;
  2000. }
  2001. const lt_dlinfo *
  2002. lt_dlgetinfo (lt_dlhandle handle)
  2003. {
  2004. if (!handle)
  2005. {
  2006. LT__SETERROR (INVALID_HANDLE);
  2007. return 0;
  2008. }
  2009. return &(handle->info);
  2010. }
  2011. lt_dlhandle
  2012. lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
  2013. {
  2014. lt_dlhandle handle = place;
  2015. lt__interface_id *iterator = (lt__interface_id *) iface;
  2016. assert (iface); /* iface is a required argument */
  2017. if (!handle)
  2018. handle = handles;
  2019. else
  2020. handle = handle->next;
  2021. /* advance while the interface check fails */
  2022. while (handle && iterator->iface
  2023. && ((*iterator->iface) (handle, iterator->id_string) != 0))
  2024. {
  2025. handle = handle->next;
  2026. }
  2027. return handle;
  2028. }
  2029. lt_dlhandle
  2030. lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
  2031. {
  2032. lt_dlhandle handle = 0;
  2033. assert (iface); /* iface is a required argument */
  2034. while ((handle = lt_dlhandle_iterate (iface, handle)))
  2035. {
  2036. lt_dlhandle cur = handle;
  2037. if (cur && cur->info.name && STREQ (cur->info.name, module_name))
  2038. break;
  2039. }
  2040. return handle;
  2041. }
  2042. int
  2043. lt_dlhandle_map (lt_dlinterface_id iface,
  2044. int (*func) (lt_dlhandle handle, void *data), void *data)
  2045. {
  2046. lt__interface_id *iterator = (lt__interface_id *) iface;
  2047. lt_dlhandle cur = handles;
  2048. assert (iface); /* iface is a required argument */
  2049. while (cur)
  2050. {
  2051. int errorcode = 0;
  2052. /* advance while the interface check fails */
  2053. while (cur && iterator->iface
  2054. && ((*iterator->iface) (cur, iterator->id_string) != 0))
  2055. {
  2056. cur = cur->next;
  2057. }
  2058. if ((errorcode = (*func) (cur, data)) != 0)
  2059. return errorcode;
  2060. }
  2061. return 0;
  2062. }