Annotation of sql/pgsql/libltdl/ltdl.c, revision 1.1
1.1 ! parser 1: /* ltdl.c -- system independent dlopen wrapper
! 2: Copyright (C) 1998-1999 Free Software Foundation, Inc.
! 3: Originally by Thomas Tanner <tanner@ffii.org>
! 4: This file is part of GNU Libtool.
! 5:
! 6: This library is free software; you can redistribute it and/or
! 7: modify it under the terms of the GNU Library General Public
! 8: License as published by the Free Software Foundation; either
! 9: version 2 of the License, or (at your option) any later version.
! 10:
! 11: As a special exception to the GNU Library General Public License,
! 12: if you distribute this file as part of a program that uses GNU libtool
! 13: to create libraries and programs, you may include it under the same
! 14: distribution terms that you use for the rest of that program.
! 15:
! 16: This library is distributed in the hope that it will be useful,
! 17: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 18: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
! 19: Library General Public License for more details.
! 20:
! 21: You should have received a copy of the GNU Library General Public
! 22: License along with this library; if not, write to the Free Software
! 23: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
! 24: 02111-1307 USA
! 25: */
! 26:
! 27: #define _LTDL_COMPILE_
! 28:
! 29: #include "config.h"
! 30:
! 31: #if HAVE_STRING_H
! 32: #include <string.h>
! 33: #endif
! 34:
! 35: #if HAVE_STRINGS_H
! 36: #include <strings.h>
! 37: #endif
! 38:
! 39: #if HAVE_CTYPE_H
! 40: #include <ctype.h>
! 41: #endif
! 42:
! 43: #if HAVE_MALLOC_H
! 44: #include <malloc.h>
! 45: #endif
! 46:
! 47: #if HAVE_MEMORY_H
! 48: #include <memory.h>
! 49: #endif
! 50:
! 51: #if HAVE_STDLIB_H
! 52: #include <stdlib.h>
! 53: #endif
! 54:
! 55: #if HAVE_STDIO_H
! 56: #include <stdio.h>
! 57: #endif
! 58:
! 59: #include "ltdl.h"
! 60:
! 61: /* max. filename length */
! 62: #ifndef LTDL_FILENAME_MAX
! 63: #define LTDL_FILENAME_MAX 1024
! 64: #endif
! 65:
! 66: #undef LTDL_READTEXT_MODE
! 67: /* fopen() mode flags for reading a text file */
! 68: #ifdef _WIN32
! 69: #define LTDL_READTEXT_MODE "rt"
! 70: #else
! 71: #define LTDL_READTEXT_MODE "r"
! 72: #endif
! 73:
! 74: #undef LTDL_SYMBOL_LENGTH
! 75: /* This is the maximum symbol size that won't require malloc/free */
! 76: #define LTDL_SYMBOL_LENGTH 128
! 77:
! 78: #undef LTDL_SYMBOL_OVERHEAD
! 79: /* This accounts for the _LTX_ separator */
! 80: #define LTDL_SYMBOL_OVERHEAD 5
! 81:
! 82: static const char objdir[] = LTDL_OBJDIR;
! 83: #ifdef LTDL_SHLIB_EXT
! 84: static const char shlib_ext[] = LTDL_SHLIB_EXT;
! 85: #endif
! 86:
! 87: static const char unknown_error[] = "unknown error";
! 88: static const char dlopen_not_supported_error[] = "dlopen support not available";
! 89: static const char file_not_found_error[] = "file not found";
! 90: static const char no_symbols_error[] = "no symbols defined";
! 91: static const char cannot_open_error[] = "can't open the module";
! 92: static const char cannot_close_error[] = "can't close the module";
! 93: static const char symbol_error[] = "symbol not found";
! 94: static const char memory_error[] = "not enough memory";
! 95: static const char invalid_handle_error[] = "invalid handle";
! 96: static const char buffer_overflow_error[] = "internal buffer overflow";
! 97: static const char shutdown_error[] = "library already shutdown";
! 98:
! 99: #ifndef HAVE_PRELOADED_SYMBOLS
! 100: /* If libtool won't define it, we'd better do */
! 101: const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
! 102: #endif
! 103:
! 104: static const char *last_error = 0;
! 105:
! 106: lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
! 107: void (*lt_dlfree) LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
! 108:
! 109: typedef struct lt_dltype_t {
! 110: struct lt_dltype_t *next;
! 111: const char *sym_prefix; /* prefix for symbols */
! 112: int (*mod_init) LTDL_PARAMS((void));
! 113: int (*mod_exit) LTDL_PARAMS((void));
! 114: int (*lib_open) LTDL_PARAMS((lt_dlhandle handle, const char *filename));
! 115: int (*lib_close) LTDL_PARAMS((lt_dlhandle handle));
! 116: lt_ptr_t (*find_sym) LTDL_PARAMS((lt_dlhandle handle, const char *symbol));
! 117: } lt_dltype_t;
! 118:
! 119: #define LTDL_TYPE_TOP 0
! 120:
! 121: typedef struct lt_dlhandle_t {
! 122: struct lt_dlhandle_t *next;
! 123: lt_dltype_t *type; /* dlopening interface */
! 124: char *filename; /* file name */
! 125: char *name; /* module name */
! 126: int usage; /* usage */
! 127: int depcount; /* number of dependencies */
! 128: lt_dlhandle *deplibs; /* dependencies */
! 129: lt_ptr_t handle; /* system handle */
! 130: lt_ptr_t system; /* system specific data */
! 131: } lt_dlhandle_t;
! 132:
! 133: #undef strdup
! 134: #define strdup xstrdup
! 135:
! 136: static inline char *
! 137: strdup(str)
! 138: const char *str;
! 139: {
! 140: char *tmp;
! 141:
! 142: if (!str)
! 143: return 0;
! 144: tmp = (char*) lt_dlmalloc(strlen(str)+1);
! 145: if (tmp)
! 146: strcpy(tmp, str);
! 147: return tmp;
! 148: }
! 149:
! 150: #if ! HAVE_STRCHR
! 151:
! 152: # if HAVE_INDEX
! 153:
! 154: # define strchr index
! 155:
! 156: # else
! 157:
! 158: # define strchr xstrchr
! 159:
! 160: static inline const char*
! 161: strchr(str, ch)
! 162: const char *str;
! 163: int ch;
! 164: {
! 165: const char *p;
! 166:
! 167: for (p = str; *p != (char)ch && *p != '\0'; p++)
! 168: /*NOWORK*/;
! 169:
! 170: return (*p == (char)ch) ? p : 0;
! 171: }
! 172:
! 173: # endif
! 174:
! 175: #endif
! 176:
! 177: #if ! HAVE_STRRCHR
! 178:
! 179: # if HAVE_RINDEX
! 180:
! 181: # define strrchr rindex
! 182:
! 183: # else
! 184:
! 185: # define strrchr xstrrchr
! 186:
! 187: static inline const char*
! 188: strrchr(str, ch)
! 189: const char *str;
! 190: int ch;
! 191: {
! 192: const char *p;
! 193:
! 194: for (p = str; *p != '\0'; p++)
! 195: /*NOWORK*/;
! 196:
! 197: while (*p != (char)ch && p >= str)
! 198: p--;
! 199:
! 200: return (*p == (char)ch) ? p : 0;
! 201: }
! 202:
! 203: # endif
! 204:
! 205: #endif
! 206:
! 207: #if HAVE_LIBDL
! 208:
! 209: /* dynamic linking with dlopen/dlsym */
! 210:
! 211: #if HAVE_DLFCN_H
! 212: # include <dlfcn.h>
! 213: #endif
! 214:
! 215: #ifdef RTLD_GLOBAL
! 216: # define LTDL_GLOBAL RTLD_GLOBAL
! 217: #else
! 218: # ifdef DL_GLOBAL
! 219: # define LTDL_GLOBAL DL_GLOBAL
! 220: # else
! 221: # define LTDL_GLOBAL 0
! 222: # endif
! 223: #endif
! 224:
! 225: /* We may have to define LTDL_LAZY_OR_NOW in the command line if we
! 226: find out it does not work in some platform. */
! 227: #ifndef LTDL_LAZY_OR_NOW
! 228: # ifdef RTLD_LAZY
! 229: # define LTDL_LAZY_OR_NOW RTLD_LAZY
! 230: # else
! 231: # ifdef DL_LAZY
! 232: # define LTDL_LAZY_OR_NOW DL_LAZY
! 233: # else
! 234: # ifdef RTLD_NOW
! 235: # define LTDL_LAZY_OR_NOW RTLD_NOW
! 236: # else
! 237: # ifdef DL_NOW
! 238: # define LTDL_LAZY_OR_NOW DL_NOW
! 239: # else
! 240: # define LTDL_LAZY_OR_NOW 0
! 241: # endif
! 242: # endif
! 243: # endif
! 244: # endif
! 245: #endif
! 246:
! 247: static int
! 248: sys_dl_init LTDL_PARAMS((void))
! 249: {
! 250: return 0;
! 251: }
! 252:
! 253: static int
! 254: sys_dl_exit LTDL_PARAMS((void))
! 255: {
! 256: return 0;
! 257: }
! 258:
! 259: static int
! 260: sys_dl_open (handle, filename)
! 261: lt_dlhandle handle;
! 262: const char *filename;
! 263: {
! 264: handle->handle = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
! 265: if (!handle->handle) {
! 266: #if HAVE_DLERROR
! 267: last_error = dlerror();
! 268: #else
! 269: last_error = cannot_open_error;
! 270: #endif
! 271: return 1;
! 272: }
! 273: return 0;
! 274: }
! 275:
! 276: static int
! 277: sys_dl_close (handle)
! 278: lt_dlhandle handle;
! 279: {
! 280: if (dlclose(handle->handle) != 0) {
! 281: #if HAVE_DLERROR
! 282: last_error = dlerror();
! 283: #else
! 284: last_error = cannot_close_error;
! 285: #endif
! 286: return 1;
! 287: }
! 288: return 0;
! 289: }
! 290:
! 291: static lt_ptr_t
! 292: sys_dl_sym (handle, symbol)
! 293: lt_dlhandle handle;
! 294: const char *symbol;
! 295: {
! 296: lt_ptr_t address = dlsym(handle->handle, symbol);
! 297:
! 298: if (!address)
! 299: #if HAVE_DLERROR
! 300: last_error = dlerror();
! 301: #else
! 302: last_error = symbol_error;
! 303: #endif
! 304: return address;
! 305: }
! 306:
! 307: static
! 308: lt_dltype_t
! 309: #ifdef NEED_USCORE
! 310: sys_dl = { LTDL_TYPE_TOP, "_", sys_dl_init, sys_dl_exit,
! 311: sys_dl_open, sys_dl_close, sys_dl_sym };
! 312: #else
! 313: sys_dl = { LTDL_TYPE_TOP, 0, sys_dl_init, sys_dl_exit,
! 314: sys_dl_open, sys_dl_close, sys_dl_sym };
! 315: #endif
! 316:
! 317: #undef LTDL_TYPE_TOP
! 318: #define LTDL_TYPE_TOP &sys_dl
! 319:
! 320: #endif
! 321:
! 322: #if HAVE_SHL_LOAD
! 323:
! 324: /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
! 325:
! 326: #ifdef HAVE_DL_H
! 327: #include <dl.h>
! 328: #endif
! 329:
! 330: /* some flags are missing on some systems, so we provide
! 331: * harmless defaults.
! 332: *
! 333: * Mandatory:
! 334: * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
! 335: * BIND_DEFERRED - Delay code symbol resolution until actual reference.
! 336: *
! 337: * Optionally:
! 338: * BIND_FIRST - Place the library at the head of the symbol search order.
! 339: * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all unsatisfied
! 340: * symbols as fatal. This flag allows binding of unsatisfied code
! 341: * symbols to be deferred until use.
! 342: * [Perl: For certain libraries, like DCE, deferred binding often
! 343: * causes run time problems. Adding BIND_NONFATAL to BIND_IMMEDIATE
! 344: * still allows unresolved references in situations like this.]
! 345: * BIND_NOSTART - Do not call the initializer for the shared library when the
! 346: * library is loaded, nor on a future call to shl_unload().
! 347: * BIND_VERBOSE - Print verbose messages concerning possible unsatisfied symbols.
! 348: *
! 349: * hp9000s700/hp9000s800:
! 350: * BIND_RESTRICTED - Restrict symbols visible by the library to those present at
! 351: * library load time.
! 352: * DYNAMIC_PATH - Allow the loader to dynamically search for the library specified
! 353: * by the path argument.
! 354: */
! 355:
! 356: #ifndef DYNAMIC_PATH
! 357: #define DYNAMIC_PATH 0
! 358: #endif /* DYNAMIC_PATH */
! 359: #ifndef BIND_RESTRICTED
! 360: #define BIND_RESTRICTED 0
! 361: #endif /* BIND_RESTRICTED */
! 362:
! 363: #define LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
! 364:
! 365: static int
! 366: sys_shl_init LTDL_PARAMS((void))
! 367: {
! 368: return 0;
! 369: }
! 370:
! 371: static int
! 372: sys_shl_exit LTDL_PARAMS((void))
! 373: {
! 374: return 0;
! 375: }
! 376:
! 377: static int
! 378: sys_shl_open (handle, filename)
! 379: lt_dlhandle handle;
! 380: const char *filename;
! 381: {
! 382: handle->handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
! 383: if (!handle->handle) {
! 384: last_error = cannot_open_error;
! 385: return 1;
! 386: }
! 387: return 0;
! 388: }
! 389:
! 390: static int
! 391: sys_shl_close (handle)
! 392: lt_dlhandle handle;
! 393: {
! 394: if (shl_unload((shl_t) (handle->handle)) != 0) {
! 395: last_error = cannot_close_error;
! 396: return 1;
! 397: }
! 398: return 0;
! 399: }
! 400:
! 401: static lt_ptr_t
! 402: sys_shl_sym (handle, symbol)
! 403: lt_dlhandle handle;
! 404: const char *symbol;
! 405: {
! 406: lt_ptr_t address;
! 407:
! 408: if (handle->handle && shl_findsym((shl_t*) &(handle->handle),
! 409: symbol, TYPE_UNDEFINED, &address) == 0)
! 410: if (address)
! 411: return address;
! 412: last_error = symbol_error;
! 413: return 0;
! 414: }
! 415:
! 416: static
! 417: lt_dltype_t
! 418: sys_shl = { LTDL_TYPE_TOP, 0, sys_shl_init, sys_shl_exit,
! 419: sys_shl_open, sys_shl_close, sys_shl_sym };
! 420:
! 421: #undef LTDL_TYPE_TOP
! 422: #define LTDL_TYPE_TOP &sys_shl
! 423:
! 424: #endif
! 425:
! 426: #if HAVE_DLD
! 427:
! 428: /* dynamic linking with dld */
! 429:
! 430: #if HAVE_DLD_H
! 431: #include <dld.h>
! 432: #endif
! 433:
! 434: static int
! 435: sys_dld_init LTDL_PARAMS((void))
! 436: {
! 437: return 0;
! 438: }
! 439:
! 440: static int
! 441: sys_dld_exit LTDL_PARAMS((void))
! 442: {
! 443: return 0;
! 444: }
! 445:
! 446: static int
! 447: sys_dld_open (handle, filename)
! 448: lt_dlhandle handle;
! 449: const char *filename;
! 450: {
! 451: handle->handle = strdup(filename);
! 452: if (!handle->handle) {
! 453: last_error = memory_error;
! 454: return 1;
! 455: }
! 456: if (dld_link(filename) != 0) {
! 457: last_error = cannot_open_error;
! 458: lt_dlfree(handle->handle);
! 459: return 1;
! 460: }
! 461: return 0;
! 462: }
! 463:
! 464: static int
! 465: sys_dld_close (handle)
! 466: lt_dlhandle handle;
! 467: {
! 468: if (dld_unlink_by_file((char*)(handle->handle), 1) != 0) {
! 469: last_error = cannot_close_error;
! 470: return 1;
! 471: }
! 472: lt_dlfree(handle->filename);
! 473: return 0;
! 474: }
! 475:
! 476: static lt_ptr_t
! 477: sys_dld_sym (handle, symbol)
! 478: lt_dlhandle handle;
! 479: const char *symbol;
! 480: {
! 481: lt_ptr_t address = dld_get_func(symbol);
! 482:
! 483: if (!address)
! 484: last_error = symbol_error;
! 485: return address;
! 486: }
! 487:
! 488: static
! 489: lt_dltype_t
! 490: sys_dld = { LTDL_TYPE_TOP, 0, sys_dld_init, sys_dld_exit,
! 491: sys_dld_open, sys_dld_close, sys_dld_sym };
! 492:
! 493: #undef LTDL_TYPE_TOP
! 494: #define LTDL_TYPE_TOP &sys_dld
! 495:
! 496: #endif
! 497:
! 498: #ifdef _WIN32
! 499:
! 500: /* dynamic linking for Win32 */
! 501:
! 502: #include <windows.h>
! 503:
! 504: static int
! 505: sys_wll_init LTDL_PARAMS((void))
! 506: {
! 507: return 0;
! 508: }
! 509:
! 510: static int
! 511: sys_wll_exit LTDL_PARAMS((void))
! 512: {
! 513: return 0;
! 514: }
! 515:
! 516: /* Forward declaration; required to implement handle search below. */
! 517: static lt_dlhandle handles;
! 518:
! 519: static int
! 520: sys_wll_open (handle, filename)
! 521: lt_dlhandle handle;
! 522: const char *filename;
! 523: {
! 524: lt_dlhandle cur;
! 525: char *searchname = NULL;
! 526: char *ext = strrchr(filename, '.');
! 527:
! 528: if (ext) {
! 529: /* FILENAME already has an extension. */
! 530: searchname = strdup(filename);
! 531: } else {
! 532: /* Append a `.' to stop Windows from adding an
! 533: implicit `.dll' extension. */
! 534: searchname = (char*)lt_dlmalloc(2+ strlen(filename));
! 535: strcpy(searchname, filename);
! 536: strcat(searchname, ".");
! 537: }
! 538:
! 539: handle->handle = LoadLibrary(searchname);
! 540: lt_dlfree(searchname);
! 541:
! 542: /* libltdl expects this function to fail if it is unable
! 543: to physically load the library. Sadly, LoadLibrary
! 544: will search the loaded libraries for a match and return
! 545: one of them if the path search load fails.
! 546:
! 547: We check whether LoadLibrary is returning a handle to
! 548: an already loaded module, and simulate failure if we
! 549: find one. */
! 550: cur = handles;
! 551: while (cur) {
! 552: if (!cur->handle) {
! 553: cur = 0;
! 554: break;
! 555: }
! 556: if (cur->handle == handle->handle)
! 557: break;
! 558: cur = cur->next;
! 559: }
! 560:
! 561: if (cur || !handle->handle) {
! 562: last_error = cannot_open_error;
! 563: return 1;
! 564: }
! 565:
! 566: return 0;
! 567: }
! 568:
! 569: static int
! 570: sys_wll_close (handle)
! 571: lt_dlhandle handle;
! 572: {
! 573: if (FreeLibrary(handle->handle) == 0) {
! 574: last_error = cannot_close_error;
! 575: return 1;
! 576: }
! 577: return 0;
! 578: }
! 579:
! 580: static lt_ptr_t
! 581: sys_wll_sym (handle, symbol)
! 582: lt_dlhandle handle;
! 583: const char *symbol;
! 584: {
! 585: lt_ptr_t address = GetProcAddress(handle->handle, symbol);
! 586:
! 587: if (!address)
! 588: last_error = symbol_error;
! 589: return address;
! 590: }
! 591:
! 592: static
! 593: lt_dltype_t
! 594: sys_wll = { LTDL_TYPE_TOP, 0, sys_wll_init, sys_wll_exit,
! 595: sys_wll_open, sys_wll_close, sys_wll_sym };
! 596:
! 597: #undef LTDL_TYPE_TOP
! 598: #define LTDL_TYPE_TOP &sys_wll
! 599:
! 600: #endif
! 601:
! 602: #ifdef __BEOS__
! 603:
! 604: /* dynamic linking for BeOS */
! 605:
! 606: #include <kernel/image.h>
! 607:
! 608: static int
! 609: sys_bedl_init LTDL_PARAMS((void))
! 610: {
! 611: return 0;
! 612: }
! 613:
! 614: static int
! 615: sys_bedl_exit LTDL_PARAMS((void))
! 616: {
! 617: return 0;
! 618: }
! 619:
! 620: static int
! 621: sys_bedl_open (handle, filename)
! 622: lt_dlhandle handle;
! 623: const char *filename;
! 624: {
! 625: image_id image = 0;
! 626:
! 627: if (filename) {
! 628: image = load_add_on(filename);
! 629: } else {
! 630: image_info info;
! 631: int32 cookie = 0;
! 632: if (get_next_image_info(0, &cookie, &info) == B_OK)
! 633: image = load_add_on(info.name);
! 634: }
! 635: if (image <= 0) {
! 636: last_error = cannot_open_error;
! 637: return 1;
! 638: }
! 639: handle->handle = (void*) image;
! 640: return 0;
! 641: }
! 642:
! 643: static int
! 644: sys_bedl_close (handle)
! 645: lt_dlhandle handle;
! 646: {
! 647: if (unload_add_on((image_id)handle->handle) != B_OK) {
! 648: last_error = cannot_close_error;
! 649: return 1;
! 650: }
! 651: return 0;
! 652: }
! 653:
! 654: static lt_ptr_t
! 655: sys_bedl_sym (handle, symbol)
! 656: lt_dlhandle handle;
! 657: const char *symbol;
! 658: {
! 659: lt_ptr_t address = 0;
! 660: image_id image = (image_id)handle->handle;
! 661:
! 662: if (get_image_symbol(image, symbol, B_SYMBOL_TYPE_ANY,
! 663: &address) != B_OK) {
! 664: last_error = symbol_error;
! 665: return 0;
! 666: }
! 667: return address;
! 668: }
! 669:
! 670: static
! 671: lt_dltype_t
! 672: sys_bedl = { LTDL_TYPE_TOP, 0, sys_bedl_init, sys_bedl_exit,
! 673: sys_bedl_open, sys_bedl_close, sys_bedl_sym };
! 674:
! 675: #undef LTDL_TYPE_TOP
! 676: #define LTDL_TYPE_TOP &sys_bedl
! 677:
! 678: #endif
! 679:
! 680: /* emulate dynamic linking using preloaded_symbols */
! 681:
! 682: typedef struct lt_dlsymlists_t {
! 683: struct lt_dlsymlists_t *next;
! 684: const lt_dlsymlist *syms;
! 685: } lt_dlsymlists_t;
! 686:
! 687: static const lt_dlsymlist *default_preloaded_symbols = 0;
! 688: static lt_dlsymlists_t *preloaded_symbols = 0;
! 689:
! 690: static int
! 691: presym_init LTDL_PARAMS((void))
! 692: {
! 693: preloaded_symbols = 0;
! 694: if (default_preloaded_symbols)
! 695: return lt_dlpreload(default_preloaded_symbols);
! 696: return 0;
! 697: }
! 698:
! 699: static int
! 700: presym_free_symlists LTDL_PARAMS((void))
! 701: {
! 702: lt_dlsymlists_t *lists = preloaded_symbols;
! 703:
! 704: while (lists) {
! 705: lt_dlsymlists_t *tmp = lists;
! 706:
! 707: lists = lists->next;
! 708: lt_dlfree(tmp);
! 709: }
! 710: preloaded_symbols = 0;
! 711: return 0;
! 712: }
! 713:
! 714: static int
! 715: presym_exit LTDL_PARAMS((void))
! 716: {
! 717: presym_free_symlists();
! 718: return 0;
! 719: }
! 720:
! 721: static int
! 722: presym_add_symlist (preloaded)
! 723: const lt_dlsymlist *preloaded;
! 724: {
! 725: lt_dlsymlists_t *tmp;
! 726: lt_dlsymlists_t *lists = preloaded_symbols;
! 727:
! 728: while (lists) {
! 729: if (lists->syms == preloaded)
! 730: return 0;
! 731: lists = lists->next;
! 732: }
! 733:
! 734: tmp = (lt_dlsymlists_t*) lt_dlmalloc(sizeof(lt_dlsymlists_t));
! 735: if (!tmp) {
! 736: last_error = memory_error;
! 737: return 1;
! 738: }
! 739: tmp->syms = preloaded;
! 740: tmp->next = 0;
! 741: if (!preloaded_symbols)
! 742: preloaded_symbols = tmp;
! 743: else {
! 744: /* append to the end */
! 745: lists = preloaded_symbols;
! 746: while (lists->next)
! 747: lists = lists->next;
! 748: lists->next = tmp;
! 749: }
! 750: return 0;
! 751: }
! 752:
! 753: static int
! 754: presym_open (handle, filename)
! 755: lt_dlhandle handle;
! 756: const char *filename;
! 757: {
! 758: lt_dlsymlists_t *lists = preloaded_symbols;
! 759:
! 760: if (!lists) {
! 761: last_error = no_symbols_error;
! 762: return 1;
! 763: }
! 764: if (!filename)
! 765: filename = "@PROGRAM@";
! 766: while (lists) {
! 767: const lt_dlsymlist *syms = lists->syms;
! 768:
! 769: while (syms->name) {
! 770: if (!syms->address &&
! 771: strcmp(syms->name, filename) == 0) {
! 772: handle->handle = (lt_ptr_t) syms;
! 773: return 0;
! 774: }
! 775: syms++;
! 776: }
! 777: lists = lists->next;
! 778: }
! 779: last_error = file_not_found_error;
! 780: return 1;
! 781: }
! 782:
! 783: static int
! 784: presym_close (handle)
! 785: lt_dlhandle handle;
! 786: {
! 787: /* Just to silence gcc -Wall */
! 788: handle = 0;
! 789: return 0;
! 790: }
! 791:
! 792: static lt_ptr_t
! 793: presym_sym (handle, symbol)
! 794: lt_dlhandle handle;
! 795: const char *symbol;
! 796: {
! 797: lt_dlsymlist *syms = (lt_dlsymlist*)(handle->handle);
! 798:
! 799: syms++;
! 800: while (syms->address) {
! 801: if (strcmp(syms->name, symbol) == 0)
! 802: return syms->address;
! 803: syms++;
! 804: }
! 805: last_error = symbol_error;
! 806: return 0;
! 807: }
! 808:
! 809: static
! 810: lt_dltype_t
! 811: presym = { LTDL_TYPE_TOP, 0, presym_init, presym_exit,
! 812: presym_open, presym_close, presym_sym };
! 813:
! 814: #undef LTDL_TYPE_TOP
! 815: #define LTDL_TYPE_TOP &presym
! 816:
! 817: static char *user_search_path = 0;
! 818: static lt_dlhandle handles = 0;
! 819: static int initialized = 0;
! 820:
! 821: static lt_dltype_t *types = LTDL_TYPE_TOP;
! 822: #undef LTDL_TYPE_TOP
! 823:
! 824: int
! 825: lt_dlinit LTDL_PARAMS((void))
! 826: {
! 827: /* initialize libltdl */
! 828: lt_dltype_t **type = &types;
! 829: int typecount = 0;
! 830:
! 831: if (initialized) { /* Initialize only at first call. */
! 832: initialized++;
! 833: return 0;
! 834: }
! 835: handles = 0;
! 836: user_search_path = 0; /* empty search path */
! 837:
! 838: while (*type) {
! 839: if ((*type)->mod_init())
! 840: *type = (*type)->next; /* Remove it from the list */
! 841: else {
! 842: type = &(*type)->next; /* Keep it */
! 843: typecount++;
! 844: }
! 845: }
! 846: if (typecount == 0) {
! 847: last_error = dlopen_not_supported_error;
! 848: return 1;
! 849: }
! 850: last_error = 0;
! 851: initialized = 1;
! 852: return 0;
! 853: }
! 854:
! 855: int
! 856: lt_dlpreload (preloaded)
! 857: const lt_dlsymlist *preloaded;
! 858: {
! 859: if (preloaded)
! 860: return presym_add_symlist(preloaded);
! 861: presym_free_symlists();
! 862: if (default_preloaded_symbols)
! 863: return lt_dlpreload(default_preloaded_symbols);
! 864: return 0;
! 865: }
! 866:
! 867: int
! 868: lt_dlpreload_default (preloaded)
! 869: const lt_dlsymlist *preloaded;
! 870: {
! 871: default_preloaded_symbols = preloaded;
! 872: return 0;
! 873: }
! 874:
! 875: int
! 876: lt_dlexit LTDL_PARAMS((void))
! 877: {
! 878: /* shut down libltdl */
! 879: lt_dltype_t *type = types;
! 880: int errors;
! 881:
! 882: if (!initialized) {
! 883: last_error = shutdown_error;
! 884: return 1;
! 885: }
! 886: if (initialized != 1) { /* shut down only at last call. */
! 887: initialized--;
! 888: return 0;
! 889: }
! 890: /* close all modules */
! 891: errors = 0;
! 892: while (handles) {
! 893: /* FIXME: what if a module depends on another one? */
! 894: if (lt_dlclose(handles))
! 895: errors++;
! 896: }
! 897: initialized = 0;
! 898: while (type) {
! 899: if (type->mod_exit())
! 900: errors++;
! 901: type = type->next;
! 902: }
! 903: return errors;
! 904: }
! 905:
! 906: static int
! 907: tryall_dlopen (handle, filename)
! 908: lt_dlhandle *handle;
! 909: const char *filename;
! 910: {
! 911: lt_dlhandle cur;
! 912: lt_dltype_t *type = types;
! 913: const char *saved_error = last_error;
! 914:
! 915: /* check whether the module was already opened */
! 916: cur = handles;
! 917: while (cur) {
! 918: if (!cur->filename && !filename)
! 919: break;
! 920: if (cur->filename && filename &&
! 921: strcmp(cur->filename, filename) == 0)
! 922: break;
! 923: cur = cur->next;
! 924: }
! 925: if (cur) {
! 926: cur->usage++;
! 927: *handle = cur;
! 928: return 0;
! 929: }
! 930:
! 931: cur = *handle;
! 932: if (filename) {
! 933: cur->filename = strdup(filename);
! 934: if (!cur->filename) {
! 935: last_error = memory_error;
! 936: return 1;
! 937: }
! 938: } else
! 939: cur->filename = 0;
! 940: while (type) {
! 941: if (type->lib_open(cur, filename) == 0)
! 942: break;
! 943: type = type->next;
! 944: }
! 945: if (!type) {
! 946: if (cur->filename)
! 947: lt_dlfree(cur->filename);
! 948: return 1;
! 949: }
! 950: cur->type = type;
! 951: last_error = saved_error;
! 952: return 0;
! 953: }
! 954:
! 955: static int
! 956: find_module (handle, dir, libdir, dlname, old_name, installed)
! 957: lt_dlhandle *handle;
! 958: const char *dir;
! 959: const char *libdir;
! 960: const char *dlname;
! 961: const char *old_name;
! 962: int installed;
! 963: {
! 964: int error;
! 965: char *filename;
! 966: /* try to open the old library first; if it was dlpreopened,
! 967: we want the preopened version of it, even if a dlopenable
! 968: module is available */
! 969: if (old_name && tryall_dlopen(handle, old_name) == 0)
! 970: return 0;
! 971: /* try to open the dynamic library */
! 972: if (dlname) {
! 973: /* try to open the installed module */
! 974: if (installed && libdir) {
! 975: filename = (char*)
! 976: lt_dlmalloc(strlen(libdir)+1+strlen(dlname)+1);
! 977: if (!filename) {
! 978: last_error = memory_error;
! 979: return 1;
! 980: }
! 981: strcpy(filename, libdir);
! 982: strcat(filename, "/");
! 983: strcat(filename, dlname);
! 984: error = tryall_dlopen(handle, filename) == 0;
! 985: lt_dlfree(filename);
! 986: if (error)
! 987: return 0;
! 988: }
! 989: /* try to open the not-installed module */
! 990: if (!installed) {
! 991: filename = (char*)
! 992: lt_dlmalloc((dir ? strlen(dir) : 0)
! 993: + strlen(objdir) + strlen(dlname) + 1);
! 994: if (!filename) {
! 995: last_error = memory_error;
! 996: return 1;
! 997: }
! 998: if (dir)
! 999: strcpy(filename, dir);
! 1000: else
! 1001: *filename = 0;
! 1002: strcat(filename, objdir);
! 1003: strcat(filename, dlname);
! 1004:
! 1005: error = tryall_dlopen(handle, filename) == 0;
! 1006: lt_dlfree(filename);
! 1007: if (error)
! 1008: return 0;
! 1009: }
! 1010: /* hmm, maybe it was moved to another directory */
! 1011: {
! 1012: filename = (char*)
! 1013: lt_dlmalloc((dir ? strlen(dir) : 0)
! 1014: + strlen(dlname) + 1);
! 1015: if (dir)
! 1016: strcpy(filename, dir);
! 1017: else
! 1018: *filename = 0;
! 1019: strcat(filename, dlname);
! 1020: error = tryall_dlopen(handle, filename) == 0;
! 1021: lt_dlfree(filename);
! 1022: if (error)
! 1023: return 0;
! 1024: }
! 1025: }
! 1026: last_error = file_not_found_error;
! 1027: return 1;
! 1028: }
! 1029:
! 1030: static lt_ptr_t
! 1031: find_file (basename, search_path, pdir, handle)
! 1032: const char *basename;
! 1033: const char *search_path;
! 1034: char **pdir;
! 1035: lt_dlhandle *handle;
! 1036: {
! 1037: /* when handle != NULL search a library, otherwise a file */
! 1038: /* return NULL on failure, otherwise the file/handle */
! 1039:
! 1040: char *filename = 0;
! 1041: int filenamesize = 0;
! 1042: const char *next = search_path;
! 1043: int lenbase = strlen(basename);
! 1044:
! 1045: if (!next || !*next) {
! 1046: last_error = file_not_found_error;
! 1047: return 0;
! 1048: }
! 1049: while (next) {
! 1050: int lendir;
! 1051: const char *cur = next;
! 1052:
! 1053: next = strchr(cur, ':');
! 1054: if (!next)
! 1055: next = cur + strlen(cur);
! 1056: lendir = next - cur;
! 1057: if (*next == ':')
! 1058: ++next;
! 1059: else
! 1060: next = 0;
! 1061: if (lendir == 0)
! 1062: continue;
! 1063: if (lendir + 1 + lenbase >= filenamesize) {
! 1064: if (filename)
! 1065: lt_dlfree(filename);
! 1066: filenamesize = lendir + 1 + lenbase + 1;
! 1067: filename = (char*) lt_dlmalloc(filenamesize);
! 1068: if (!filename) {
! 1069: last_error = memory_error;
! 1070: return 0;
! 1071: }
! 1072: }
! 1073: strncpy(filename, cur, lendir);
! 1074: if (filename[lendir-1] != '/')
! 1075: filename[lendir++] = '/';
! 1076: strcpy(filename+lendir, basename);
! 1077: if (handle) {
! 1078: if (tryall_dlopen(handle, filename) == 0) {
! 1079: lt_dlfree(filename);
! 1080: return (lt_ptr_t) handle;
! 1081: }
! 1082: } else {
! 1083: FILE *file = fopen(filename, LTDL_READTEXT_MODE);
! 1084: if (file) {
! 1085: if (*pdir)
! 1086: lt_dlfree(*pdir);
! 1087: filename[lendir] = '\0';
! 1088: *pdir = strdup(filename);
! 1089: if (!*pdir) {
! 1090: /* We could have even avoided the
! 1091: strdup, but there would be some
! 1092: memory overhead. */
! 1093: *pdir = filename;
! 1094: } else
! 1095: lt_dlfree(filename);
! 1096: return (lt_ptr_t) file;
! 1097: }
! 1098: }
! 1099: }
! 1100: if (filename)
! 1101: lt_dlfree(filename);
! 1102: last_error = file_not_found_error;
! 1103: return 0;
! 1104: }
! 1105:
! 1106: static int
! 1107: load_deplibs(handle, deplibs)
! 1108: lt_dlhandle handle;
! 1109: const char *deplibs;
! 1110: {
! 1111: /* FIXME: load deplibs */
! 1112: handle->depcount = 0;
! 1113: handle->deplibs = 0;
! 1114: /* Just to silence gcc -Wall */
! 1115: deplibs = 0;
! 1116: return 0;
! 1117: }
! 1118:
! 1119: static int
! 1120: unload_deplibs(handle)
! 1121: lt_dlhandle handle;
! 1122: {
! 1123: /* FIXME: unload deplibs */
! 1124: /* Just to silence gcc -Wall */
! 1125: handle = 0;
! 1126: return 0;
! 1127: }
! 1128:
! 1129: static inline int
! 1130: trim (dest, str)
! 1131: char **dest;
! 1132: const char *str;
! 1133: {
! 1134: /* remove the leading and trailing "'" from str
! 1135: and store the result in dest */
! 1136: char *tmp;
! 1137: const char *end = strrchr(str, '\'');
! 1138: int len = strlen(str);
! 1139:
! 1140: if (*dest)
! 1141: lt_dlfree(*dest);
! 1142: if (len > 3 && str[0] == '\'') {
! 1143: tmp = (char*) lt_dlmalloc(end - str);
! 1144: if (!tmp) {
! 1145: last_error = memory_error;
! 1146: return 1;
! 1147: }
! 1148: strncpy(tmp, &str[1], (end - str) - 1);
! 1149: tmp[len-3] = '\0';
! 1150: *dest = tmp;
! 1151: } else
! 1152: *dest = 0;
! 1153: return 0;
! 1154: }
! 1155:
! 1156: static inline int
! 1157: free_vars(dir, name, dlname, oldname, libdir, deplibs)
! 1158: char *dir;
! 1159: char *name;
! 1160: char *dlname;
! 1161: char *oldname;
! 1162: char *libdir;
! 1163: char *deplibs;
! 1164: {
! 1165: if (dir)
! 1166: lt_dlfree(dir);
! 1167: if (name)
! 1168: lt_dlfree(name);
! 1169: if (dlname)
! 1170: lt_dlfree(dlname);
! 1171: if (oldname)
! 1172: lt_dlfree(oldname);
! 1173: if (libdir)
! 1174: lt_dlfree(libdir);
! 1175: if (deplibs)
! 1176: lt_dlfree(deplibs);
! 1177: return 0;
! 1178: }
! 1179:
! 1180: lt_dlhandle
! 1181: lt_dlopen (filename)
! 1182: const char *filename;
! 1183: {
! 1184: lt_dlhandle handle, newhandle;
! 1185: const char *basename, *ext;
! 1186: const char *saved_error = last_error;
! 1187: char *dir = 0, *name = 0;
! 1188:
! 1189: if (!filename) {
! 1190: handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
! 1191: if (!handle) {
! 1192: last_error = memory_error;
! 1193: return 0;
! 1194: }
! 1195: handle->usage = 0;
! 1196: handle->depcount = 0;
! 1197: handle->deplibs = 0;
! 1198: newhandle = handle;
! 1199: if (tryall_dlopen(&newhandle, 0) != 0) {
! 1200: lt_dlfree(handle);
! 1201: return 0;
! 1202: }
! 1203: goto register_handle;
! 1204: }
! 1205: basename = strrchr(filename, '/');
! 1206: if (basename) {
! 1207: basename++;
! 1208: dir = (char*) lt_dlmalloc(basename - filename + 1);
! 1209: if (!dir) {
! 1210: last_error = memory_error;
! 1211: return 0;
! 1212: }
! 1213: strncpy(dir, filename, basename - filename);
! 1214: dir[basename - filename] = '\0';
! 1215: } else
! 1216: basename = filename;
! 1217: /* check whether we open a libtool module (.la extension) */
! 1218: ext = strrchr(basename, '.');
! 1219: if (ext && strcmp(ext, ".la") == 0) {
! 1220: /* this seems to be a libtool module */
! 1221: FILE *file;
! 1222: int i;
! 1223: char *dlname = 0, *old_name = 0;
! 1224: char *libdir = 0, *deplibs = 0;
! 1225: char *line;
! 1226: int error = 0;
! 1227: /* if we can't find the installed flag, it is probably an
! 1228: installed libtool archive, produced with an old version
! 1229: of libtool */
! 1230: int installed = 1;
! 1231:
! 1232: /* extract the module name from the file name */
! 1233: name = (char*) lt_dlmalloc(ext - basename + 1);
! 1234: if (!name) {
! 1235: last_error = memory_error;
! 1236: if (dir)
! 1237: lt_dlfree(dir);
! 1238: return 0;
! 1239: }
! 1240: /* canonicalize the module name */
! 1241: for (i = 0; i < ext - basename; i++)
! 1242: if (isalnum((int)(basename[i])))
! 1243: name[i] = basename[i];
! 1244: else
! 1245: name[i] = '_';
! 1246: name[ext - basename] = '\0';
! 1247: /* now try to open the .la file */
! 1248: file = fopen(filename, LTDL_READTEXT_MODE);
! 1249: if (!file)
! 1250: last_error = file_not_found_error;
! 1251: if (!file && !dir) {
! 1252: /* try other directories */
! 1253: file = (FILE*) find_file(basename,
! 1254: user_search_path,
! 1255: &dir, 0);
! 1256: if (!file)
! 1257: file = (FILE*) find_file(basename,
! 1258: getenv("LTDL_LIBRARY_PATH"),
! 1259: &dir, 0);
! 1260: #ifdef LTDL_SHLIBPATH_VAR
! 1261: if (!file)
! 1262: file = (FILE*) find_file(basename,
! 1263: getenv(LTDL_SHLIBPATH_VAR),
! 1264: &dir, 0);
! 1265: #endif
! 1266: }
! 1267: if (!file) {
! 1268: if (name)
! 1269: lt_dlfree(name);
! 1270: if (dir)
! 1271: lt_dlfree(dir);
! 1272: return 0;
! 1273: }
! 1274: line = (char*) lt_dlmalloc(LTDL_FILENAME_MAX);
! 1275: if (!line) {
! 1276: fclose(file);
! 1277: last_error = memory_error;
! 1278: return 0;
! 1279: }
! 1280: /* read the .la file */
! 1281: while (!feof(file)) {
! 1282: if (!fgets(line, LTDL_FILENAME_MAX, file))
! 1283: break;
! 1284: if (line[0] == '\n' || line[0] == '#')
! 1285: continue;
! 1286: # undef STR_DLNAME
! 1287: # define STR_DLNAME "dlname="
! 1288: if (strncmp(line, STR_DLNAME,
! 1289: sizeof(STR_DLNAME) - 1) == 0)
! 1290: error = trim(&dlname,
! 1291: &line[sizeof(STR_DLNAME) - 1]);
! 1292: else
! 1293: # undef STR_OLD_LIBRARY
! 1294: # define STR_OLD_LIBRARY "old_library="
! 1295: if (strncmp(line, STR_OLD_LIBRARY,
! 1296: sizeof(STR_OLD_LIBRARY) - 1) == 0)
! 1297: error = trim(&old_name,
! 1298: &line[sizeof(STR_OLD_LIBRARY) - 1]);
! 1299: else
! 1300: # undef STR_LIBDIR
! 1301: # define STR_LIBDIR "libdir="
! 1302: if (strncmp(line, STR_LIBDIR,
! 1303: sizeof(STR_LIBDIR) - 1) == 0)
! 1304: error = trim(&libdir,
! 1305: &line[sizeof(STR_LIBDIR) - 1]);
! 1306: else
! 1307: # undef STR_DL_DEPLIBS
! 1308: # define STR_DL_DEPLIBS "dl_dependency_libs="
! 1309: if (strncmp(line, STR_DL_DEPLIBS,
! 1310: sizeof(STR_DL_DEPLIBS) - 1) == 0)
! 1311: error = trim(&deplibs,
! 1312: &line[sizeof(STR_DL_DEPLIBS) - 1]);
! 1313: else
! 1314: if (strcmp(line, "installed=yes\n") == 0)
! 1315: installed = 1;
! 1316: else
! 1317: if (strcmp(line, "installed=no\n") == 0)
! 1318: installed = 0;
! 1319: if (error)
! 1320: break;
! 1321: }
! 1322: fclose(file);
! 1323: lt_dlfree(line);
! 1324: /* allocate the handle */
! 1325: handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
! 1326: if (!handle || error) {
! 1327: if (handle)
! 1328: lt_dlfree(handle);
! 1329: if (!error)
! 1330: last_error = memory_error;
! 1331: free_vars(name, dir, dlname, old_name, libdir, deplibs);
! 1332: return 0;
! 1333: }
! 1334: handle->usage = 0;
! 1335: if (load_deplibs(handle, deplibs) == 0) {
! 1336: newhandle = handle;
! 1337: /* find_module may replace newhandle */
! 1338: if (find_module(&newhandle, dir, libdir,
! 1339: dlname, old_name, installed)) {
! 1340: unload_deplibs(handle);
! 1341: error = 1;
! 1342: }
! 1343: } else
! 1344: error = 1;
! 1345: if (error) {
! 1346: lt_dlfree(handle);
! 1347: free_vars(name, dir, dlname, old_name, libdir, deplibs);
! 1348: return 0;
! 1349: }
! 1350: if (handle != newhandle) {
! 1351: unload_deplibs(handle);
! 1352: }
! 1353: } else {
! 1354: /* not a libtool module */
! 1355: handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
! 1356: if (!handle) {
! 1357: last_error = memory_error;
! 1358: if (dir)
! 1359: lt_dlfree(dir);
! 1360: return 0;
! 1361: }
! 1362: handle->usage = 0;
! 1363: /* non-libtool modules don't have dependencies */
! 1364: handle->depcount = 0;
! 1365: handle->deplibs = 0;
! 1366: newhandle = handle;
! 1367: if (tryall_dlopen(&newhandle, filename)
! 1368: && (dir
! 1369: || (!find_file(basename, user_search_path,
! 1370: 0, &newhandle)
! 1371: && !find_file(basename,
! 1372: getenv("LTDL_LIBRARY_PATH"),
! 1373: 0, &newhandle)
! 1374: #ifdef LTDL_SHLIBPATH_VAR
! 1375: && !find_file(basename,
! 1376: getenv(LTDL_SHLIBPATH_VAR),
! 1377: 0, &newhandle)
! 1378: #endif
! 1379: ))) {
! 1380: lt_dlfree(handle);
! 1381: if (dir)
! 1382: lt_dlfree(dir);
! 1383: return 0;
! 1384: }
! 1385: }
! 1386: register_handle:
! 1387: if (newhandle != handle) {
! 1388: lt_dlfree(handle);
! 1389: handle = newhandle;
! 1390: }
! 1391: if (!handle->usage) {
! 1392: handle->usage = 1;
! 1393: handle->name = name;
! 1394: handle->next = handles;
! 1395: handles = handle;
! 1396: } else if (name)
! 1397: lt_dlfree(name);
! 1398: if (dir)
! 1399: lt_dlfree(dir);
! 1400: last_error = saved_error;
! 1401: return handle;
! 1402: }
! 1403:
! 1404: lt_dlhandle
! 1405: lt_dlopenext (filename)
! 1406: const char *filename;
! 1407: {
! 1408: lt_dlhandle handle;
! 1409: char *tmp;
! 1410: int len;
! 1411: const char *saved_error = last_error;
! 1412:
! 1413: if (!filename)
! 1414: return lt_dlopen(filename);
! 1415: len = strlen(filename);
! 1416: if (!len) {
! 1417: last_error = file_not_found_error;
! 1418: return 0;
! 1419: }
! 1420: /* try the normal file name */
! 1421: handle = lt_dlopen(filename);
! 1422: if (handle)
! 1423: return handle;
! 1424: /* try "filename.la" */
! 1425: tmp = (char*) lt_dlmalloc(len+4);
! 1426: if (!tmp) {
! 1427: last_error = memory_error;
! 1428: return 0;
! 1429: }
! 1430: strcpy(tmp, filename);
! 1431: strcat(tmp, ".la");
! 1432: handle = lt_dlopen(tmp);
! 1433: if (handle) {
! 1434: last_error = saved_error;
! 1435: lt_dlfree(tmp);
! 1436: return handle;
! 1437: }
! 1438: #ifdef LTDL_SHLIB_EXT
! 1439: /* try "filename.EXT" */
! 1440: if (strlen(shlib_ext) > 3) {
! 1441: lt_dlfree(tmp);
! 1442: tmp = (char*) lt_dlmalloc(len + strlen(shlib_ext) + 1);
! 1443: if (!tmp) {
! 1444: last_error = memory_error;
! 1445: return 0;
! 1446: }
! 1447: strcpy(tmp, filename);
! 1448: } else
! 1449: tmp[len] = '\0';
! 1450: strcat(tmp, shlib_ext);
! 1451: handle = lt_dlopen(tmp);
! 1452: if (handle) {
! 1453: last_error = saved_error;
! 1454: lt_dlfree(tmp);
! 1455: return handle;
! 1456: }
! 1457: #endif
! 1458: last_error = file_not_found_error;
! 1459: lt_dlfree(tmp);
! 1460: return 0;
! 1461: }
! 1462:
! 1463: int
! 1464: lt_dlclose (handle)
! 1465: lt_dlhandle handle;
! 1466: {
! 1467: lt_dlhandle cur, last;
! 1468:
! 1469: /* check whether the handle is valid */
! 1470: last = cur = handles;
! 1471: while (cur && handle != cur) {
! 1472: last = cur;
! 1473: cur = cur->next;
! 1474: }
! 1475: if (!cur) {
! 1476: last_error = invalid_handle_error;
! 1477: return 1;
! 1478: }
! 1479: handle->usage--;
! 1480: if (!handle->usage) {
! 1481: int error;
! 1482:
! 1483: if (handle != handles)
! 1484: last->next = handle->next;
! 1485: else
! 1486: handles = handle->next;
! 1487: error = handle->type->lib_close(handle);
! 1488: error += unload_deplibs(handle);
! 1489: if (handle->filename)
! 1490: lt_dlfree(handle->filename);
! 1491: if (handle->name)
! 1492: lt_dlfree(handle->name);
! 1493: lt_dlfree(handle);
! 1494: return error;
! 1495: }
! 1496: return 0;
! 1497: }
! 1498:
! 1499: lt_ptr_t
! 1500: lt_dlsym (handle, symbol)
! 1501: lt_dlhandle handle;
! 1502: const char *symbol;
! 1503: {
! 1504: int lensym;
! 1505: char lsym[LTDL_SYMBOL_LENGTH];
! 1506: char *sym;
! 1507: lt_ptr_t address;
! 1508:
! 1509: if (!handle) {
! 1510: last_error = invalid_handle_error;
! 1511: return 0;
! 1512: }
! 1513: if (!symbol) {
! 1514: last_error = symbol_error;
! 1515: return 0;
! 1516: }
! 1517: lensym = strlen(symbol);
! 1518: if (handle->type->sym_prefix)
! 1519: lensym += strlen(handle->type->sym_prefix);
! 1520: if (handle->name)
! 1521: lensym += strlen(handle->name);
! 1522: if (lensym + LTDL_SYMBOL_OVERHEAD < LTDL_SYMBOL_LENGTH)
! 1523: sym = lsym;
! 1524: else
! 1525: sym = (char*) lt_dlmalloc(lensym + LTDL_SYMBOL_OVERHEAD + 1);
! 1526: if (!sym) {
! 1527: last_error = buffer_overflow_error;
! 1528: return 0;
! 1529: }
! 1530: if (handle->name) {
! 1531: const char *saved_error = last_error;
! 1532:
! 1533: /* this is a libtool module */
! 1534: if (handle->type->sym_prefix) {
! 1535: strcpy(sym, handle->type->sym_prefix);
! 1536: strcat(sym, handle->name);
! 1537: } else
! 1538: strcpy(sym, handle->name);
! 1539: strcat(sym, "_LTX_");
! 1540: strcat(sym, symbol);
! 1541: /* try "modulename_LTX_symbol" */
! 1542: address = handle->type->find_sym(handle, sym);
! 1543: if (address) {
! 1544: if (sym != lsym)
! 1545: lt_dlfree(sym);
! 1546: return address;
! 1547: }
! 1548: last_error = saved_error;
! 1549: }
! 1550: /* otherwise try "symbol" */
! 1551: if (handle->type->sym_prefix) {
! 1552: strcpy(sym, handle->type->sym_prefix);
! 1553: strcat(sym, symbol);
! 1554: } else
! 1555: strcpy(sym, symbol);
! 1556: address = handle->type->find_sym(handle, sym);
! 1557: if (sym != lsym)
! 1558: lt_dlfree(sym);
! 1559: return address;
! 1560: }
! 1561:
! 1562: const char *
! 1563: lt_dlerror LTDL_PARAMS((void))
! 1564: {
! 1565: const char *error = last_error;
! 1566:
! 1567: last_error = 0;
! 1568: return error;
! 1569: }
! 1570:
! 1571: int
! 1572: lt_dladdsearchdir (search_dir)
! 1573: const char *search_dir;
! 1574: {
! 1575: if (!search_dir || !strlen(search_dir))
! 1576: return 0;
! 1577: if (!user_search_path) {
! 1578: user_search_path = strdup(search_dir);
! 1579: if (!user_search_path) {
! 1580: last_error = memory_error;
! 1581: return 1;
! 1582: }
! 1583: } else {
! 1584: char *new_search_path = (char*)
! 1585: lt_dlmalloc(strlen(user_search_path) +
! 1586: strlen(search_dir) + 2); /* ':' + '\0' == 2 */
! 1587: if (!new_search_path) {
! 1588: last_error = memory_error;
! 1589: return 1;
! 1590: }
! 1591: strcpy(new_search_path, user_search_path);
! 1592: strcat(new_search_path, ":");
! 1593: strcat(new_search_path, search_dir);
! 1594: lt_dlfree(user_search_path);
! 1595: user_search_path = new_search_path;
! 1596: }
! 1597: return 0;
! 1598: }
! 1599:
! 1600: int
! 1601: lt_dlsetsearchpath (search_path)
! 1602: const char *search_path;
! 1603: {
! 1604: if (user_search_path)
! 1605: lt_dlfree(user_search_path);
! 1606: user_search_path = 0; /* reset the search path */
! 1607: if (!search_path || !strlen(search_path))
! 1608: return 0;
! 1609: user_search_path = strdup(search_path);
! 1610: if (!user_search_path)
! 1611: return 1;
! 1612: return 0;
! 1613: }
! 1614:
! 1615: const char *
! 1616: lt_dlgetsearchpath LTDL_PARAMS((void))
! 1617: {
! 1618: return user_search_path;
! 1619: }
E-mail: