~ubuntu-branches/debian/squeeze/kdelibs/squeeze

« back to all changes in this revision

Viewing changes to .pc/53_kdelibs_ltdl_ext.diff/libltdl/ltdl.c

  • Committer: Bazaar Package Importer
  • Author(s): Modestas Vainius
  • Date: 2010-08-07 23:20:21 UTC
  • Revision ID: james.westby@ubuntu.com-20100807232021-owvkgp5wpc076s33
Tags: 4:3.5.10.dfsg.1-5
* Change by email address to @debian.org.
* Drop common HTML docs from kdelibs-data package. Instead suggest
  kdelibs5-data which ships them (Closes: #591609). What's more, whoever
  wants to view docs, will have to install khelpcenter4 which pulls in
  kdelibs5-data anyway.
* Switch to dpkg-source format 3.0 (quilt):
  - drop simple-patchsys.mk from debian/rules;
  - add debian/patches/series file.
* Fix corruption of zip files caused by wrong encoding of umlauts in kzip
  (patch 67_kio_zip_file_encoding.diff). (Closes: #563942) Thanks to Bjoern
  Ricks for the patch.
* Support opening of KDE 4 khelpcenter in Help -> Handbook. (Closes: #525621)
  Thanks to Ben Burton for the patch.
* Do not recurse into .pc subdirectory with doxygen 
  (patch debian/patches/02_exclude_pc_from_dox.diff).
* Urgency=medium due to multiple RC bug fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ltdl.c -- system independent dlopen wrapper
 
2
   Copyright (C) 1998, 1999, 2000 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 Lesser 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 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 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
Lesser General Public License for more details.
 
20
 
 
21
You should have received a copy of the GNU Lesser General Public
 
22
License along with this library; if not, write to the Free Software
 
23
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
24
02110-1301  USA
 
25
 
 
26
*/
 
27
 
 
28
#if HAVE_CONFIG_H
 
29
#  include <config.h>
 
30
#endif
 
31
 
 
32
#if HAVE_STDIO_H
 
33
#  include <stdio.h>
 
34
#endif
 
35
 
 
36
#if HAVE_STDLIB_H
 
37
#  include <stdlib.h>
 
38
#endif
 
39
 
 
40
#if HAVE_STRING_H
 
41
#  include <string.h>
 
42
#else
 
43
#  if HAVE_STRINGS_H
 
44
#    include <strings.h>
 
45
#  endif
 
46
#endif
 
47
 
 
48
#if HAVE_CTYPE_H
 
49
#  include <ctype.h>
 
50
#endif
 
51
 
 
52
#if HAVE_MALLOC_H
 
53
#  include <malloc.h>
 
54
#endif
 
55
 
 
56
#if HAVE_MEMORY_H
 
57
#  include <memory.h>
 
58
#endif
 
59
 
 
60
#ifdef _AIX
 
61
#include <errno.h>
 
62
#include <strings.h>
 
63
#include <sys/ldr.h>
 
64
#endif /* _AIX */
 
65
 
 
66
#include "ltdl.h"
 
67
 
 
68
/* Bah.  We don't want inline.  Needs autoconf check, which we don't want.  */
 
69
#ifdef inline
 
70
#  undef inline
 
71
#endif
 
72
#define inline
 
73
 
 
74
 
 
75
 
 
76
/* --- WINDOWS SUPPORT --- */
 
77
 
 
78
 
 
79
#ifdef DLL_EXPORT
 
80
#  define LT_GLOBAL_DATA        __declspec(dllexport)
 
81
#else
 
82
#  define LT_GLOBAL_DATA
 
83
#endif
 
84
 
 
85
/* fopen() mode flags for reading a text file */
 
86
#undef  LT_READTEXT_MODE
 
87
#ifdef __WINDOWS__
 
88
#  define LT_READTEXT_MODE "rt"
 
89
#else
 
90
#  define LT_READTEXT_MODE "r"
 
91
#endif
 
92
 
 
93
#if defined(_WIN32) && !defined(__CYGWIN__)
 
94
#  include "ltdl_win.h"
 
95
#endif
 
96
 
 
97
 
 
98
 
 
99
/* --- MANIFEST CONSTANTS --- */
 
100
 
 
101
 
 
102
/* max. filename length */
 
103
#ifndef LT_FILENAME_MAX
 
104
#  define LT_FILENAME_MAX       1024
 
105
#endif
 
106
 
 
107
/* This is the maximum symbol size that won't require malloc/free */
 
108
#undef  LT_SYMBOL_LENGTH
 
109
#define LT_SYMBOL_LENGTH        128
 
110
 
 
111
/* This accounts for the _LTX_ separator */
 
112
#undef  LT_SYMBOL_OVERHEAD
 
113
#define LT_SYMBOL_OVERHEAD      5
 
114
 
 
115
 
 
116
 
 
117
 
 
118
/* --- TYPE DEFINITIONS -- */
 
119
 
 
120
 
 
121
/* This type is used for the array of caller data sets in each handler. */
 
122
typedef struct {
 
123
  lt_dlcaller_id        key;
 
124
  lt_ptr                data;
 
125
} lt_caller_data;
 
126
 
 
127
 
 
128
 
 
129
 
 
130
/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
 
131
 
 
132
 
 
133
/* Extract the diagnostic strings from the error table macro in the same
 
134
   order as the enumberated indices in ltdl.h. */
 
135
 
 
136
static const char *lt_dlerror_strings[] =
 
137
  {
 
138
#define LT_ERROR(name, diagnostic)      (diagnostic),
 
139
    lt_dlerror_table
 
140
#undef LT_ERROR
 
141
 
 
142
    0
 
143
  };
 
144
 
 
145
/* This structure is used for the list of registered loaders. */
 
146
struct lt_dlloader {
 
147
  struct lt_dlloader   *next;
 
148
  const char           *loader_name;    /* identifying name for each loader */
 
149
  const char           *sym_prefix;     /* prefix for symbols */
 
150
  lt_module_open       *module_open;
 
151
  lt_module_close      *module_close;
 
152
  lt_find_sym          *find_sym;
 
153
  lt_dlloader_exit     *dlloader_exit;
 
154
  lt_user_data          dlloader_data;
 
155
};
 
156
 
 
157
struct lt_dlhandle_struct {
 
158
  struct lt_dlhandle_struct   *next;
 
159
  lt_dlloader          *loader;         /* dlopening interface */
 
160
  lt_dlinfo             info;
 
161
  int                   depcount;       /* number of dependencies */
 
162
  lt_dlhandle          *deplibs;        /* dependencies */
 
163
  lt_module             module;         /* system module handle */
 
164
  lt_ptr                system;         /* system specific data */
 
165
  lt_caller_data       *caller_data;    /* per caller associated data */
 
166
  int                   flags;          /* various boolean stats */
 
167
};
 
168
 
 
169
/* Various boolean flags can be stored in the flags field of an
 
170
   lt_dlhandle_struct... */
 
171
#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
 
172
#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
 
173
 
 
174
#define LT_DLRESIDENT_FLAG          (0x01 << 0)
 
175
#ifdef _AIX
 
176
#define LT_DLNOTFOUND_FLAG          (0x01 << 1) /* may be linked statically */
 
177
#define LT_DLMEMBER_FLAG            RTLD_MEMBER
 
178
#endif /* _AIX */
 
179
/* ...add more flags here... */
 
180
 
 
181
#define LT_DLIS_RESIDENT(handle)    LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
 
182
 
 
183
 
 
184
#define LT_DLSTRERROR(name)     lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
 
185
 
 
186
static  const char      objdir[]                = LTDL_OBJDIR;
 
187
#ifdef  LTDL_SHLIB_EXT
 
188
static  const char      shlib_ext[]             = LTDL_SHLIB_EXT;
 
189
#endif
 
190
#ifdef  LTDL_SYSSEARCHPATH
 
191
static  const char      sys_search_path[]       = LTDL_SYSSEARCHPATH;
 
192
#endif
 
193
 
 
194
 
 
195
 
 
196
 
 
197
/* --- MUTEX LOCKING --- */
 
198
 
 
199
 
 
200
/* Macros to make it easier to run the lock functions only if they have 
 
201
   been registered.  The reason for the complicated lock macro is to
 
202
   ensure that the stored error message from the last error is not 
 
203
   accidentally erased if the current function doesn't generate an
 
204
   error of its own.  */
 
205
#define MUTEX_LOCK()                            LT_STMT_START { \
 
206
        if (mutex_lock) (*mutex_lock)();        } LT_STMT_END
 
207
#define MUTEX_UNLOCK()                          LT_STMT_START { \
 
208
        if (mutex_unlock) (*mutex_unlock)();    } LT_STMT_END
 
209
#define MUTEX_SETERROR(errormsg)                LT_STMT_START { \
 
210
        if (mutex_seterror) (*mutex_seterror) (errormsg);       \
 
211
        else last_error = (errormsg);           } LT_STMT_END
 
212
#define MUTEX_GETERROR(errormsg)                LT_STMT_START { \
 
213
        if (mutex_seterror) errormsg = (*mutex_geterror)();     \
 
214
        else (errormsg) = last_error;           } LT_STMT_END
 
215
 
 
216
/* The mutex functions stored here are global, and are necessarily the
 
217
   same for all threads that wish to share access to libltdl.  */
 
218
static  lt_dlmutex_lock     *mutex_lock     = 0;
 
219
static  lt_dlmutex_unlock   *mutex_unlock   = 0;
 
220
static  lt_dlmutex_seterror *mutex_seterror = 0;
 
221
static  lt_dlmutex_geterror *mutex_geterror = 0;
 
222
static  const char          *last_error     = 0;
 
223
 
 
224
 
 
225
/* Either set or reset the mutex functions.  Either all the arguments must
 
226
   be valid functions, or else all can be NULL to turn off locking entirely.
 
227
   The registered functions should be manipulating a static global lock
 
228
   from the lock() and unlock() callbacks, which needs to be reentrant.  */
 
229
int
 
230
lt_dlmutex_register (lock, unlock, seterror, geterror)
 
231
     lt_dlmutex_lock *lock;
 
232
     lt_dlmutex_unlock *unlock;
 
233
     lt_dlmutex_seterror *seterror;
 
234
     lt_dlmutex_geterror *geterror;
 
235
{
 
236
  lt_dlmutex_unlock *old_unlock = unlock;
 
237
  int                errors     = 0;
 
238
 
 
239
  /* Lock using the old lock() callback, if any.  */
 
240
  MUTEX_LOCK ();
 
241
 
 
242
  if ((lock && unlock && seterror && geterror) 
 
243
      || !(lock || unlock || seterror || geterror))
 
244
    {
 
245
      mutex_lock     = lock;
 
246
      mutex_unlock   = unlock;
 
247
      mutex_geterror = geterror;
 
248
    }
 
249
  else
 
250
    {
 
251
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
 
252
      ++errors;
 
253
    }
 
254
 
 
255
  /* Use the old unlock() callback we saved earlier, if any.  Otherwise
 
256
     record any errors using internal storage.  */
 
257
  if (old_unlock)
 
258
    (*old_unlock) ();
 
259
 
 
260
  /* Return the number of errors encountered during the execution of
 
261
     this function.  */
 
262
  return errors;
 
263
}
 
264
 
 
265
 
 
266
 
 
267
 
 
268
/* --- MEMORY HANDLING --- */
 
269
 
 
270
 
 
271
LT_GLOBAL_DATA    lt_ptr        (*lt_dlmalloc)  LT_PARAMS((size_t size))
 
272
                                    = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
 
273
LT_GLOBAL_DATA    void          (*lt_dlfree)    LT_PARAMS((lt_ptr ptr))
 
274
                                    = (void (*) LT_PARAMS((lt_ptr))) free;
 
275
 
 
276
static            lt_ptr        rpl_realloc     LT_PARAMS((lt_ptr ptr,
 
277
                                                           size_t size));
 
278
 
 
279
#define LT_DLMALLOC(tp, n)      ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
 
280
#define LT_DLREALLOC(tp, p, n)  ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
 
281
#define LT_DLFREE(p)                                            \
 
282
        LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
 
283
 
 
284
#define LT_DLMEM_REASSIGN(p, q)                 LT_STMT_START { \
 
285
        if ((p) != (q)) { lt_dlfree (p); (p) = (q); }           \
 
286
                                                } LT_STMT_END
 
287
 
 
288
 
 
289
 
 
290
/* --- ERROR MESSAGES --- */
 
291
 
 
292
 
 
293
static  const char    **user_error_strings      = 0;
 
294
static  int             errorcount              = LT_ERROR_MAX;
 
295
 
 
296
int
 
297
lt_dladderror (diagnostic)
 
298
     const char *diagnostic;
 
299
{
 
300
  int           _index   = 0;
 
301
  int           result   = -1;
 
302
  const char  **temp     = (const char **) 0;
 
303
 
 
304
  MUTEX_LOCK ();
 
305
 
 
306
  _index         = errorcount - LT_ERROR_MAX;
 
307
  temp = LT_DLREALLOC (const char *, user_error_strings, 1 + _index);
 
308
  if (temp == 0)
 
309
    {
 
310
      MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
311
    }
 
312
  else
 
313
    {
 
314
      user_error_strings        = temp;
 
315
      user_error_strings[_index] = diagnostic;
 
316
      result                    = errorcount++;
 
317
    }
 
318
 
 
319
  MUTEX_UNLOCK ();
 
320
 
 
321
  return result;
 
322
}
 
323
 
 
324
int
 
325
lt_dlseterror (_index)
 
326
     int _index;
 
327
{
 
328
  int           errors   = 0;
 
329
 
 
330
  MUTEX_LOCK ();
 
331
 
 
332
  if (_index >= errorcount || _index < 0)
 
333
    {
 
334
      /* Ack!  Error setting the error message! */
 
335
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
 
336
      ++errors;
 
337
    }
 
338
  else if (_index < LT_ERROR_MAX)
 
339
    {
 
340
      /* No error setting the error message! */
 
341
      MUTEX_SETERROR (lt_dlerror_strings[errorcount]);
 
342
    }
 
343
  else
 
344
    {
 
345
      /* No error setting the error message! */
 
346
      MUTEX_SETERROR (user_error_strings[errorcount - LT_ERROR_MAX]);
 
347
    }
 
348
 
 
349
  MUTEX_UNLOCK ();
 
350
 
 
351
  return errors;
 
352
}
 
353
 
 
354
 
 
355
 
 
356
 
 
357
/* --- REPLACEMENT FUNCTIONS --- */
 
358
 
 
359
 
 
360
#undef strdup
 
361
#define strdup rpl_strdup
 
362
 
 
363
static inline char *
 
364
strdup(str)
 
365
     const char *str;
 
366
{
 
367
  char *tmp = 0;
 
368
 
 
369
  if (str)
 
370
    {
 
371
      tmp = LT_DLMALLOC (char, 1+ strlen (str));
 
372
      if (tmp)
 
373
        {
 
374
          strcpy(tmp, str);
 
375
        }
 
376
    }
 
377
 
 
378
  return tmp;
 
379
}
 
380
 
 
381
 
 
382
#if ! HAVE_STRCMP
 
383
 
 
384
#undef strcmp
 
385
#define strcmp rpl_strcmp
 
386
 
 
387
static inline int
 
388
strcmp (str1, str2)
 
389
     const char *str1;
 
390
     const char *str2;
 
391
{
 
392
  if (str1 == str2)
 
393
    return 0;
 
394
  if (str1 == 0)
 
395
    return -1;
 
396
  if (str2 == 0)
 
397
    return 1;
 
398
 
 
399
  for (;*str1 && *str2; ++str1, ++str2)
 
400
    {
 
401
      if (*str1 != *str2)
 
402
        break;
 
403
    }
 
404
 
 
405
  return (int)(*str1 - *str2);
 
406
}
 
407
#endif
 
408
 
 
409
 
 
410
#if ! HAVE_STRCHR
 
411
 
 
412
#  if HAVE_INDEX
 
413
#    define strchr index
 
414
#  else
 
415
#    define strchr rpl_strchr
 
416
 
 
417
static inline const char*
 
418
strchr(str, ch)
 
419
     const char *str;
 
420
     int ch;
 
421
{
 
422
  const char *p;
 
423
 
 
424
  for (p = str; *p != (char)ch && *p != '\0'; ++p)
 
425
    /*NOWORK*/;
 
426
 
 
427
  return (*p == (char)ch) ? p : 0;
 
428
}
 
429
 
 
430
#  endif
 
431
#endif /* !HAVE_STRCHR */
 
432
 
 
433
#if ! HAVE_STRRCHR
 
434
 
 
435
#  if HAVE_RINDEX
 
436
#    define strrchr rindex
 
437
#  else
 
438
#    define strrchr rpl_strrchr
 
439
 
 
440
static inline const char*
 
441
strrchr(str, ch)
 
442
     const char *str;
 
443
     int ch;
 
444
{
 
445
  const char *p, *q = 0;
 
446
 
 
447
  for (p = str; *p != '\0'; ++p)
 
448
    {
 
449
      if (*p == (char) ch)
 
450
        {
 
451
          q = p;
 
452
        }
 
453
    }
 
454
 
 
455
  return q;
 
456
}
 
457
 
 
458
# endif
 
459
#endif
 
460
 
 
461
/* NOTE:  Neither bcopy nor the memcpy implementation below can
 
462
          reliably handle copying in overlapping areas of memory, so
 
463
          do not rely on this behavior when invoking memcpy later.  */
 
464
#if ! HAVE_MEMCPY
 
465
 
 
466
#  if HAVE_BCOPY
 
467
#    define memcpy(dest, src, size)     bcopy (src, dest, size)
 
468
#  else
 
469
#    define memcpy rpl_memcpy
 
470
 
 
471
static inline char *
 
472
memcpy (dest, src, size)
 
473
     char *dest;
 
474
     const char *src;
 
475
     size_t size;
 
476
{
 
477
  size_t i = 0;
 
478
 
 
479
  for (i = 0; i < size; ++i)
 
480
    {
 
481
      dest[i] = src[i];
 
482
    }
 
483
 
 
484
  return dest;
 
485
}
 
486
 
 
487
#  endif
 
488
#endif
 
489
 
 
490
/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
 
491
    ``realloc is not entirely portable''
 
492
   In any case we want to use the allocator supplied by the user without
 
493
   burdening them with an lt_dlrealloc function pointer to maintain.
 
494
   Instead implement our own version (with known boundary conditions)
 
495
   using lt_dlmalloc and lt_dlfree. */
 
496
static lt_ptr
 
497
rpl_realloc (ptr, size)
 
498
     lt_ptr ptr;
 
499
     size_t size;
 
500
{
 
501
  if (size < 1)
 
502
    {
 
503
      /* For zero or less bytes, free the original memory */
 
504
      if (ptr != 0)
 
505
        {
 
506
          lt_dlfree (ptr);
 
507
        }
 
508
 
 
509
      return (lt_ptr) 0;
 
510
    }
 
511
  else if (ptr == 0)
 
512
    {
 
513
      /* Allow reallocation of a NULL pointer.  */
 
514
      return lt_dlmalloc (size);
 
515
    }
 
516
  else
 
517
    {
 
518
      /* Allocate a new block, copy and free the old block.  */
 
519
      lt_ptr mem = (lt_ptr) realloc (ptr, size);
 
520
 
 
521
      /* Note that the contents of PTR are not damaged if there is
 
522
         insufficient memory to realloc.  */
 
523
      return mem;
 
524
    }
 
525
}
 
526
 
 
527
 
 
528
 
 
529
 
 
530
/* --- DLOPEN() INTERFACE LOADER --- */
 
531
 
 
532
/* The Cygwin dlopen implementation prints a spurious error message to
 
533
   stderr if its call to LoadLibrary() fails for any reason.  We can
 
534
   mitigate this by not using the Cygwin implementation, and falling
 
535
   back to our own LoadLibrary() wrapper. */
 
536
#if HAVE_LIBDL && !defined(__CYGWIN__)
 
537
 
 
538
/* dynamic linking with dlopen/dlsym */
 
539
 
 
540
#if HAVE_DLFCN_H
 
541
#  include <dlfcn.h>
 
542
#endif
 
543
 
 
544
#ifdef RTLD_GLOBAL
 
545
#  define LT_GLOBAL             RTLD_GLOBAL
 
546
#else
 
547
#  ifdef DL_GLOBAL
 
548
#    define LT_GLOBAL           DL_GLOBAL
 
549
#  endif
 
550
#endif /* !RTLD_GLOBAL */
 
551
#ifndef LT_GLOBAL
 
552
#  define LT_GLOBAL             0
 
553
#endif /* !LT_GLOBAL */
 
554
 
 
555
/* We may have to define LT_LAZY_OR_NOW in the command line if we
 
556
   find out it does not work in some platform. */
 
557
#ifndef LT_LAZY_OR_NOW
 
558
#  ifdef RTLD_LAZY
 
559
#    define LT_LAZY_OR_NOW      RTLD_LAZY
 
560
#  else
 
561
#    ifdef DL_LAZY
 
562
#      define LT_LAZY_OR_NOW    DL_LAZY
 
563
#    endif
 
564
#  endif /* !RTLD_LAZY */
 
565
#endif
 
566
#ifndef LT_LAZY_OR_NOW
 
567
#  ifdef RTLD_NOW
 
568
#    define LT_LAZY_OR_NOW      RTLD_NOW
 
569
#  else
 
570
#    ifdef DL_NOW
 
571
#      define LT_LAZY_OR_NOW    DL_NOW
 
572
#    endif
 
573
#  endif /* !RTLD_NOW */
 
574
#endif
 
575
#ifndef LT_LAZY_OR_NOW
 
576
#  define LT_LAZY_OR_NOW        0
 
577
#endif /* !LT_LAZY_OR_NOW */
 
578
 
 
579
#if HAVE_DLERROR
 
580
#  define DLERROR(arg)  dlerror ()
 
581
#else
 
582
#  define DLERROR(arg)  LT_DLSTRERROR (arg)
 
583
#endif
 
584
 
 
585
int lt_dlopen_flag = LT_LAZY_OR_NOW;
 
586
 
 
587
#ifdef _AIX
 
588
/*------------------------------------------------------------------*/
 
589
/* implementations found at the end                                 */
 
590
/*------------------------------------------------------------------*/
 
591
 
 
592
static void
 
593
sys_dl_init( );
 
594
 
 
595
static lt_dlhandle
 
596
sys_dl_search_by_name( const char* name );
 
597
 
 
598
static void
 
599
sys_dl_not_found_entry( const char* tmp );
 
600
#endif /* _AIX */
 
601
 
 
602
static lt_module
 
603
sys_dl_open (loader_data, filename)
 
604
     lt_user_data loader_data;
 
605
     const char *filename;
 
606
{
 
607
  lt_module module;
 
608
#ifdef _AIX
 
609
  /* If the basename is of the form "libname.a(member)",
 
610
     set the appropriate flag. */
 
611
  if (strrchr(filename, '('))
 
612
    lt_dlopen_flag |= LT_DLMEMBER_FLAG;
 
613
#endif
 
614
  module = dlopen (filename, lt_dlopen_flag);
 
615
 
 
616
  if (!module)
 
617
    {
 
618
      MUTEX_SETERROR (DLERROR (CANNOT_OPEN));
 
619
    }
 
620
 
 
621
  return module;
 
622
}
 
623
 
 
624
static int
 
625
sys_dl_close (loader_data, module)
 
626
     lt_user_data loader_data;
 
627
     lt_module module;
 
628
{
 
629
  int errors = 0;
 
630
 
 
631
  if (dlclose (module) != 0)
 
632
    {
 
633
      MUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
 
634
      ++errors;
 
635
    }
 
636
 
 
637
  return errors;
 
638
}
 
639
 
 
640
static lt_ptr
 
641
sys_dl_sym (loader_data, module, symbol)
 
642
     lt_user_data loader_data;
 
643
     lt_module module;
 
644
     const char *symbol;
 
645
{
 
646
  lt_ptr address = dlsym (module, symbol);
 
647
 
 
648
  if (!address)
 
649
    {
 
650
      MUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
 
651
    }
 
652
 
 
653
  return address;
 
654
}
 
655
 
 
656
static struct lt_user_dlloader sys_dl =
 
657
  {
 
658
#  ifdef NEED_USCORE
 
659
    "_",
 
660
#  else
 
661
    0,
 
662
#  endif
 
663
    sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
 
664
 
 
665
#else
 
666
int lt_dlopen_flag = 0;
 
667
#endif /* HAVE_LIBDL */
 
668
 
 
669
 
 
670
 
 
671
/* --- SHL_LOAD() INTERFACE LOADER --- */
 
672
 
 
673
#if HAVE_SHL_LOAD
 
674
 
 
675
/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
 
676
 
 
677
#ifdef HAVE_DL_H
 
678
#  include <dl.h>
 
679
#endif
 
680
 
 
681
/* some flags are missing on some systems, so we provide
 
682
 * harmless defaults.
 
683
 *
 
684
 * Mandatory:
 
685
 * BIND_IMMEDIATE  - Resolve symbol references when the library is loaded.
 
686
 * BIND_DEFERRED   - Delay code symbol resolution until actual reference.
 
687
 *
 
688
 * Optionally:
 
689
 * BIND_FIRST      - Place the library at the head of the symbol search
 
690
 *                   order.
 
691
 * BIND_NONFATAL   - The default BIND_IMMEDIATE behavior is to treat all
 
692
 *                   unsatisfied symbols as fatal.  This flag allows
 
693
 *                   binding of unsatisfied code symbols to be deferred
 
694
 *                   until use.
 
695
 *                   [Perl: For certain libraries, like DCE, deferred
 
696
 *                   binding often causes run time problems. Adding
 
697
 *                   BIND_NONFATAL to BIND_IMMEDIATE still allows
 
698
 *                   unresolved references in situations like this.]
 
699
 * BIND_NOSTART    - Do not call the initializer for the shared library
 
700
 *                   when the library is loaded, nor on a future call to
 
701
 *                   shl_unload().
 
702
 * BIND_VERBOSE    - Print verbose messages concerning possible
 
703
 *                   unsatisfied symbols.
 
704
 *
 
705
 * hp9000s700/hp9000s800:
 
706
 * BIND_RESTRICTED - Restrict symbols visible by the library to those
 
707
 *                   present at library load time.
 
708
 * DYNAMIC_PATH    - Allow the loader to dynamically search for the
 
709
 *                   library specified by the path argument.
 
710
 */
 
711
 
 
712
#ifndef DYNAMIC_PATH
 
713
#  define DYNAMIC_PATH          0
 
714
#endif
 
715
#ifndef BIND_RESTRICTED
 
716
#  define BIND_RESTRICTED       0
 
717
#endif
 
718
 
 
719
#define LT_BIND_FLAGS   (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
 
720
 
 
721
static lt_module
 
722
sys_shl_open (loader_data, filename)
 
723
     lt_user_data loader_data;
 
724
     const char *filename;
 
725
{
 
726
  /* A NULL handle is used to get symbols from self and everything
 
727
     else already loaded that was exported with -E compiler flag.  */
 
728
  lt_module module = (lt_module) 0;
 
729
 
 
730
  if (filename)
 
731
    {
 
732
      module = shl_load (filename, LT_BIND_FLAGS, 0L);
 
733
 
 
734
      if (!module)
 
735
        {
 
736
          MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
 
737
        }
 
738
    }
 
739
  
 
740
  return module;
 
741
}
 
742
 
 
743
static int
 
744
sys_shl_close (loader_data, module)
 
745
     lt_user_data loader_data;
 
746
     lt_module module;
 
747
{
 
748
  int errors = 0;
 
749
 
 
750
  if (module && (shl_unload ((shl_t) (module)) != 0))
 
751
    {
 
752
      MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
 
753
      ++errors;
 
754
    }
 
755
 
 
756
  return errors;
 
757
}
 
758
 
 
759
static lt_ptr
 
760
sys_shl_sym (loader_data, module, symbol)
 
761
     lt_user_data loader_data;
 
762
     lt_module module;
 
763
     const char *symbol;
 
764
{
 
765
  int    is_module_self = (module == (lt_module) 0);
 
766
  lt_ptr address        = 0;
 
767
 
 
768
  /* shl_findsym considers zero valued MODULE as an indicator to search
 
769
     for a symbol among all loaded (and exported) symbols including those
 
770
     in the main executable.  However, it sets MODULE to a valid module
 
771
     address which breaks the semantics of libltdl's module management.  */
 
772
  if (shl_findsym ((shl_t*) &module, symbol, TYPE_UNDEFINED, &address) == 0)
 
773
    {
 
774
      if (!address)
 
775
        {
 
776
          MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
 
777
        }
 
778
    }
 
779
  
 
780
  if (is_module_self)
 
781
    module = (lt_module) 0;
 
782
 
 
783
  return address;
 
784
}
 
785
 
 
786
static struct lt_user_dlloader sys_shl = {
 
787
  0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
 
788
};
 
789
 
 
790
#endif /* HAVE_SHL_LOAD */
 
791
 
 
792
 
 
793
 
 
794
 
 
795
/* --- LOADLIBRARY() INTERFACE LOADER --- */
 
796
 
 
797
#if defined(__WINDOWS__) || defined(__CYGWIN__)
 
798
 
 
799
/* dynamic linking for Win32 */
 
800
 
 
801
#include <windows.h>
 
802
 
 
803
/* Forward declaration; required to implement handle search below. */
 
804
static lt_dlhandle handles;
 
805
 
 
806
static lt_module
 
807
sys_wll_open (loader_data, filename)
 
808
     lt_user_data loader_data;
 
809
     const char *filename;
 
810
{
 
811
  lt_dlhandle   cur;
 
812
  lt_module     module     = 0;
 
813
  const char   *errormsg   = 0;
 
814
  char         *searchname = 0;
 
815
  char         *ext;
 
816
  char          self_name_buf[MAX_PATH];
 
817
 
 
818
  if (!filename)
 
819
    {
 
820
      /* Get the name of main module */
 
821
      *self_name_buf = 0;
 
822
      GetModuleFileName (NULL, (unsigned short*)self_name_buf, sizeof (self_name_buf));
 
823
      filename = ext = self_name_buf;
 
824
    }
 
825
  else
 
826
    {
 
827
      ext = (char *)strrchr (filename, '.');
 
828
    }
 
829
 
 
830
  if (ext)
 
831
    {
 
832
      /* FILENAME already has an extension. */
 
833
      searchname = strdup (filename);
 
834
    }
 
835
  else
 
836
    {
 
837
      /* Append a `.' to stop Windows from adding an
 
838
         implicit `.dll' extension. */
 
839
      searchname = LT_DLMALLOC (char, 2+ strlen (filename));
 
840
      if (!searchname)
 
841
        {
 
842
          MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
843
          return 0;
 
844
        }
 
845
      strcpy (searchname, filename);
 
846
      strcat (searchname, ".");
 
847
    }
 
848
 
 
849
#if __CYGWIN__
 
850
  {
 
851
    char wpath[MAX_PATH];
 
852
    cygwin_conv_to_full_win32_path(searchname, wpath);
 
853
    module = LoadLibrary(wpath);
 
854
  }
 
855
#elif defined(_WIN32)
 
856
  {
 
857
     char wpath[MAX_PATH];
 
858
     strncpy(wpath, searchname, MAX_PATH);
 
859
     win32_backslashify( wpath );
 
860
     win32_mapSo2Dll( wpath );
 
861
//fprintf (stderr, "LoadLibraryA(\"%s\")\n", wpath);
 
862
     module = LoadLibraryA( wpath );
 
863
  }
 
864
#else
 
865
  module = LoadLibrary (searchname);
 
866
#endif
 
867
  LT_DLFREE (searchname);
 
868
 
 
869
  /* libltdl expects this function to fail if it is unable
 
870
     to physically load the library.  Sadly, LoadLibrary
 
871
     will search the loaded libraries for a match and return
 
872
     one of them if the path search load fails.
 
873
 
 
874
     We check whether LoadLibrary is returning a handle to
 
875
     an already loaded module, and simulate failure if we
 
876
     find one. */
 
877
  MUTEX_LOCK ();
 
878
  cur = handles;
 
879
  while (cur)
 
880
    {
 
881
      if (!cur->module)
 
882
        {
 
883
          cur = 0;
 
884
          break;
 
885
        }
 
886
 
 
887
      if (cur->module == module)
 
888
        {
 
889
          break;
 
890
        }
 
891
 
 
892
      cur = cur->next;
 
893
  }
 
894
  MUTEX_UNLOCK ();
 
895
 
 
896
  if (cur || !module)
 
897
    {
 
898
      MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
 
899
      module = 0;
 
900
    }
 
901
 
 
902
  return module;
 
903
}
 
904
 
 
905
static int
 
906
sys_wll_close (loader_data, module)
 
907
     lt_user_data loader_data;
 
908
     lt_module module;
 
909
{
 
910
  int         errors   = 0;
 
911
 
 
912
  if (FreeLibrary(module) == 0)
 
913
    {
 
914
      MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
 
915
      ++errors;
 
916
    }
 
917
 
 
918
  return errors;
 
919
}
 
920
 
 
921
static lt_ptr
 
922
sys_wll_sym (loader_data, module, symbol)
 
923
     lt_user_data loader_data;
 
924
     lt_module module;
 
925
     const char *symbol;
 
926
{
 
927
  lt_ptr      address  = GetProcAddress (module, symbol);
 
928
 
 
929
  if (!address)
 
930
    {
 
931
      MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
 
932
    }
 
933
 
 
934
  return address;
 
935
}
 
936
 
 
937
static struct lt_user_dlloader sys_wll = {
 
938
  0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
 
939
};
 
940
 
 
941
#endif /* __WINDOWS__ */
 
942
 
 
943
 
 
944
 
 
945
 
 
946
/* --- LOAD_ADD_ON() INTERFACE LOADER --- */
 
947
 
 
948
 
 
949
#ifdef __BEOS__
 
950
 
 
951
/* dynamic linking for BeOS */
 
952
 
 
953
#include <kernel/image.h>
 
954
 
 
955
static lt_module
 
956
sys_bedl_open (loader_data, filename)
 
957
     lt_user_data loader_data;
 
958
     const char *filename;
 
959
{
 
960
  image_id image = 0;
 
961
 
 
962
  if (filename)
 
963
    {
 
964
      image = load_add_on (filename);
 
965
    }
 
966
  else
 
967
    {
 
968
      image_info info;
 
969
      int32 cookie = 0;
 
970
      if (get_next_image_info (0, &cookie, &info) == B_OK)
 
971
        image = load_add_on (info.name);
 
972
    }
 
973
 
 
974
  if (image <= 0)
 
975
    {
 
976
      MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
 
977
      image = 0;
 
978
    }
 
979
 
 
980
  return (lt_module) image;
 
981
}
 
982
 
 
983
static int
 
984
sys_bedl_close (loader_data, module)
 
985
     lt_user_data loader_data;
 
986
     lt_module module;
 
987
{
 
988
  int errors = 0;
 
989
 
 
990
  if (unload_add_on ((image_id) module) != B_OK)
 
991
    {
 
992
      MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
 
993
      ++errors;
 
994
    }
 
995
 
 
996
  return errors;
 
997
}
 
998
 
 
999
static lt_ptr
 
1000
sys_bedl_sym (loader_data, module, symbol)
 
1001
     lt_user_data loader_data;
 
1002
     lt_module module;
 
1003
     const char *symbol;
 
1004
{
 
1005
  lt_ptr address = 0;
 
1006
  image_id image = (image_id) module;
 
1007
 
 
1008
  if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
 
1009
    {
 
1010
      MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
 
1011
      address = 0;
 
1012
    }
 
1013
 
 
1014
  return address;
 
1015
}
 
1016
 
 
1017
static struct lt_user_dlloader sys_bedl = {
 
1018
  0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
 
1019
};
 
1020
 
 
1021
#endif /* __BEOS__ */
 
1022
 
 
1023
 
 
1024
 
 
1025
 
 
1026
/* --- DLD_LINK() INTERFACE LOADER --- */
 
1027
 
 
1028
 
 
1029
#if HAVE_DLD
 
1030
 
 
1031
/* dynamic linking with dld */
 
1032
 
 
1033
#if HAVE_DLD_H
 
1034
#include <dld.h>
 
1035
#endif
 
1036
 
 
1037
static lt_module
 
1038
sys_dld_open (loader_data, filename)
 
1039
     lt_user_data loader_data;
 
1040
     const char *filename;
 
1041
{
 
1042
  lt_module module = strdup (filename);
 
1043
 
 
1044
  if (!module)
 
1045
    {
 
1046
      MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
1047
      module = 0;
 
1048
    }
 
1049
  else if (dld_link (filename) != 0)
 
1050
    {
 
1051
      MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
 
1052
      LT_DLFREE (module);
 
1053
      module = 0;
 
1054
    }
 
1055
 
 
1056
  return module;
 
1057
}
 
1058
 
 
1059
static int
 
1060
sys_dld_close (loader_data, module)
 
1061
     lt_user_data loader_data;
 
1062
     lt_module module;
 
1063
{
 
1064
  int errors = 0;
 
1065
 
 
1066
  if (dld_unlink_by_file ((char*)(module), 1) != 0)
 
1067
    {
 
1068
      MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
 
1069
      ++errors;
 
1070
    }
 
1071
  else
 
1072
    {
 
1073
      LT_DLFREE (module);
 
1074
    }
 
1075
 
 
1076
  return errors;
 
1077
}
 
1078
 
 
1079
static lt_ptr
 
1080
sys_dld_sym (loader_data, module, symbol)
 
1081
     lt_user_data loader_data;
 
1082
     lt_module module;
 
1083
     const char *symbol;
 
1084
{
 
1085
  lt_ptr address = dld_get_func (symbol);
 
1086
 
 
1087
  if (!address)
 
1088
    {
 
1089
      MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
 
1090
    }
 
1091
 
 
1092
  return address;
 
1093
}
 
1094
 
 
1095
static struct lt_user_dlloader sys_dld = {
 
1096
  0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
 
1097
};
 
1098
 
 
1099
#endif /* HAVE_DLD */
 
1100
 
 
1101
 
 
1102
 
 
1103
 
 
1104
/* --- DLPREOPEN() INTERFACE LOADER --- */
 
1105
 
 
1106
 
 
1107
/* emulate dynamic linking using preloaded_symbols */
 
1108
 
 
1109
typedef struct lt_dlsymlists_t
 
1110
{
 
1111
  struct lt_dlsymlists_t       *next;
 
1112
  const lt_dlsymlist           *syms;
 
1113
} lt_dlsymlists_t;
 
1114
 
 
1115
static  const lt_dlsymlist     *default_preloaded_symbols       = 0;
 
1116
static  lt_dlsymlists_t        *preloaded_symbols               = 0;
 
1117
 
 
1118
static int
 
1119
presym_init (loader_data)
 
1120
     lt_user_data loader_data;
 
1121
{
 
1122
  int errors = 0;
 
1123
 
 
1124
  MUTEX_LOCK ();
 
1125
 
 
1126
  preloaded_symbols = 0;
 
1127
  if (default_preloaded_symbols)
 
1128
    {
 
1129
      errors = lt_dlpreload (default_preloaded_symbols);
 
1130
    }
 
1131
 
 
1132
  MUTEX_UNLOCK ();
 
1133
 
 
1134
  return errors;
 
1135
}
 
1136
 
 
1137
static int
 
1138
presym_free_symlists ()
 
1139
{
 
1140
  lt_dlsymlists_t *lists;
 
1141
 
 
1142
  MUTEX_LOCK ();
 
1143
 
 
1144
  lists = preloaded_symbols;
 
1145
  while (lists)
 
1146
    {
 
1147
      lt_dlsymlists_t   *tmp = lists;
 
1148
 
 
1149
      lists = lists->next;
 
1150
      LT_DLFREE (tmp);
 
1151
    }
 
1152
  preloaded_symbols = 0;
 
1153
 
 
1154
  MUTEX_UNLOCK ();
 
1155
 
 
1156
  return 0;
 
1157
}
 
1158
 
 
1159
static int
 
1160
presym_exit (loader_data)
 
1161
     lt_user_data loader_data;
 
1162
{
 
1163
  presym_free_symlists ();
 
1164
  return 0;
 
1165
}
 
1166
 
 
1167
static int
 
1168
presym_add_symlist (preloaded)
 
1169
     const lt_dlsymlist *preloaded;
 
1170
{
 
1171
  lt_dlsymlists_t *tmp;
 
1172
  lt_dlsymlists_t *lists;
 
1173
  int              errors   = 0;
 
1174
 
 
1175
  MUTEX_LOCK ();
 
1176
 
 
1177
  lists = preloaded_symbols;
 
1178
  while (lists)
 
1179
    {
 
1180
      if (lists->syms == preloaded)
 
1181
        {
 
1182
          goto done;
 
1183
        }
 
1184
      lists = lists->next;
 
1185
    }
 
1186
 
 
1187
  tmp = LT_DLMALLOC (lt_dlsymlists_t, 1);
 
1188
  if (tmp)
 
1189
    {
 
1190
      tmp->syms = preloaded;
 
1191
      tmp->next = preloaded_symbols;
 
1192
      preloaded_symbols = tmp;
 
1193
    }
 
1194
  else
 
1195
    {
 
1196
      MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
1197
      ++errors;
 
1198
    }
 
1199
 
 
1200
 done:
 
1201
  MUTEX_UNLOCK ();
 
1202
  return errors;
 
1203
}
 
1204
 
 
1205
static lt_module
 
1206
presym_open (loader_data, filename)
 
1207
     lt_user_data loader_data;
 
1208
     const char *filename;
 
1209
{
 
1210
  lt_dlsymlists_t *lists;
 
1211
  lt_module        module = (lt_module) 0;
 
1212
 
 
1213
  MUTEX_LOCK ();
 
1214
  lists = preloaded_symbols;
 
1215
 
 
1216
  if (!lists)
 
1217
    {
 
1218
      MUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
 
1219
      goto done;
 
1220
    }
 
1221
 
 
1222
  if (!filename)
 
1223
    {
 
1224
      filename = "@PROGRAM@";
 
1225
    }
 
1226
 
 
1227
  while (lists)
 
1228
    {
 
1229
      const lt_dlsymlist *syms = lists->syms;
 
1230
 
 
1231
      while (syms->name)
 
1232
        {
 
1233
          if (!syms->address && strcmp(syms->name, filename) == 0)
 
1234
            {
 
1235
              module = (lt_module) syms;
 
1236
              goto done;
 
1237
            }
 
1238
          ++syms;
 
1239
        }
 
1240
 
 
1241
      lists = lists->next;
 
1242
    }
 
1243
 
 
1244
  MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
 
1245
 
 
1246
 done:
 
1247
  MUTEX_UNLOCK ();
 
1248
  return module;
 
1249
}
 
1250
 
 
1251
static int
 
1252
presym_close (loader_data, module)
 
1253
     lt_user_data loader_data;
 
1254
     lt_module module;
 
1255
{
 
1256
  /* Just to silence gcc -Wall */
 
1257
  module = 0;
 
1258
  return 0;
 
1259
}
 
1260
 
 
1261
static lt_ptr
 
1262
presym_sym (loader_data, module, symbol)
 
1263
     lt_user_data loader_data;
 
1264
     lt_module module;
 
1265
     const char *symbol;
 
1266
{
 
1267
  lt_dlsymlist *syms = (lt_dlsymlist*) module;
 
1268
 
 
1269
  ++syms;
 
1270
  while (syms->address)
 
1271
    {
 
1272
      if (strcmp(syms->name, symbol) == 0)
 
1273
        {
 
1274
          return syms->address;
 
1275
        }
 
1276
 
 
1277
    ++syms;
 
1278
  }
 
1279
 
 
1280
  MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
 
1281
 
 
1282
  return 0;
 
1283
}
 
1284
 
 
1285
static struct lt_user_dlloader presym = {
 
1286
  0, presym_open, presym_close, presym_sym, presym_exit, 0
 
1287
};
 
1288
 
 
1289
 
 
1290
 
 
1291
 
 
1292
 
 
1293
/* --- DYNAMIC MODULE LOADING --- */
 
1294
 
 
1295
 
 
1296
static  char           *user_search_path= 0;
 
1297
static  lt_dlloader    *loaders         = 0;
 
1298
static  lt_dlhandle     handles         = 0;
 
1299
static  int             initialized     = 0;
 
1300
 
 
1301
/* Initialize libltdl. */
 
1302
int
 
1303
lt_dlinit ()
 
1304
{
 
1305
  int         errors   = 0;
 
1306
 
 
1307
  MUTEX_LOCK ();
 
1308
 
 
1309
  /* Initialize only at first call. */
 
1310
  if (++initialized == 1)
 
1311
    {
 
1312
      handles = 0;
 
1313
      user_search_path = 0; /* empty search path */
 
1314
 
 
1315
#if HAVE_LIBDL && !defined(__CYGWIN__)
 
1316
      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
 
1317
#ifdef _AIX
 
1318
      sys_dl_init();
 
1319
#endif /* _AIX */
 
1320
#endif
 
1321
#if HAVE_SHL_LOAD
 
1322
      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
 
1323
#endif
 
1324
#if defined(__WINDOWS__) || defined(__CYGWIN__)
 
1325
      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
 
1326
#endif
 
1327
#ifdef __BEOS__
 
1328
      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
 
1329
#endif
 
1330
#if HAVE_DLD
 
1331
      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
 
1332
#endif
 
1333
      errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
 
1334
 
 
1335
      if (presym_init (presym.dlloader_data))
 
1336
        {
 
1337
          MUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
 
1338
          ++errors;
 
1339
        }
 
1340
      else if (errors != 0)
 
1341
        {
 
1342
          MUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
 
1343
          ++errors;
 
1344
        }
 
1345
    }
 
1346
 
 
1347
  MUTEX_UNLOCK ();
 
1348
 
 
1349
  return errors;
 
1350
}
 
1351
 
 
1352
int
 
1353
lt_dlpreload (preloaded)
 
1354
     const lt_dlsymlist *preloaded;
 
1355
{
 
1356
  int errors = 0;
 
1357
 
 
1358
  if (preloaded)
 
1359
    {
 
1360
      errors = presym_add_symlist (preloaded);
 
1361
    }
 
1362
  else
 
1363
    {
 
1364
      const char *errormsg = 0;
 
1365
 
 
1366
      presym_free_symlists();
 
1367
  
 
1368
      MUTEX_LOCK ();
 
1369
      if (default_preloaded_symbols)
 
1370
        {
 
1371
          errors = lt_dlpreload (default_preloaded_symbols);
 
1372
        }
 
1373
      MUTEX_UNLOCK ();
 
1374
    }
 
1375
 
 
1376
  return errors;
 
1377
}
 
1378
 
 
1379
int
 
1380
lt_dlpreload_default (preloaded)
 
1381
     const lt_dlsymlist *preloaded;
 
1382
{
 
1383
  MUTEX_LOCK ();
 
1384
  default_preloaded_symbols = preloaded;
 
1385
  MUTEX_UNLOCK ();
 
1386
  return 0;
 
1387
}
 
1388
 
 
1389
int
 
1390
lt_dlexit ()
 
1391
{
 
1392
  /* shut down libltdl */
 
1393
  lt_dlloader *loader;
 
1394
  const char  *errormsg;
 
1395
  int          errors   = 0;
 
1396
 
 
1397
  MUTEX_LOCK ();
 
1398
  loader = loaders;
 
1399
 
 
1400
  if (!initialized)
 
1401
    {
 
1402
      MUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
 
1403
      ++errors;
 
1404
      goto done;
 
1405
    }
 
1406
 
 
1407
  /* shut down only at last call. */
 
1408
  if (--initialized == 0)
 
1409
    {
 
1410
      int       level;
 
1411
 
 
1412
      while (handles && LT_DLIS_RESIDENT (handles))
 
1413
        {
 
1414
          handles = handles->next;
 
1415
        }
 
1416
 
 
1417
      /* close all modules */
 
1418
      for (level = 1; handles; ++level)
 
1419
        {
 
1420
          lt_dlhandle cur = handles;
 
1421
 
 
1422
          while (cur)
 
1423
            {
 
1424
              lt_dlhandle tmp = cur;
 
1425
              cur = cur->next;
 
1426
              if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
 
1427
                {
 
1428
                  if (lt_dlclose (tmp))
 
1429
                    {
 
1430
                      ++errors;
 
1431
                    }
 
1432
                }
 
1433
            }
 
1434
        }
 
1435
 
 
1436
      /* close all loaders */
 
1437
      while (loader)
 
1438
        {
 
1439
          lt_dlloader *next = loader->next;
 
1440
          lt_user_data data = loader->dlloader_data;
 
1441
          if (loader->dlloader_exit && loader->dlloader_exit (data))
 
1442
            {
 
1443
              ++errors;
 
1444
            }
 
1445
 
 
1446
          LT_DLMEM_REASSIGN (loader, next);
 
1447
        }
 
1448
      loaders = 0;
 
1449
    }
 
1450
 
 
1451
 done:
 
1452
  MUTEX_UNLOCK ();
 
1453
  return errors;
 
1454
}
 
1455
 
 
1456
static int
 
1457
tryall_dlopen (handle, filename)
 
1458
     lt_dlhandle *handle;
 
1459
     const char *filename;
 
1460
{
 
1461
  lt_dlhandle    cur;
 
1462
  lt_dlloader   *loader;
 
1463
  const char    *saved_error;
 
1464
  int            errors         = 0;
 
1465
 
 
1466
  MUTEX_GETERROR (saved_error);
 
1467
  MUTEX_LOCK ();
 
1468
 
 
1469
  cur    = handles;
 
1470
  loader = loaders;
 
1471
 
 
1472
  /* check whether the module was already opened */
 
1473
  while (cur)
 
1474
    {
 
1475
      /* try to dlopen the program itself? */
 
1476
      if (!cur->info.filename && !filename)
 
1477
        {
 
1478
          break;
 
1479
        }
 
1480
 
 
1481
      if (cur->info.filename && filename
 
1482
          && strcmp (cur->info.filename, filename) == 0)
 
1483
        {
 
1484
          break;
 
1485
        }
 
1486
 
 
1487
      cur = cur->next;
 
1488
    }
 
1489
 
 
1490
  if (cur)
 
1491
    {
 
1492
      ++cur->info.ref_count;
 
1493
      *handle = cur;
 
1494
      goto done;
 
1495
    }
 
1496
 
 
1497
  cur = *handle;
 
1498
  if (filename)
 
1499
    {
 
1500
      LT_DLFREE( cur->info.filename );
 
1501
      cur->info.filename = strdup (filename);
 
1502
      if (!cur->info.filename)
 
1503
        {
 
1504
          MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
1505
          ++errors;
 
1506
          goto done;
 
1507
        }
 
1508
    }
 
1509
  else
 
1510
    {
 
1511
      LT_DLFREE( cur->info.filename );
 
1512
      cur->info.filename = 0;
 
1513
    }
 
1514
 
 
1515
  while (loader)
 
1516
    {
 
1517
      lt_user_data data = loader->dlloader_data;
 
1518
 
 
1519
      cur->module = loader->module_open (data, filename);
 
1520
 
 
1521
      if (cur->module != 0)
 
1522
        {
 
1523
          break;
 
1524
        }
 
1525
      loader = loader->next;
 
1526
    }
 
1527
 
 
1528
  if (!loader)
 
1529
    {
 
1530
      LT_DLFREE (cur->info.filename);
 
1531
      ++errors;
 
1532
      goto done;
 
1533
    }
 
1534
 
 
1535
  cur->loader   = loader;
 
1536
  last_error    = saved_error;
 
1537
  
 
1538
 done:
 
1539
  MUTEX_UNLOCK ();
 
1540
 
 
1541
  return errors;
 
1542
}
 
1543
 
 
1544
static int
 
1545
find_module (handle, dir, libdir, dlname, old_name, installed)
 
1546
     lt_dlhandle *handle;
 
1547
     const char *dir;
 
1548
     const char *libdir;
 
1549
     const char *dlname;
 
1550
     const char *old_name;
 
1551
     int installed;
 
1552
{
 
1553
  int   error;
 
1554
  char  *filename;
 
1555
 
 
1556
  /* try to open the old library first; if it was dlpreopened,
 
1557
     we want the preopened version of it, even if a dlopenable
 
1558
     module is available */
 
1559
  if (old_name && tryall_dlopen(handle, old_name) == 0)
 
1560
    {
 
1561
      return 0;
 
1562
    }
 
1563
 
 
1564
  /* try to open the dynamic library */
 
1565
  if (dlname)
 
1566
    {
 
1567
      size_t len;
 
1568
 
 
1569
      /* try to open the installed module */
 
1570
      if (installed && libdir)
 
1571
        {
 
1572
          len       = strlen (libdir) + 1 + strlen (dlname);
 
1573
          filename  = LT_DLMALLOC (char, 1+ len);
 
1574
 
 
1575
          if (!filename)
 
1576
            {
 
1577
              MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
1578
              return 1;
 
1579
            }
 
1580
 
 
1581
          sprintf (filename, "%s/%s", libdir, dlname);
 
1582
          error = (tryall_dlopen (handle, filename) != 0);
 
1583
          LT_DLFREE (filename);
 
1584
 
 
1585
          if (!error)
 
1586
            {
 
1587
              return 0;
 
1588
            }
 
1589
        }
 
1590
 
 
1591
      /* try to open the not-installed module */
 
1592
      if (!installed)
 
1593
        {
 
1594
          len = (dir ? strlen (dir) : 0) + strlen (objdir) + strlen (dlname);
 
1595
          filename = LT_DLMALLOC (char, 1+ len);
 
1596
 
 
1597
          if (!filename)
 
1598
            {
 
1599
              MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
1600
              return 1;
 
1601
            }
 
1602
 
 
1603
          if (dir)
 
1604
            {
 
1605
              strcpy (filename, dir);
 
1606
            }
 
1607
          else
 
1608
            {
 
1609
              *filename = 0;
 
1610
            }
 
1611
          strcat(filename, objdir);
 
1612
          strcat(filename, dlname);
 
1613
 
 
1614
          error = tryall_dlopen (handle, filename) != 0;
 
1615
          LT_DLFREE (filename);
 
1616
          if (!error)
 
1617
            {
 
1618
              return 0;
 
1619
            }
 
1620
        }
 
1621
 
 
1622
      /* maybe it was moved to another directory */
 
1623
      {
 
1624
        len      = (dir ? strlen (dir) : 0) + strlen (dlname);
 
1625
        filename = LT_DLMALLOC (char, 1+ len);
 
1626
 
 
1627
        if (dir)
 
1628
          {
 
1629
            strcpy (filename, dir);
 
1630
          }
 
1631
        else
 
1632
          {
 
1633
            *filename = 0;
 
1634
          }
 
1635
        strcat(filename, dlname);
 
1636
 
 
1637
        error = (tryall_dlopen (handle, filename) != 0);
 
1638
        LT_DLFREE (filename);
 
1639
        if (!error)
 
1640
          {
 
1641
            return 0;
 
1642
          }
 
1643
      }
 
1644
    }
 
1645
 
 
1646
  return 1;
 
1647
}
 
1648
 
 
1649
static char*
 
1650
canonicalize_path (path)
 
1651
     const char *path;
 
1652
{
 
1653
  char *canonical = 0;
 
1654
 
 
1655
  if (path && *path)
 
1656
    {
 
1657
      char *ptr = strdup (path);
 
1658
      canonical = ptr;
 
1659
 
 
1660
#ifdef LT_DIRSEP_CHAR
 
1661
      /* Avoid this overhead where '/' is the only separator. */
 
1662
      while (ptr = (char*)strchr (ptr, LT_DIRSEP_CHAR))
 
1663
        {
 
1664
          *ptr++ = '/';
 
1665
        }
 
1666
#endif
 
1667
    }
 
1668
 
 
1669
  return canonical;
 
1670
}
 
1671
 
 
1672
static lt_ptr
 
1673
find_file (basename, search_path, pdir, handle)
 
1674
     const char *basename;
 
1675
     const char *search_path;
 
1676
     char **pdir;
 
1677
     lt_dlhandle *handle;
 
1678
{
 
1679
  /* When handle != NULL search a library, otherwise a file
 
1680
     return NULL on failure, otherwise the file/handle.  */
 
1681
 
 
1682
  lt_ptr    result      = 0;
 
1683
  char     *filename    = 0;
 
1684
  int       filenamesize= 0;
 
1685
  int       lenbase     = strlen (basename);
 
1686
  char     *canonical   = 0;
 
1687
  char     *next        = 0;
 
1688
 
 
1689
  MUTEX_LOCK ();
 
1690
 
 
1691
  if (!search_path || !*search_path)
 
1692
    {
 
1693
      MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
 
1694
      goto cleanup;
 
1695
    }
 
1696
 
 
1697
  canonical = canonicalize_path (search_path);
 
1698
  if (!canonical)
 
1699
    {
 
1700
      MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
1701
      goto cleanup;
 
1702
    }
 
1703
 
 
1704
  next = canonical;
 
1705
  while (next)
 
1706
    {
 
1707
      int lendir;
 
1708
      char *cur = next;
 
1709
 
 
1710
      next = (char*)strchr (cur, LT_PATHSEP_CHAR);
 
1711
      if (!next)
 
1712
        {
 
1713
          next = cur + strlen (cur);
 
1714
        }
 
1715
 
 
1716
      lendir = next - cur;
 
1717
      if (*next == LT_PATHSEP_CHAR)
 
1718
        {
 
1719
          ++next;
 
1720
        }
 
1721
      else
 
1722
        {
 
1723
          next = 0;
 
1724
        }
 
1725
 
 
1726
      if (lendir == 0)
 
1727
        {
 
1728
          continue;
 
1729
        }
 
1730
 
 
1731
      if (lendir + 1 + lenbase >= filenamesize)
 
1732
        {
 
1733
          LT_DLFREE (filename);
 
1734
          filenamesize = lendir + 1 + lenbase + 1;
 
1735
          filename = LT_DLMALLOC (char, filenamesize);
 
1736
 
 
1737
          if (!filename)
 
1738
            {
 
1739
              MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
1740
              goto cleanup;
 
1741
            }
 
1742
        }
 
1743
 
 
1744
      strncpy(filename, cur, lendir);
 
1745
      if (filename[lendir-1] != '/')
 
1746
        {
 
1747
          filename[lendir++] = '/';
 
1748
        }
 
1749
      strcpy(filename+lendir, basename);
 
1750
      if (handle)
 
1751
        {
 
1752
          if (tryall_dlopen (handle, filename) == 0)
 
1753
            {
 
1754
              result = (lt_ptr) handle;
 
1755
              goto cleanup;
 
1756
            }
 
1757
        }
 
1758
      else
 
1759
        {
 
1760
          FILE *file = fopen (filename, LT_READTEXT_MODE);
 
1761
          if (file)
 
1762
            {
 
1763
              LT_DLFREE (*pdir);
 
1764
 
 
1765
              filename[lendir] = '\0';
 
1766
              *pdir = strdup(filename);
 
1767
              if (!*pdir)
 
1768
                {
 
1769
                  /* We could have even avoided the strdup,
 
1770
                     but there would be some memory overhead. */
 
1771
                  *pdir = filename;
 
1772
                  filename = 0;
 
1773
                }
 
1774
 
 
1775
              result = (lt_ptr) file;
 
1776
              goto cleanup;
 
1777
            }
 
1778
        }
 
1779
    }
 
1780
 
 
1781
  MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
 
1782
 
 
1783
 cleanup:
 
1784
  LT_DLFREE (filename);
 
1785
  LT_DLFREE (canonical);
 
1786
 
 
1787
  MUTEX_UNLOCK ();
 
1788
 
 
1789
  return result;
 
1790
}
 
1791
 
 
1792
static int
 
1793
load_deplibs(handle, deplibs)
 
1794
     lt_dlhandle handle;
 
1795
     char *deplibs;
 
1796
{
 
1797
#if LTDL_DLOPEN_DEPLIBS
 
1798
  char  *p, *save_search_path;
 
1799
  int   depcount = 0;
 
1800
  int   i;
 
1801
  char  **names = 0;
 
1802
#endif
 
1803
  int   errors = 0;
 
1804
 
 
1805
  handle->depcount = 0;
 
1806
 
 
1807
#if LTDL_DLOPEN_DEPLIBS
 
1808
  if (!deplibs)
 
1809
    {
 
1810
      return errors;
 
1811
    }
 
1812
  ++errors;
 
1813
 
 
1814
  MUTEX_LOCK ();
 
1815
  save_search_path = strdup (user_search_path);
 
1816
  if (user_search_path && !save_search_path)
 
1817
    {
 
1818
      MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
1819
      goto cleanup;
 
1820
    }
 
1821
 
 
1822
  /* extract search paths and count deplibs */
 
1823
  p = deplibs;
 
1824
  while (*p)
 
1825
    {
 
1826
      if (!isspace ((int) *p))
 
1827
        {
 
1828
          char *end = p+1;
 
1829
          while (*end && !isspace((int) *end))
 
1830
            {
 
1831
              ++end;
 
1832
            }
 
1833
 
 
1834
          if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
 
1835
            {
 
1836
              char save = *end;
 
1837
              *end = 0; /* set a temporary string terminator */
 
1838
              if (lt_dladdsearchdir(p+2))
 
1839
                {
 
1840
                  goto cleanup;
 
1841
                }
 
1842
              *end = save;
 
1843
            }
 
1844
          else
 
1845
            {
 
1846
              ++depcount;
 
1847
            }
 
1848
 
 
1849
          p = end;
 
1850
        }
 
1851
      else
 
1852
        {
 
1853
          ++p;
 
1854
        }
 
1855
    }
 
1856
 
 
1857
  /* restore the old search path */
 
1858
  LT_DLFREE (user_search_path);
 
1859
  user_search_path = save_search_path;
 
1860
 
 
1861
  MUTEX_UNLOCK ();
 
1862
 
 
1863
  if (!depcount)
 
1864
    {
 
1865
      errors = 0;
 
1866
      goto cleanup;
 
1867
    }
 
1868
 
 
1869
  names = LT_DLMALLOC (char *, depcount * sizeof (char*));
 
1870
  if (!names)
 
1871
    {
 
1872
      goto cleanup;
 
1873
    }
 
1874
 
 
1875
  /* now only extract the actual deplibs */
 
1876
  depcount = 0;
 
1877
  p = deplibs;
 
1878
  while (*p)
 
1879
    {
 
1880
      if (isspace ((int) *p))
 
1881
        {
 
1882
          ++p;
 
1883
        }
 
1884
      else
 
1885
        {
 
1886
          char *end = p+1;
 
1887
          while (*end && !isspace ((int) *end))
 
1888
            {
 
1889
              ++end;
 
1890
            }
 
1891
 
 
1892
          if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
 
1893
            {
 
1894
              char *name;
 
1895
              char save = *end;
 
1896
              *end = 0; /* set a temporary string terminator */
 
1897
              if (strncmp(p, "-l", 2) == 0)
 
1898
                {
 
1899
                  name = LT_DLMALLOC (char, 3+ /* "lib" */ strlen (p+2) + 1);
 
1900
                  if (name)
 
1901
                    {
 
1902
                      sprintf (name, "lib%s", p+2);
 
1903
                    }
 
1904
                }
 
1905
              else
 
1906
                {
 
1907
                  name = strdup(p);
 
1908
                }
 
1909
 
 
1910
              if (name)
 
1911
                {
 
1912
                  names[depcount++] = name;
 
1913
                }
 
1914
              else
 
1915
                {
 
1916
                  goto cleanup_names;
 
1917
                }
 
1918
              *end = save;
 
1919
            }
 
1920
          p = end;
 
1921
        }
 
1922
    }
 
1923
 
 
1924
  /* load the deplibs (in reverse order)
 
1925
     At this stage, don't worry if the deplibs do not load correctly,
 
1926
     they may already be statically linked into the loading application
 
1927
     for instance.  There will be a more enlightening error message
 
1928
     later on if the loaded module cannot resolve all of its symbols.  */
 
1929
  if (depcount)
 
1930
    {
 
1931
      int       j = 0;
 
1932
 
 
1933
      handle->deplibs = (lt_dlhandle*) LT_DLMALLOC (lt_dlhandle *, depcount);
 
1934
      if (!handle->deplibs)
 
1935
            {
 
1936
          goto cleanup;
 
1937
            }
 
1938
 
 
1939
      for (i = 0; i < depcount; ++i)
 
1940
        {
 
1941
          handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
 
1942
          if (handle->deplibs[j])
 
1943
            {
 
1944
              ++j;
 
1945
            }
 
1946
        }
 
1947
 
 
1948
      handle->depcount  = j;    /* Number of successfully loaded deplibs */
 
1949
      errors            = 0;
 
1950
    }
 
1951
 
 
1952
 cleanup_names:
 
1953
  for (i = 0; i < depcount; ++i)
 
1954
    {
 
1955
      LT_DLFREE (names[i]);
 
1956
    }
 
1957
 
 
1958
 cleanup:
 
1959
  LT_DLFREE (names);
 
1960
#endif
 
1961
 
 
1962
  return errors;
 
1963
}
 
1964
 
 
1965
static int
 
1966
unload_deplibs(handle)
 
1967
     lt_dlhandle handle;
 
1968
{
 
1969
  int i;
 
1970
  int errors = 0;
 
1971
 
 
1972
  if (handle->depcount)
 
1973
    {
 
1974
      for (i = 0; i < handle->depcount; ++i)
 
1975
        {
 
1976
          if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
 
1977
            {
 
1978
              errors += lt_dlclose (handle->deplibs[i]);
 
1979
            }
 
1980
        }
 
1981
    }
 
1982
 
 
1983
  return errors;
 
1984
}
 
1985
 
 
1986
static inline int
 
1987
trim (dest, str)
 
1988
     char **dest;
 
1989
     const char *str;
 
1990
{
 
1991
  /* remove the leading and trailing "'" from str
 
1992
     and store the result in dest */
 
1993
  const char *end   = strrchr (str, '\'');
 
1994
  int   len         = strlen  (str);
 
1995
  char *tmp;
 
1996
 
 
1997
  LT_DLFREE (*dest);
 
1998
 
 
1999
  if (len > 3 && str[0] == '\'')
 
2000
    {
 
2001
      tmp = LT_DLMALLOC (char, end - str);
 
2002
      if (!tmp)
 
2003
        {
 
2004
          last_error = LT_DLSTRERROR (NO_MEMORY);
 
2005
          return 1;
 
2006
        }
 
2007
 
 
2008
      strncpy(tmp, &str[1], (end - str) - 1);
 
2009
      tmp[end-str-1] = '\0';
 
2010
      *dest = tmp;
 
2011
    }
 
2012
  else
 
2013
    {
 
2014
      *dest = 0;
 
2015
    }
 
2016
 
 
2017
  return 0;
 
2018
}
 
2019
 
 
2020
static inline int
 
2021
free_vars( dlname, oldname, libdir, deplibs)
 
2022
     char *dlname;
 
2023
     char *oldname;
 
2024
     char *libdir;
 
2025
     char *deplibs;
 
2026
{
 
2027
  LT_DLFREE (dlname);
 
2028
  LT_DLFREE (oldname);
 
2029
  LT_DLFREE (libdir);
 
2030
  LT_DLFREE (deplibs);
 
2031
 
 
2032
  return 0;
 
2033
}
 
2034
 
 
2035
lt_dlhandle
 
2036
lt_dlopen (filename)
 
2037
     const char *filename;
 
2038
{
 
2039
  lt_dlhandle handle = 0, newhandle;
 
2040
  const char *ext;
 
2041
  const char *saved_error;
 
2042
  char  *canonical = 0, *basename = 0, *dir = 0, *name = 0;
 
2043
 
 
2044
  MUTEX_GETERROR (saved_error);
 
2045
 
 
2046
  /* dlopen self? */
 
2047
  if (!filename)
 
2048
    {
 
2049
      handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
 
2050
      if (!handle)
 
2051
        {
 
2052
          MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2053
          return 0;
 
2054
        }
 
2055
      memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
 
2056
 
 
2057
      handle->info.ref_count    = 0;
 
2058
      handle->depcount          = 0;
 
2059
      handle->deplibs           = 0;
 
2060
      handle->caller_data       = 0;
 
2061
      newhandle                 = handle;
 
2062
 
 
2063
      /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
 
2064
      LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
 
2065
 
 
2066
      if (tryall_dlopen (&newhandle, 0) != 0)
 
2067
        {
 
2068
          LT_DLFREE (handle);
 
2069
          return 0;
 
2070
        }
 
2071
      goto register_handle;
 
2072
    }
 
2073
 
 
2074
  canonical = canonicalize_path (filename);
 
2075
  if (!canonical)
 
2076
    {
 
2077
      MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2078
      LT_DLFREE (handle);
 
2079
      return 0;
 
2080
    }
 
2081
 
 
2082
  /* If the canonical module name is a path (relative or absolute)
 
2083
     then split it into a directory part and a name part.  */
 
2084
  basename = (char*)strrchr (canonical, '/');
 
2085
  if (basename)
 
2086
    {
 
2087
      ++basename;
 
2088
      dir = LT_DLMALLOC (char, basename - canonical + 1);
 
2089
      if (!dir)
 
2090
        {
 
2091
          MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2092
          handle = 0;
 
2093
          goto cleanup;
 
2094
        }
 
2095
 
 
2096
      strncpy (dir, canonical, basename - canonical);
 
2097
      dir[basename - canonical] = '\0';
 
2098
    }
 
2099
  else
 
2100
    {
 
2101
      basename = canonical;
 
2102
    }
 
2103
 
 
2104
  /* Check whether we are opening a libtool module (.la extension).  */
 
2105
  ext = strrchr(basename, '.');
 
2106
  if (ext && strcmp(ext, ".la") == 0)
 
2107
    {
 
2108
      /* this seems to be a libtool module */
 
2109
      FILE     *file = 0;
 
2110
      int       i;
 
2111
      char     *dlname = 0, *old_name = 0;
 
2112
      char     *libdir = 0, *deplibs = 0;
 
2113
      char     *line;
 
2114
      size_t    line_len;
 
2115
      int       error = 0;
 
2116
 
 
2117
      /* if we can't find the installed flag, it is probably an
 
2118
         installed libtool archive, produced with an old version
 
2119
         of libtool */
 
2120
      int       installed = 1;
 
2121
 
 
2122
      /* extract the module name from the file name */
 
2123
      name = LT_DLMALLOC (char, ext - basename + 1);
 
2124
      if (!name)
 
2125
        {
 
2126
          MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2127
          handle = 0;
 
2128
          goto cleanup;
 
2129
      }
 
2130
 
 
2131
    /* canonicalize the module name */
 
2132
    for (i = 0; i < ext - basename; ++i)
 
2133
      {
 
2134
        if (isalnum ((int)(basename[i])))
 
2135
          {
 
2136
            name[i] = basename[i];
 
2137
          }
 
2138
        else
 
2139
          {
 
2140
            name[i] = '_';
 
2141
          }
 
2142
      }
 
2143
 
 
2144
    name[ext - basename] = '\0';
 
2145
 
 
2146
    /* Now try to open the .la file.  If there is no directory name
 
2147
       component, try to find it first in user_search_path and then other
 
2148
       prescribed paths.  Otherwise (or in any case if the module was not
 
2149
       yet found) try opening just the module name as passed.  */
 
2150
    if (!dir)
 
2151
      {
 
2152
        file = (FILE*) find_file(basename, user_search_path, &dir, 0);
 
2153
        if (!file)
 
2154
          {
 
2155
            file = (FILE*) find_file(basename, getenv("LTDL_LIBRARY_PATH"),
 
2156
                                     &dir, 0);
 
2157
          }
 
2158
 
 
2159
#ifdef LTDL_SHLIBPATH_VAR
 
2160
        if (!file)
 
2161
          {
 
2162
            file = (FILE*) find_file(basename, getenv(LTDL_SHLIBPATH_VAR),
 
2163
                                     &dir, 0);
 
2164
          }
 
2165
#endif
 
2166
#ifdef LTDL_SYSSEARCHPATH
 
2167
        if (!file)
 
2168
          {
 
2169
            file = (FILE*) find_file(basename, sys_search_path, &dir, 0);
 
2170
          }
 
2171
#endif
 
2172
      }
 
2173
    if (!file)
 
2174
      {
 
2175
        file = fopen (filename, LT_READTEXT_MODE);
 
2176
      }
 
2177
    if (!file)
 
2178
      {
 
2179
        MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
 
2180
      }
 
2181
 
 
2182
    if (!file)
 
2183
      {
 
2184
        handle = 0;
 
2185
        goto cleanup;
 
2186
      }
 
2187
 
 
2188
    line_len = LT_FILENAME_MAX;
 
2189
    line = LT_DLMALLOC (char, line_len);
 
2190
    if (!line)
 
2191
      {
 
2192
        fclose (file);
 
2193
        MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2194
        handle = 0;
 
2195
        goto cleanup;
 
2196
      }
 
2197
 
 
2198
    /* read the .la file */
 
2199
    while (!feof(file))
 
2200
      {
 
2201
        line[line_len-2] = '\0';
 
2202
        if (!fgets (line, line_len, file))
 
2203
          {
 
2204
            break;
 
2205
          }
 
2206
 
 
2207
        /* Handle the case where we occasionally need to read a line
 
2208
           that is longer than the initial buffer size.  */
 
2209
        while (line[line_len-2] && (!feof (file)))
 
2210
          {
 
2211
            line = LT_DLREALLOC (char, line, line_len *2);
 
2212
            line[line_len*2-2] = '\0';
 
2213
            if (!line || !fgets (&line[line_len -1], (int) line_len +1, file))
 
2214
              {
 
2215
                error = 1;
 
2216
                break;
 
2217
              }
 
2218
            line_len *= 2;
 
2219
          }
 
2220
 
 
2221
        if (error)
 
2222
            break;
 
2223
        if (line[0] == '\n' || line[0] == '#')
 
2224
          {
 
2225
            continue;
 
2226
          }
 
2227
 
 
2228
 
 
2229
#undef  STR_DLNAME
 
2230
#define STR_DLNAME      "dlname="
 
2231
        if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
 
2232
          {
 
2233
            error = trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
 
2234
          }
 
2235
 
 
2236
#undef  STR_OLD_LIBRARY
 
2237
#define STR_OLD_LIBRARY "old_library="
 
2238
        else if (strncmp (line, STR_OLD_LIBRARY,
 
2239
                          sizeof (STR_OLD_LIBRARY) - 1) == 0)
 
2240
          {
 
2241
            error = trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
 
2242
          }
 
2243
#undef  STR_LIBDIR
 
2244
#define STR_LIBDIR      "libdir="
 
2245
        else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
 
2246
          {
 
2247
            error = trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
 
2248
#if defined(_WIN32) && !defined(__CYGWIN__)
 
2249
            win32_mapDir(&libdir);
 
2250
#endif
 
2251
          }
 
2252
 
 
2253
#undef  STR_DL_DEPLIBS
 
2254
#define STR_DL_DEPLIBS  "dependency_libs="
 
2255
        else if (strncmp (line, STR_DL_DEPLIBS,
 
2256
                          sizeof (STR_DL_DEPLIBS) - 1) == 0)
 
2257
          {
 
2258
            error = trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
 
2259
          }
 
2260
        else if (strcmp (line, "installed=yes\n") == 0)
 
2261
          {
 
2262
            installed = 1;
 
2263
          }
 
2264
        else if (strcmp (line, "installed=no\n") == 0)
 
2265
          {
 
2266
            installed = 0;
 
2267
          }
 
2268
 
 
2269
#undef  STR_LIBRARY_NAMES
 
2270
#define STR_LIBRARY_NAMES "library_names="
 
2271
        else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
 
2272
                                      sizeof (STR_LIBRARY_NAMES) - 1) == 0)
 
2273
          {
 
2274
            char *last_libname;
 
2275
            error = trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
 
2276
            if (! error && dlname &&
 
2277
                (last_libname = (char*)strrchr (dlname, ' ')) != NULL)
 
2278
              {
 
2279
                last_libname = strdup (last_libname + 1);
 
2280
                LT_DLMEM_REASSIGN (dlname, last_libname);
 
2281
              }
 
2282
          }
 
2283
 
 
2284
        if (error)
 
2285
          {
 
2286
            break;
 
2287
          }
 
2288
      }
 
2289
 
 
2290
    fclose (file);
 
2291
    LT_DLFREE (line);
 
2292
 
 
2293
    /* allocate the handle */
 
2294
    handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
 
2295
    if (!handle || error)
 
2296
      {
 
2297
        LT_DLFREE (handle);
 
2298
        if (!error)
 
2299
          {
 
2300
            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2301
          }
 
2302
 
 
2303
        free_vars (dlname, old_name, libdir, deplibs);
 
2304
        /* handle is already set to 0 */
 
2305
        goto cleanup;
 
2306
      }
 
2307
    memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
 
2308
 
 
2309
    handle->info.ref_count = 0;
 
2310
    if (load_deplibs (handle, deplibs) == 0)
 
2311
      {
 
2312
        newhandle = handle;
 
2313
        /* find_module may replace newhandle */
 
2314
        if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
 
2315
          {
 
2316
            unload_deplibs (handle);
 
2317
            error = 1;
 
2318
          }
 
2319
      }
 
2320
    else
 
2321
      {
 
2322
        error = 1;
 
2323
      }
 
2324
 
 
2325
    free_vars (dlname, old_name, libdir, deplibs);
 
2326
    if (error)
 
2327
      {
 
2328
        LT_DLFREE (handle);
 
2329
        goto cleanup;
 
2330
      }
 
2331
 
 
2332
    if (handle != newhandle)
 
2333
      {
 
2334
        unload_deplibs (handle);
 
2335
      } else {
 
2336
        LT_DLFREE( handle->info.filename );
 
2337
        handle->info.filename = strdup( filename );
 
2338
      }
 
2339
    }
 
2340
  else
 
2341
    {
 
2342
      /* not a libtool module */
 
2343
      handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
 
2344
      if (!handle)
 
2345
        {
 
2346
          MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2347
          /* handle is already set to 0 */
 
2348
          goto cleanup;
 
2349
        }
 
2350
      memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
 
2351
      handle->info.ref_count = 0;
 
2352
      /* non-libtool modules don't have dependencies */
 
2353
      handle->depcount    = 0;
 
2354
      handle->deplibs     = 0;
 
2355
      newhandle           = handle;
 
2356
 
 
2357
      /* If the module has no directory name component, try to find it
 
2358
         first in user_search_path and then other prescribed paths.
 
2359
         Otherwise (or in any case if the module was not yet found) try
 
2360
         opening just the module name as passed.  */
 
2361
      if ((dir || (!find_file (basename, user_search_path, 0, &newhandle)
 
2362
                      && !find_file (basename, getenv ("LTDL_LIBRARY_PATH"),
 
2363
                                     0, &newhandle)
 
2364
#ifdef LTDL_SHLIBPATH_VAR
 
2365
                      && !find_file (basename, getenv (LTDL_SHLIBPATH_VAR),
 
2366
                                     0, &newhandle)
 
2367
#endif
 
2368
#ifdef LTDL_SYSSEARCHPATH
 
2369
                      && !find_file (basename, sys_search_path, 0, &newhandle)
 
2370
#endif
 
2371
                   )) && tryall_dlopen (&newhandle, filename))
 
2372
        {
 
2373
          LT_DLFREE (handle);
 
2374
          goto cleanup;
 
2375
        }
 
2376
    }
 
2377
 
 
2378
 register_handle:
 
2379
  LT_DLMEM_REASSIGN (handle, newhandle);
 
2380
 
 
2381
  if (handle->info.ref_count == 0)
 
2382
    {
 
2383
      handle->info.ref_count    = 1;
 
2384
      handle->info.name         = name;
 
2385
      handle->next              = handles;
 
2386
 
 
2387
      MUTEX_LOCK ();
 
2388
      handles                   = handle;
 
2389
      MUTEX_UNLOCK ();
 
2390
 
 
2391
      name = 0; /* don't free this during `cleanup' */
 
2392
    }
 
2393
 
 
2394
  MUTEX_SETERROR (saved_error);
 
2395
 
 
2396
 cleanup:
 
2397
  LT_DLFREE (dir);
 
2398
  LT_DLFREE (name);
 
2399
  LT_DLFREE (canonical);
 
2400
 
 
2401
  return handle;
 
2402
}
 
2403
 
 
2404
lt_dlhandle
 
2405
lt_dlopenext (filename)
 
2406
     const char *filename;
 
2407
{
 
2408
  lt_dlhandle handle;
 
2409
  char  *tmp;
 
2410
  int   len;
 
2411
  const char *saved_error;
 
2412
 
 
2413
  MUTEX_GETERROR (saved_error);
 
2414
 
 
2415
  if (!filename)
 
2416
    {
 
2417
      return lt_dlopen (filename);
 
2418
    }
 
2419
 
 
2420
  len = strlen (filename);
 
2421
  if (!len)
 
2422
    {
 
2423
      MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
 
2424
      return 0;
 
2425
    }
 
2426
 
 
2427
  tmp = LT_DLMALLOC (char, len+4);
 
2428
  if (!tmp)
 
2429
    {
 
2430
      MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2431
      return 0;
 
2432
    }
 
2433
  strcpy (tmp, filename);
 
2434
 
 
2435
#ifdef _AIX
 
2436
  tmp[len] = '\0';
 
2437
 
 
2438
  /* find by info.name in the list */
 
2439
  handle = sys_dl_search_by_name( tmp );
 
2440
  if (handle)
 
2441
    {
 
2442
      if( LT_DLGET_FLAG (handle, LT_DLNOTFOUND_FLAG) )
 
2443
        {
 
2444
          /* don't search libm and libstdc++ over and over again,
 
2445
           * they are hardlinked and symbols are exported by the
 
2446
           * executable */
 
2447
          MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
 
2448
          LT_DLFREE (tmp);
 
2449
          return 0;
 
2450
        }
 
2451
      MUTEX_SETERROR (saved_error);
 
2452
      LT_DLFREE (tmp);
 
2453
      return handle;
 
2454
    }
 
2455
#endif /* _AIX */
 
2456
 
 
2457
  /* try "filename.la" */
 
2458
  strcat (tmp, ".la");
 
2459
  handle = lt_dlopen (tmp);
 
2460
  if (handle)
 
2461
    {
 
2462
      MUTEX_SETERROR (saved_error);
 
2463
      LT_DLFREE (tmp);
 
2464
      return handle;
 
2465
    }
 
2466
 
 
2467
 
 
2468
#ifdef _AIX
 
2469
  tmp[len] = '\0'; /* delete the ".la" again.  */
 
2470
  
 
2471
  /* versioned shared objects can be in .a's */
 
2472
  strcat(tmp, ".a");
 
2473
  handle = lt_dlopen (tmp);
 
2474
  if (handle)
 
2475
    {
 
2476
      MUTEX_SETERROR (saved_error);
 
2477
      LT_DLFREE (tmp);
 
2478
      return handle;
 
2479
    }
 
2480
#endif /* _AIX */
 
2481
 
 
2482
#ifdef LTDL_SHLIB_EXT
 
2483
  /* try "filename.EXT" */
 
2484
  if (strlen(shlib_ext) > 3)
 
2485
    {
 
2486
      LT_DLFREE (tmp);
 
2487
      tmp = LT_DLMALLOC (char, len + strlen (shlib_ext) + 1);
 
2488
      if (!tmp)
 
2489
        {
 
2490
          MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2491
          return 0;
 
2492
        }
 
2493
      strcpy (tmp, filename);
 
2494
    }
 
2495
  else
 
2496
    {
 
2497
      tmp[len] = '\0';
 
2498
    }
 
2499
 
 
2500
  strcat(tmp, shlib_ext);
 
2501
  handle = lt_dlopen (tmp);
 
2502
  if (handle)
 
2503
    {
 
2504
      MUTEX_SETERROR (saved_error);
 
2505
      LT_DLFREE (tmp);
 
2506
      return handle;
 
2507
    }
 
2508
#endif
 
2509
 
 
2510
  /* try the normal file name */
 
2511
  handle = lt_dlopen (filename);
 
2512
  if (handle)
 
2513
    {
 
2514
      return handle;
 
2515
    }
 
2516
 
 
2517
#ifdef _AIX
 
2518
  /* put into the can't be found list */
 
2519
  tmp[len] = '\0';
 
2520
  sys_dl_not_found_entry( tmp );
 
2521
#endif /* _AIX */
 
2522
 
 
2523
  MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
 
2524
  LT_DLFREE (tmp);
 
2525
  return 0;
 
2526
}
 
2527
 
 
2528
int
 
2529
lt_dlclose (handle)
 
2530
     lt_dlhandle handle;
 
2531
{
 
2532
  lt_dlhandle cur, last;
 
2533
  int errors = 0;
 
2534
 
 
2535
  MUTEX_LOCK ();
 
2536
 
 
2537
  /* check whether the handle is valid */
 
2538
  last = cur = handles;
 
2539
  while (cur && handle != cur)
 
2540
    {
 
2541
      last = cur;
 
2542
      cur = cur->next;
 
2543
    }
 
2544
 
 
2545
  if (!cur)
 
2546
    {
 
2547
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
 
2548
      ++errors;
 
2549
      goto done;
 
2550
    }
 
2551
 
 
2552
  handle->info.ref_count--;
 
2553
 
 
2554
  /* Note that even with resident modules, we must track the ref_count
 
2555
     correctly incase the user decides to reset the residency flag
 
2556
     later (even though the API makes no provision for that at the
 
2557
     moment).  */
 
2558
  if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
 
2559
    {
 
2560
      lt_user_data data = handle->loader->dlloader_data;
 
2561
 
 
2562
      if (handle != handles)
 
2563
        {
 
2564
          last->next = handle->next;
 
2565
        }
 
2566
      else
 
2567
        {
 
2568
          handles = handle->next;
 
2569
        }
 
2570
 
 
2571
      errors += handle->loader->module_close (data, handle->module);
 
2572
      errors += unload_deplibs(handle);
 
2573
 
 
2574
      LT_DLFREE (handle->info.filename);
 
2575
      LT_DLFREE (handle->info.name);
 
2576
      LT_DLFREE (handle);
 
2577
 
 
2578
      goto done;
 
2579
    }
 
2580
 
 
2581
  if (LT_DLIS_RESIDENT (handle))
 
2582
    {
 
2583
      MUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
 
2584
      ++errors;
 
2585
    }
 
2586
 
 
2587
 done:
 
2588
  MUTEX_UNLOCK ();
 
2589
 
 
2590
  return errors;
 
2591
}
 
2592
 
 
2593
lt_ptr
 
2594
lt_dlsym (handle, symbol)
 
2595
     lt_dlhandle handle;
 
2596
     const char *symbol;
 
2597
{
 
2598
  int   lensym;
 
2599
  char  lsym[LT_SYMBOL_LENGTH];
 
2600
  char  *sym;
 
2601
  lt_ptr address;
 
2602
  lt_user_data data;
 
2603
 
 
2604
  if (!handle)
 
2605
    {
 
2606
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
 
2607
      return 0;
 
2608
    }
 
2609
 
 
2610
  if (!symbol)
 
2611
    {
 
2612
      MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
 
2613
      return 0;
 
2614
    }
 
2615
 
 
2616
  lensym = strlen(symbol);
 
2617
  if (handle->loader->sym_prefix)
 
2618
    {
 
2619
      lensym += strlen(handle->loader->sym_prefix);
 
2620
    }
 
2621
 
 
2622
  if (handle->info.name)
 
2623
    {
 
2624
      lensym += strlen(handle->info.name);
 
2625
    }
 
2626
 
 
2627
  if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
 
2628
    {
 
2629
      sym = lsym;
 
2630
    }
 
2631
  else
 
2632
    {
 
2633
      sym = LT_DLMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
 
2634
    }
 
2635
 
 
2636
  if (!sym)
 
2637
    {
 
2638
      MUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
 
2639
      return 0;
 
2640
    }
 
2641
 
 
2642
  data = handle->loader->dlloader_data;
 
2643
  if (handle->info.name)
 
2644
    {
 
2645
      const char *saved_error;
 
2646
 
 
2647
      MUTEX_GETERROR (saved_error);
 
2648
 
 
2649
      /* this is a libtool module */
 
2650
      if (handle->loader->sym_prefix)
 
2651
        {
 
2652
          strcpy(sym, handle->loader->sym_prefix);
 
2653
          strcat(sym, handle->info.name);
 
2654
        }
 
2655
      else
 
2656
        {
 
2657
          strcpy(sym, handle->info.name);
 
2658
        }
 
2659
 
 
2660
      strcat(sym, "_LTX_");
 
2661
      strcat(sym, symbol);
 
2662
 
 
2663
      /* try "modulename_LTX_symbol" */
 
2664
      address = handle->loader->find_sym (data, handle->module, sym);
 
2665
      if (address)
 
2666
        {
 
2667
          if (sym != lsym)
 
2668
            {
 
2669
              LT_DLFREE (sym);
 
2670
            }
 
2671
          return address;
 
2672
        }
 
2673
      MUTEX_SETERROR (saved_error);
 
2674
    }
 
2675
 
 
2676
  /* otherwise try "symbol" */
 
2677
  if (handle->loader->sym_prefix)
 
2678
    {
 
2679
      strcpy(sym, handle->loader->sym_prefix);
 
2680
      strcat(sym, symbol);
 
2681
    }
 
2682
  else
 
2683
    {
 
2684
      strcpy(sym, symbol);
 
2685
    }
 
2686
 
 
2687
  address = handle->loader->find_sym (data, handle->module, sym);
 
2688
  if (sym != lsym)
 
2689
    {
 
2690
      LT_DLFREE (sym);
 
2691
    }
 
2692
 
 
2693
  return address;
 
2694
}
 
2695
 
 
2696
const char *
 
2697
lt_dlerror ()
 
2698
{
 
2699
  const char *error;
 
2700
 
 
2701
  MUTEX_GETERROR (error);
 
2702
  MUTEX_SETERROR (0);
 
2703
 
 
2704
  return error;
 
2705
}
 
2706
 
 
2707
int
 
2708
lt_dladdsearchdir (search_dir)
 
2709
     const char *search_dir;
 
2710
{
 
2711
  int errors = 0;
 
2712
 
 
2713
  if (!search_dir || !strlen(search_dir))
 
2714
    {
 
2715
      return errors;
 
2716
    }
 
2717
 
 
2718
  MUTEX_LOCK ();
 
2719
  if (!user_search_path)
 
2720
    {
 
2721
      user_search_path = strdup (search_dir);
 
2722
      if (!user_search_path)
 
2723
        {
 
2724
          last_error = LT_DLSTRERROR (NO_MEMORY);
 
2725
          ++errors;
 
2726
        }
 
2727
    }
 
2728
  else
 
2729
    {
 
2730
      size_t len = strlen (user_search_path) + 1 + strlen (search_dir);
 
2731
      char  *new_search_path = LT_DLMALLOC (char, 1+ len);
 
2732
 
 
2733
      if (!new_search_path)
 
2734
        {
 
2735
          MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2736
          ++errors;
 
2737
        }
 
2738
      else
 
2739
        {
 
2740
          sprintf (new_search_path, "%s%c%s", user_search_path,
 
2741
                   LT_PATHSEP_CHAR, search_dir);
 
2742
 
 
2743
          LT_DLMEM_REASSIGN (user_search_path, new_search_path);
 
2744
        }
 
2745
    }
 
2746
  MUTEX_UNLOCK ();
 
2747
 
 
2748
  return errors;
 
2749
}
 
2750
 
 
2751
int
 
2752
lt_dlsetsearchpath (search_path)
 
2753
     const char *search_path;
 
2754
{
 
2755
  int errors = 0;
 
2756
 
 
2757
  MUTEX_LOCK ();
 
2758
  LT_DLFREE (user_search_path);
 
2759
  MUTEX_UNLOCK ();
 
2760
 
 
2761
  if (!search_path || !strlen (search_path))
 
2762
    {
 
2763
      return errors;
 
2764
    }
 
2765
 
 
2766
  MUTEX_LOCK ();
 
2767
  user_search_path = strdup (search_path);
 
2768
  if (!user_search_path)
 
2769
    {
 
2770
      ++errors;
 
2771
    }
 
2772
  MUTEX_UNLOCK ();
 
2773
 
 
2774
  return errors;
 
2775
}
 
2776
 
 
2777
const char *
 
2778
lt_dlgetsearchpath ()
 
2779
{
 
2780
  const char *saved_path;
 
2781
 
 
2782
  MUTEX_LOCK ();
 
2783
  saved_path = user_search_path;
 
2784
  MUTEX_UNLOCK ();
 
2785
 
 
2786
  return saved_path;
 
2787
}
 
2788
 
 
2789
int
 
2790
lt_dlmakeresident (handle)
 
2791
     lt_dlhandle handle;
 
2792
{
 
2793
  int errors = 0;
 
2794
 
 
2795
  if (!handle)
 
2796
    {
 
2797
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
 
2798
      ++errors;
 
2799
    }
 
2800
  else
 
2801
    {
 
2802
      LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
 
2803
    }
 
2804
 
 
2805
  return errors;
 
2806
}
 
2807
 
 
2808
int
 
2809
lt_dlisresident (handle)
 
2810
     lt_dlhandle handle;
 
2811
{
 
2812
  if (!handle)
 
2813
    {
 
2814
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
 
2815
      return -1;
 
2816
    }
 
2817
 
 
2818
  return LT_DLIS_RESIDENT (handle);
 
2819
}
 
2820
 
 
2821
 
 
2822
 
 
2823
 
 
2824
/* --- MODULE INFORMATION --- */
 
2825
 
 
2826
const lt_dlinfo *
 
2827
lt_dlgetinfo (handle)
 
2828
     lt_dlhandle handle;
 
2829
{
 
2830
  if (!handle)
 
2831
    {
 
2832
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
 
2833
      return 0;
 
2834
    }
 
2835
 
 
2836
  return &(handle->info);
 
2837
}
 
2838
 
 
2839
lt_dlhandle
 
2840
lt_dlhandle_next (place)
 
2841
     lt_dlhandle place;
 
2842
{
 
2843
  return place ? place->next : (lt_dlhandle) 0;
 
2844
}
 
2845
 
 
2846
int
 
2847
lt_dlforeach (func, data)
 
2848
     int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
 
2849
     lt_ptr data;
 
2850
{
 
2851
  int errors = 0;
 
2852
  lt_dlhandle cur;
 
2853
 
 
2854
  MUTEX_LOCK ();
 
2855
 
 
2856
  cur = handles;
 
2857
  while (cur)
 
2858
    {
 
2859
      lt_dlhandle tmp = cur;
 
2860
 
 
2861
      cur = cur->next;
 
2862
      if ((*func) (tmp, data))
 
2863
        {
 
2864
          ++errors;
 
2865
          break;
 
2866
        }
 
2867
    }
 
2868
 
 
2869
  MUTEX_UNLOCK ();
 
2870
 
 
2871
  return errors;
 
2872
}
 
2873
 
 
2874
lt_dlcaller_id
 
2875
lt_dlcaller_register ()
 
2876
{
 
2877
  static int last_caller_id = -1;
 
2878
  int result;
 
2879
 
 
2880
  MUTEX_LOCK ();
 
2881
  result = ++last_caller_id;
 
2882
  MUTEX_UNLOCK ();
 
2883
 
 
2884
  return result;
 
2885
}
 
2886
 
 
2887
#define N_ELEMENTS(a)   (sizeof(a) / sizeof(*(a)))
 
2888
 
 
2889
lt_ptr
 
2890
lt_dlcaller_set_data (key, handle, data)
 
2891
     lt_dlcaller_id key;
 
2892
     lt_dlhandle handle;
 
2893
     lt_ptr data;
 
2894
{
 
2895
  int n_elements = 0;
 
2896
  lt_ptr stale = (lt_ptr) 0;
 
2897
  int i;
 
2898
 
 
2899
  /* This needs to be locked so that the caller data can be updated
 
2900
     simultaneously by different threads.  */
 
2901
  MUTEX_LOCK ();
 
2902
 
 
2903
  if (handle->caller_data)
 
2904
    n_elements = N_ELEMENTS (handle->caller_data);
 
2905
 
 
2906
  for (i = 0; i < n_elements; ++i)
 
2907
    {
 
2908
      if (handle->caller_data[i].key == key)
 
2909
        {
 
2910
          stale = handle->caller_data[i].data;
 
2911
          break;
 
2912
        }
 
2913
    }
 
2914
 
 
2915
  /* Ensure that there is enough room in this handle's caller_data
 
2916
     array to accept a new element.  */
 
2917
  if (i == n_elements)
 
2918
    {
 
2919
      lt_caller_data *temp
 
2920
        = LT_DLREALLOC (lt_caller_data, handle->caller_data, 1+ n_elements);
 
2921
 
 
2922
      if (temp == 0)
 
2923
        {
 
2924
          MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
2925
          stale =  (lt_ptr) 0;
 
2926
          goto done;
 
2927
        }
 
2928
      else
 
2929
        {
 
2930
          handle->caller_data = temp;
 
2931
        }
 
2932
 
 
2933
      /* We only need this if we needed to allocate a new caller_data.  */
 
2934
      handle->caller_data[i].key  = key;
 
2935
    }
 
2936
 
 
2937
  handle->caller_data[i].data = data;
 
2938
 
 
2939
 done:
 
2940
  MUTEX_UNLOCK ();
 
2941
 
 
2942
  return stale;
 
2943
}
 
2944
 
 
2945
lt_ptr
 
2946
lt_dlcaller_get_data  (key, handle)
 
2947
     lt_dlcaller_id key;
 
2948
     lt_dlhandle handle;
 
2949
{
 
2950
  lt_ptr result = (lt_ptr) 0;
 
2951
  int n_elements = 0;
 
2952
 
 
2953
  /* This needs to be locked so that the caller data isn't updated by
 
2954
     another thread part way through this function.  */
 
2955
  MUTEX_LOCK ();
 
2956
 
 
2957
  if (handle->caller_data)
 
2958
    n_elements = N_ELEMENTS (handle->caller_data);
 
2959
 
 
2960
  /* Locate the index of the element with a matching KEY.  */
 
2961
  {
 
2962
    int i;
 
2963
    for (i = 0; i < n_elements; ++i)
 
2964
      {
 
2965
        if (handle->caller_data[i].key == key)
 
2966
          {
 
2967
            result = handle->caller_data[i].data;
 
2968
            break;
 
2969
          }
 
2970
      }
 
2971
  }
 
2972
 
 
2973
  MUTEX_UNLOCK ();
 
2974
 
 
2975
  return result;
 
2976
}
 
2977
 
 
2978
 
 
2979
 
 
2980
/* --- USER MODULE LOADER API --- */
 
2981
 
 
2982
 
 
2983
int
 
2984
lt_dlloader_add (place, dlloader, loader_name)
 
2985
     lt_dlloader *place;
 
2986
     const struct lt_user_dlloader *dlloader;
 
2987
     const char *loader_name;
 
2988
{
 
2989
  int errors = 0;
 
2990
  lt_dlloader *node = 0, *ptr = 0;
 
2991
 
 
2992
  if ((dlloader == 0)   /* diagnose null parameters */
 
2993
      || (dlloader->module_open == 0)
 
2994
      || (dlloader->module_close == 0)
 
2995
      || (dlloader->find_sym == 0))
 
2996
    {
 
2997
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
 
2998
      return 1;
 
2999
    }
 
3000
 
 
3001
  /* Create a new dlloader node with copies of the user callbacks.  */
 
3002
  node = LT_DLMALLOC (lt_dlloader, 1);
 
3003
  if (node == 0)
 
3004
    {
 
3005
      MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
3006
      return 1;
 
3007
    }
 
3008
 
 
3009
  node->next            = 0;
 
3010
  node->loader_name     = loader_name;
 
3011
  node->sym_prefix      = dlloader->sym_prefix;
 
3012
  node->dlloader_exit   = dlloader->dlloader_exit;
 
3013
  node->module_open     = dlloader->module_open;
 
3014
  node->module_close    = dlloader->module_close;
 
3015
  node->find_sym        = dlloader->find_sym;
 
3016
  node->dlloader_data   = dlloader->dlloader_data;
 
3017
 
 
3018
  MUTEX_LOCK ();
 
3019
  if (!loaders)
 
3020
    {
 
3021
      /* If there are no loaders, NODE becomes the list! */
 
3022
      loaders = node;
 
3023
    }
 
3024
  else if (!place)
 
3025
    {
 
3026
      /* If PLACE is not set, add NODE to the end of the
 
3027
         LOADERS list. */
 
3028
      for (ptr = loaders; ptr->next; ptr = ptr->next)
 
3029
        {
 
3030
          /*NOWORK*/;
 
3031
        }
 
3032
 
 
3033
      ptr->next = node;
 
3034
    }
 
3035
  else if (loaders == place)
 
3036
    {
 
3037
      /* If PLACE is the first loader, NODE goes first. */
 
3038
      node->next = place;
 
3039
      loaders = node;
 
3040
    }
 
3041
  else
 
3042
    {
 
3043
      /* Find the node immediately preceding PLACE. */
 
3044
      for (ptr = loaders; ptr->next != place; ptr = ptr->next)
 
3045
        {
 
3046
          /*NOWORK*/;
 
3047
        }
 
3048
 
 
3049
      if (ptr->next != place)
 
3050
        {
 
3051
          last_error = LT_DLSTRERROR (INVALID_LOADER);
 
3052
          ++errors;
 
3053
        }
 
3054
      else
 
3055
        {
 
3056
          /* Insert NODE between PTR and PLACE. */
 
3057
          node->next = place;
 
3058
          ptr->next  = node;
 
3059
        }
 
3060
    }
 
3061
 
 
3062
  MUTEX_UNLOCK ();
 
3063
 
 
3064
  return errors;
 
3065
}
 
3066
 
 
3067
int
 
3068
lt_dlloader_remove (loader_name)
 
3069
     const char *loader_name;
 
3070
{
 
3071
  lt_dlloader *place = lt_dlloader_find (loader_name);
 
3072
  lt_dlhandle handle;
 
3073
  int errors = 0;
 
3074
 
 
3075
  if (!place)
 
3076
    {
 
3077
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
 
3078
      return 1;
 
3079
    }
 
3080
 
 
3081
  MUTEX_LOCK ();
 
3082
 
 
3083
  /* Fail if there are any open modules which use this loader. */
 
3084
  for  (handle = handles; handle; handle = handle->next)
 
3085
    {
 
3086
      if (handle->loader == place)
 
3087
        {
 
3088
          MUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
 
3089
          ++errors;
 
3090
          goto done;
 
3091
        }
 
3092
    }
 
3093
 
 
3094
  if (place == loaders)
 
3095
    {
 
3096
      /* PLACE is the first loader in the list. */
 
3097
      loaders = loaders->next;
 
3098
    }
 
3099
  else
 
3100
    {
 
3101
      /* Find the loader before the one being removed. */
 
3102
      lt_dlloader *prev;
 
3103
      for (prev = loaders; prev->next; prev = prev->next)
 
3104
        {
 
3105
          if (!strcmp (prev->next->loader_name, loader_name))
 
3106
            {
 
3107
              break;
 
3108
            }
 
3109
        }
 
3110
 
 
3111
      place = prev->next;
 
3112
      prev->next = prev->next->next;
 
3113
    }
 
3114
 
 
3115
  if (place->dlloader_exit)
 
3116
    {
 
3117
      errors = place->dlloader_exit (place->dlloader_data);
 
3118
    }
 
3119
 
 
3120
  LT_DLFREE (place);
 
3121
 
 
3122
 done:
 
3123
  MUTEX_UNLOCK ();
 
3124
 
 
3125
  return errors;
 
3126
}
 
3127
 
 
3128
lt_dlloader *
 
3129
lt_dlloader_next (place)
 
3130
     lt_dlloader *place;
 
3131
{
 
3132
  lt_dlloader *next;
 
3133
 
 
3134
  MUTEX_LOCK ();
 
3135
  next = place ? place->next : loaders;
 
3136
  MUTEX_UNLOCK ();
 
3137
 
 
3138
  return next;
 
3139
}
 
3140
 
 
3141
const char *
 
3142
lt_dlloader_name (place)
 
3143
     lt_dlloader *place;
 
3144
{
 
3145
  const char *name = 0;
 
3146
 
 
3147
  if (place)
 
3148
    {
 
3149
      MUTEX_LOCK ();
 
3150
      name = place ? place->loader_name : 0;
 
3151
      MUTEX_UNLOCK ();
 
3152
    }
 
3153
  else
 
3154
    {
 
3155
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
 
3156
    }
 
3157
 
 
3158
  return name;
 
3159
}
 
3160
 
 
3161
lt_user_data *
 
3162
lt_dlloader_data (place)
 
3163
     lt_dlloader *place;
 
3164
{
 
3165
  lt_user_data *data = 0;
 
3166
 
 
3167
  if (place)
 
3168
    {
 
3169
      MUTEX_LOCK ();
 
3170
      data = place ? &(place->dlloader_data) : 0;
 
3171
      MUTEX_UNLOCK ();
 
3172
    }
 
3173
  else
 
3174
    {
 
3175
      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
 
3176
    }
 
3177
 
 
3178
  return data;
 
3179
}
 
3180
 
 
3181
lt_dlloader *
 
3182
lt_dlloader_find (loader_name)
 
3183
     const char *loader_name;
 
3184
{
 
3185
  lt_dlloader *place = 0;
 
3186
 
 
3187
  MUTEX_LOCK ();
 
3188
  for (place = loaders; place; place = place->next)
 
3189
    {
 
3190
      if (strcmp (place->loader_name, loader_name) == 0)
 
3191
        {
 
3192
          break;
 
3193
        }
 
3194
    }
 
3195
  MUTEX_UNLOCK ();
 
3196
 
 
3197
  return place;
 
3198
}
 
3199
 
 
3200
#ifdef _AIX
 
3201
 
 
3202
/* #define DBG_PRNT(a) fprintf a ; */
 
3203
#define DBG_PRNT(a)
 
3204
 
 
3205
static void
 
3206
sys_dl_debug_print_loaded( const char* filename )
 
3207
{
 
3208
    int                    ret;
 
3209
    static unsigned char   buffer[1024*1024];
 
3210
    struct ld_info*        info;
 
3211
 
 
3212
    ret = loadquery( L_GETINFO, buffer, 1024*1024 );
 
3213
    if( ret >= 0 )
 
3214
      {
 
3215
        DBG_PRNT((stderr, "%d: Successfully loaded %s\n",
 
3216
                __LINE__, filename ))
 
3217
        info = (struct ld_info*)buffer;
 
3218
        do
 
3219
          {
 
3220
            const char* c;
 
3221
            const char* d;
 
3222
            c = info->ldinfo_filename;
 
3223
            d = &c[strlen(c)];
 
3224
            d++;
 
3225
            DBG_PRNT((stderr, "%d: path name %s, member name %s\n",
 
3226
                    __LINE__,
 
3227
                    c,d))
 
3228
            info = (struct ld_info*)(((char*)info)+info->ldinfo_next);
 
3229
          }
 
3230
        while( info->ldinfo_next != 0 );
 
3231
      }
 
3232
    else if( errno == ENOMEM )
 
3233
      {
 
3234
        DBG_PRNT((stderr, "%d: Successfully loaded %s, loadquery needs larger buffer\n",
 
3235
                __LINE__, filename ))
 
3236
      }
 
3237
    else
 
3238
      {
 
3239
        DBG_PRNT((stderr, "Loadquery failure\n"))
 
3240
      }
 
3241
}
 
3242
 
 
3243
static void
 
3244
sys_dl_debug_print_handle( lt_dlhandle handle )
 
3245
{
 
3246
    DBG_PRNT((stderr," > next          = %ld\n", (long)handle->next ))
 
3247
    DBG_PRNT((stderr," > loader        = %ld\n", (long)handle->loader ))
 
3248
    DBG_PRNT((stderr," > info.filename = %s\n", handle->info.filename ))
 
3249
    DBG_PRNT((stderr," > info.name     = %s\n", handle->info.name ))
 
3250
    DBG_PRNT((stderr," > info.ref_count= %d\n", handle->info.ref_count ))
 
3251
    DBG_PRNT((stderr," > depcount      = %d\n", handle->depcount ))
 
3252
    DBG_PRNT((stderr," > resident flags %s\n",
 
3253
            (LT_DLGET_FLAG (handle, LT_DLRESIDENT_FLAG)?"yes":"no")))
 
3254
    DBG_PRNT((stderr," > not found flags %s\n",
 
3255
            (LT_DLGET_FLAG (handle, LT_DLNOTFOUND_FLAG)?"yes":"no")))
 
3256
}
 
3257
 
 
3258
static void
 
3259
sys_dl_init( )
 
3260
{
 
3261
  char*           buffer = NULL;
 
3262
  size_t          buf_size = 512;
 
3263
  int             ret;
 
3264
  const char*     libname;
 
3265
  const char*     modname;
 
3266
  struct ld_info* info;
 
3267
  lt_dlhandle     cur;
 
3268
  lt_dlhandle     handle;
 
3269
  int             already_listed;
 
3270
  const char*     last_slash;
 
3271
  const char*     last_dot;
 
3272
 
 
3273
  do
 
3274
    {
 
3275
      buf_size *= 2;
 
3276
      if( buffer != NULL ) LT_DLFREE( buffer );
 
3277
      buffer = LT_DLMALLOC( char, buf_size );
 
3278
      ret = loadquery( L_GETINFO, buffer, buf_size );
 
3279
    }
 
3280
  while( ret==-1 && errno==ENOMEM );
 
3281
 
 
3282
  if( ret >= 0 )
 
3283
    {
 
3284
      info = (struct ld_info*)buffer;
 
3285
      do
 
3286
        {
 
3287
          libname        = info->ldinfo_filename;
 
3288
          modname        = &libname[strlen(libname)];
 
3289
          modname        += 1;
 
3290
          already_listed = 0;
 
3291
 
 
3292
          cur = handles;
 
3293
          while (cur)
 
3294
            {
 
3295
              if( cur->info.filename &&
 
3296
                  !strcmp( cur->info.filename, libname ) )
 
3297
                {
 
3298
                  already_listed = 1;
 
3299
                  break;
 
3300
                }
 
3301
              cur = cur->next;
 
3302
            }
 
3303
 
 
3304
          if( already_listed == 0 )
 
3305
            {
 
3306
              handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
 
3307
              if (!handle)
 
3308
                {
 
3309
                  MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
3310
                  LT_DLFREE( buffer );
 
3311
                  return;
 
3312
                }
 
3313
              memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
 
3314
 
 
3315
              last_slash = strrchr( libname, '/' );
 
3316
              if( last_slash == NULL )
 
3317
                {
 
3318
                  last_slash = libname;
 
3319
                }
 
3320
              else
 
3321
                {
 
3322
                  last_slash++;
 
3323
                }
 
3324
              last_dot   = strrchr( last_slash, '.' );
 
3325
              if( last_dot == NULL )
 
3326
                {
 
3327
                  last_dot = &last_slash[strlen(last_slash)];
 
3328
                }
 
3329
 
 
3330
              handle->info.name = LT_DLMALLOC( char, last_dot-last_slash+1 );
 
3331
              strncpy( handle->info.name, last_slash, last_dot-last_slash );
 
3332
              handle->info.name[last_dot-last_slash] = '\0';
 
3333
 
 
3334
              handle->loader         = lt_dlloader_find ("dlopen");
 
3335
              handle->info.filename  = strdup( libname );
 
3336
              handle->info.ref_count = 1;
 
3337
              handle->depcount       = 0;
 
3338
              handle->deplibs        = 0;
 
3339
              handle->module         = dlopen( libname, lt_dlopen_flag );
 
3340
              handle->system         = 0;
 
3341
              handle->caller_data    = 0;
 
3342
              LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
 
3343
 
 
3344
              MUTEX_LOCK ();
 
3345
              handle->next = handles;
 
3346
              handles = handle;
 
3347
              MUTEX_UNLOCK ();
 
3348
            }
 
3349
 
 
3350
          info = (struct ld_info*)(((char*)info)+info->ldinfo_next);
 
3351
        }
 
3352
      while( info->ldinfo_next != 0 );
 
3353
    }
 
3354
 
 
3355
    if( buffer != NULL ) LT_DLFREE( buffer );
 
3356
}
 
3357
 
 
3358
static lt_dlhandle
 
3359
sys_dl_search_by_name( const char* name )
 
3360
{
 
3361
  lt_dlhandle cur;
 
3362
  const char* la;
 
3363
  int         inlen;
 
3364
 
 
3365
  cur = handles;
 
3366
 
 
3367
  while (cur)
 
3368
    {
 
3369
      if( cur->info.name && name )
 
3370
        {
 
3371
          if( !strcmp( cur->info.name, name ) )
 
3372
            {
 
3373
              if( cur->info.filename )
 
3374
                {
 
3375
                  la = strrchr( cur->info.filename, '.' );
 
3376
                  if( !la || strcmp(la,".la") )
 
3377
                    {
 
3378
                      return cur;
 
3379
                    }
 
3380
                }
 
3381
            }
 
3382
        }
 
3383
      if( cur->info.filename && name )
 
3384
        {
 
3385
          if( !strcmp( cur->info.filename, name ) )
 
3386
            {
 
3387
              return cur;
 
3388
            }
 
3389
        }
 
3390
      cur = cur->next;
 
3391
    }
 
3392
  return NULL;
 
3393
}
 
3394
 
 
3395
static void
 
3396
sys_dl_not_found_entry( const char* tmp )
 
3397
{
 
3398
    lt_dlhandle handle;
 
3399
 
 
3400
    handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
 
3401
    if (!handle)
 
3402
      {
 
3403
        MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
 
3404
        return;
 
3405
      }
 
3406
    memset( handle, 0, sizeof( struct lt_dlhandle_struct ) );
 
3407
 
 
3408
    handle->loader = NULL;
 
3409
 
 
3410
    handle->info.filename = strdup( tmp );
 
3411
    handle->info.name = strdup( tmp );
 
3412
    handle->info.ref_count    = 0;
 
3413
    handle->depcount          = 0;
 
3414
    handle->deplibs           = 0;
 
3415
    handle->module            = 0;
 
3416
    handle->system            = 0;
 
3417
    handle->caller_data       = 0;
 
3418
 
 
3419
    LT_DLSET_FLAG (handle, LT_DLNOTFOUND_FLAG);
 
3420
 
 
3421
    MUTEX_LOCK ();
 
3422
    handle->next = handles;
 
3423
    handles = handle;
 
3424
    MUTEX_UNLOCK ();
 
3425
}
 
3426
 
 
3427
#endif /* _AIX */