diff -urpN libtool-1.4c/bootstrap libtool/bootstrap --- libtool-1.4c/bootstrap Thu Jun 28 23:35:49 2001 +++ libtool/bootstrap Fri Jul 27 15:10:42 2001 @@ -12,7 +12,7 @@ touch ltmain.sh touch libtoolize -for sub in . libltdl demo depdemo mdemo cdemo tagdemo pdemo; do +for sub in . libltdl cdemo demo depdemo mdemo ltdldemo pdemo tagdemo; do case $sub in .) top_srcdir=. diff -urpN libtool-1.4c/libltdl/configure.ac libtool/libltdl/configure.ac --- libtool-1.4c/libltdl/configure.ac Fri Jun 29 23:47:07 2001 +++ libtool/libltdl/configure.ac Tue Jul 24 15:36:41 2001 @@ -23,7 +23,7 @@ if test -z "$enable_ltdl_install$enable_ fi fi -AM_INIT_AUTOMAKE(libltdl,1.1,-) +AM_INIT_AUTOMAKE(libltdl,1.2,-) AM_CONFIG_HEADER(config.h:config-h.in) AM_MAINTAINER_MODE @@ -32,7 +32,7 @@ AC_C_CONST AC_C_INLINE AC_LIBTOOL_WIN32_DLL -AM_PROG_LIBTOOL +AC_PROG_LIBTOOL AC_SUBST(LIBTOOL_DEPS) AC_LIB_LTDL diff -urpN libtool-1.4c/libltdl/ltdl.c libtool/libltdl/ltdl.c --- libtool-1.4c/libltdl/ltdl.c Mon Jul 2 02:14:19 2001 +++ libtool/libltdl/ltdl.c Fri Jul 27 15:00:05 2001 @@ -57,6 +57,10 @@ Foundation, Inc., 59 Temple Place, Suite # include #endif +#if HAVE_ERRNO_H +# include +#endif + #if HAVE_DIRENT_H # include # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) @@ -74,9 +78,14 @@ Foundation, Inc., 59 Temple Place, Suite # endif #endif -#include "ltdl.h" +#if HAVE_ARGZ_H +# include +#endif -#define LT_DLSTRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) +/* I have never seen a system without this: */ +#include + +#include "ltdl.h" @@ -120,6 +129,475 @@ Foundation, Inc., 59 Temple Place, Suite +/* --- MEMORY HANDLING --- */ + + +/* These are the functions used internally. In addition to making + use of the associated function pointers above, they also perform + error handling. */ +static char *lt_estrdup LT_PARAMS((const char *str)); +static lt_ptr lt_emalloc LT_PARAMS((size_t size)); +static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size)); + +static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); + +/* These are the pointers that can be changed by the caller: */ +LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)) + = (lt_ptr (*) LT_PARAMS((size_t))) malloc; +LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)) + = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc; +LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)) + = (void (*) LT_PARAMS((lt_ptr))) free; + +/* The following macros reduce the amount of typing needed to cast + assigned memory. */ +#define LT_MALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp))) +#define LT_REALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp))) +#define LT_FREE(p) \ + LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp))) + +#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ + if ((p) != (q)) { lt_dlfree (p); (p) = (q); (q) = 0; } \ + } LT_STMT_END + + +/* --- REPLACEMENT FUNCTIONS --- */ + + +#undef strdup +#define strdup rpl_strdup + +static char *strdup LT_PARAMS((const char *str)); + +char * +strdup(str) + const char *str; +{ + char *tmp = 0; + + if (str) + { + tmp = LT_MALLOC (char, 1+ strlen (str)); + if (tmp) + { + strcpy(tmp, str); + } + } + + return tmp; +} + + +#if ! HAVE_STRCMP + +#undef strcmp +#define strcmp rpl_strcmp + +static int strcmp LT_PARAMS((const char *str1, const char *str2)); + +int +strcmp (str1, str2) + const char *str1; + const char *str2; +{ + if (str1 == str2) + return 0; + if (str1 == 0) + return -1; + if (str2 == 0) + return 1; + + for (;*str1 && *str2; ++str1, ++str2) + { + if (*str1 != *str2) + break; + } + + return (int)(*str1 - *str2); +} +#endif + + +#if ! HAVE_STRCHR + +# if HAVE_INDEX +# define strchr index +# else +# define strchr rpl_strchr + +static const char *strchr LT_PARAMS((const char *str, int ch)); + +const char* +strchr(str, ch) + const char *str; + int ch; +{ + const char *p; + + for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p) + /*NOWORK*/; + + return (*p == (char)ch) ? p : 0; +} + +# endif +#endif /* !HAVE_STRCHR */ + + +#if ! HAVE_STRRCHR + +# if HAVE_RINDEX +# define strrchr rindex +# else +# define strrchr rpl_strrchr + +static const char *strrchr LT_PARAMS((const char *str, int ch)); + +const char* +strrchr(str, ch) + const char *str; + int ch; +{ + const char *p, *q = 0; + + for (p = str; *p != LT_EOS_CHAR; ++p) + { + if (*p == (char) ch) + { + q = p; + } + } + + return q; +} + +# endif +#endif + +/* NOTE: Neither bcopy nor the memcpy implementation below can + reliably handle copying in overlapping areas of memory. Use + memmove (for which there is a fallback implmentation below) + if you need that behaviour. */ +#if ! HAVE_MEMCPY + +# if HAVE_BCOPY +# define memcpy(dest, src, size) bcopy (src, dest, size) +# else +# define memcpy rpl_memcpy + +static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); + +lt_ptr +memcpy (dest, src, size) + lt_ptr dest; + const lt_ptr src; + size_t size; +{ + size_t i = 0; + + for (i = 0; i < size; ++i) + { + dest[i] = src[i]; + } + + return dest; +} + +# endif /* !HAVE_BCOPY */ +#endif /* !HAVE_MEMCPY */ + +#if ! HAVE_MEMMOVE +# define memmove rpl_memmove + +static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); + +lt_ptr +memmove (dest, src, size) + lt_ptr dest; + const lt_ptr src; + size_t size; +{ + size_t i; + + if (dest < src) + for (i = 0; i < size; ++i) + { + dest[i] = src[i]; + } + else if (dest > src) + for (i = size -1; i >= 0; --i) + { + dest[i] = src[i]; + } + + return dest; +} + +#endif /* !HAVE_MEMMOVE */ + + +/* According to Alexandre Oliva , + ``realloc is not entirely portable'' + In any case we want to use the allocator supplied by the user without + burdening them with an lt_dlrealloc function pointer to maintain. + Instead implement our own version (with known boundary conditions) + using lt_dlmalloc and lt_dlfree. */ + +#undef realloc +#define realloc rpl_realloc + +lt_ptr +realloc (ptr, size) + lt_ptr ptr; + size_t size; +{ + if (size <= 0) + { + /* For zero or less bytes, free the original memory */ + if (ptr != 0) + { + lt_dlfree (ptr); + } + + return (lt_ptr) 0; + } + else if (ptr == 0) + { + /* Allow reallocation of a NULL pointer. */ + return lt_dlmalloc (size); + } + else + { + /* Allocate a new block, copy and free the old block. */ + lt_ptr mem = lt_dlmalloc (size); + + if (mem) + { + memcpy (mem, ptr, size); + lt_dlfree (ptr); + } + + /* Note that the contents of PTR are not damaged if there is + insufficient memory to realloc. */ + return mem; + } +} + + +#if ! HAVE___ARGZ_APPEND +# define __argz_append rpl_argz_append + +static error_t __argz_append LT_PARAMS((char **pargz, size_t *pargz_len, + const char *buf, size_t buf_len)); + +error_t +__argz_append (pargz, pargz_len, buf, buf_len) + char **pargz; + size_t *pargz_len; + const char *buf; + size_t buf_len; +{ + size_t argz_len; + char *argz; + + assert (pargz); + assert (pargz_len); + assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); + + /* If nothing needs to be appended, no more work is required. */ + if (buf_len == 0) + return 0; + + /* Ensure there is enough room to append BUF_LEN. */ + argz_len = *pargz_len + buf_len; + argz = LT_REALLOC (char, *pargz, argz_len); + if (!argz) + return ENOMEM; + + /* Copy characters from BUF after terminating '\0' in ARGZ. */ + memcpy (argz + *pargz_len, buf, buf_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE___ARGZ_APPEND */ + + +#if ! HAVE___ARGZ_CREATE_SEP +# define __argz_create_sep rpl_argz_create_sep + +static error_t __argz_create_sep LT_PARAMS((const char *str, int delim, + char **pargz, size_t *pargz_len)); + +error_t +__argz_create_sep (str, delim, pargz, pargz_len) + const char *str; + int delim; + char **pargz; + size_t *pargz_len; +{ + size_t argz_len; + char *argz = 0; + + assert (str); + assert (pargz); + assert (pargz_len); + + /* Make a copy of STR, but replacing each occurence of + DELIM with '\0'. */ + argz_len = LT_STRLEN (str); + if (argz_len) + { + const char *p; + char *q; + + argz = LT_MALLOC (char, 1+ argz_len); + if (!argz) + return ENOMEM; + + for (p = str, q = argz; *p != LT_EOS_CHAR; ++p) + { + if (*p == delim) + { + /* Ignore leading delimiters, and fold consecutive + delimiters in STR into a single '\0' in ARGZ. */ + if ((q > argz) && (q[-1] != LT_EOS_CHAR)) + *q++ = LT_EOS_CHAR; + else + --argz_len; + } + else + *q++ = *p; + } + } + + /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ + if (!argz_len) + LT_FREE (argz); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE___ARGZ_CREATE_SEP */ + + +#if ! HAVE___ARGZ_INSERT +# define __argz_insert rpl_argz_insert + +static error_t __argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, + char *before, const char *entry)); + +error_t +__argz_insert (pargz, pargz_len, before, entry) + char **pargz; + size_t *pargz_len; + char *before; + const char *entry; +{ + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + /* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL, + or BEFORE points into an address within the ARGZ vector. */ + assert ((!*pargz && !*pargz_len && !before) + || ((*pargz <= before) && (before < (*pargz + *pargz_len)))); + + /* No BEFORE address indicates ENTRY should be inserted after the + current last element. */ + if (!before) + return __argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry)); + + /* This probably indicates a programmer error, but to preserve + semantics, scan back to the start of an entry if BEFORE points + into the middle of it. */ + while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR)) + --before; + + { + size_t entry_len = 1+ LT_STRLEN (entry); + size_t argz_len = *pargz_len + entry_len; + size_t offset = before - *pargz; + char *argz = LT_REALLOC (char, *pargz, argz_len); + + if (!argz) + return ENOMEM; + + /* Make BEFORE point to the equivalent offset in ARGZ that it + used to have in *PARGZ incase realloc() moved the block. */ + before = argz + offset; + + /* Move the ARGZ entries starting at BEFORE up into the new + space at the end -- making room to copy ENTRY into the + resulting gap. */ + memmove (before + entry_len, before, *pargz_len - offset); + memcpy (before, entry, entry_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + } + + return 0; +} +#endif /* !HAVE___ARGZ_INSERT */ + + +#if ! HAVE___ARGZ_NEXT +# define __argz_next rpl_argz_next + +static char *__argz_next LT_PARAMS((char *argz, size_t argz_len, + const char *entry)); + +char * +__argz_next (argz, argz_len, entry) + char *argz; + size_t argz_len; + const char *entry; +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (entry) + { + /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address + within the ARGZ vector. */ + assert ((!argz && !argz_len) + || ((argz <= entry) && (entry < (argz + argz_len)))); + + /* Move to the char immediately after the terminating + '\0' of ENTRY. */ + entry = 1+ strchr (entry, LT_EOS_CHAR); + + /* Return either the new ENTRY, or else NULL if ARGZ is + exhausted. */ + return (entry >= argz + argz_len) ? 0 : (char *) entry; + } + else + { + /* This should probably be flagged as a programmer error, + since starting an __argz_next loop with the iterator set + to ARGZ is safer. To preserve semantics, handle the NULL + case by returning the start of ARGZ (if any). */ + if (argz_len > 0) + return argz; + else + return 0; + } +} +#endif /* !HAVE_ARGZ_NEXT */ + + + + /* --- TYPE DEFINITIONS -- */ @@ -136,7 +614,7 @@ typedef struct { /* Extract the diagnostic strings from the error table macro in the same - order as the enumberated indices in ltdl.h. */ + order as the enumerated indices in ltdl.h. */ static const char *lt_dlerror_strings[] = { @@ -270,29 +748,7 @@ lt_dlmutex_register (lock, unlock, seter -/* --- MEMORY HANDLING --- */ - - -LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)) - = (lt_ptr (*) LT_PARAMS((size_t))) malloc; -LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)) - = (void (*) LT_PARAMS((lt_ptr))) free; - -static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, - size_t size)); - -#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp))) -#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp))) -#define LT_DLFREE(p) \ - LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END - -#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ - if ((p) != (q)) { lt_dlfree (p); (p) = (q); } \ - } LT_STMT_END - - - -/* --- ERROR MESSAGES --- */ +/* --- ERROR HANDLING --- */ static const char **user_error_strings = 0; @@ -306,15 +762,13 @@ lt_dladderror (diagnostic) int result = -1; const char **temp = (const char **) 0; + assert (diagnostic); + LT_DLMUTEX_LOCK (); errindex = errorcount - LT_ERROR_MAX; - temp = LT_DLREALLOC (const char *, user_error_strings, 1 + errindex); - if (temp == 0) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - } - else + temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex); + if (temp) { user_error_strings = temp; user_error_strings[errindex] = diagnostic; @@ -356,183 +810,35 @@ lt_dlseterror (errindex) return errors; } - - - -/* --- REPLACEMENT FUNCTIONS --- */ - - -#undef strdup -#define strdup rpl_strdup - -static char * -strdup(str) - const char *str; -{ - char *tmp = 0; - - if (str) - { - tmp = LT_DLMALLOC (char, 1+ strlen (str)); - if (tmp) - { - strcpy(tmp, str); - } - } - - return tmp; -} - - -#if ! HAVE_STRCMP - -#undef strcmp -#define strcmp rpl_strcmp - -static int -strcmp (str1, str2) - const char *str1; - const char *str2; -{ - if (str1 == str2) - return 0; - if (str1 == 0) - return -1; - if (str2 == 0) - return 1; - - for (;*str1 && *str2; ++str1, ++str2) - { - if (*str1 != *str2) - break; - } - - return (int)(*str1 - *str2); -} -#endif - - -#if ! HAVE_STRCHR - -# if HAVE_INDEX -# define strchr index -# else -# define strchr rpl_strchr - -static const char* -strchr(str, ch) - const char *str; - int ch; +lt_ptr +lt_emalloc (size) + size_t size; { - const char *p; - - for (p = str; *p != (char)ch && *p != '\0'; ++p) - /*NOWORK*/; - - return (*p == (char)ch) ? p : 0; + lt_ptr mem = lt_dlmalloc (size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; } -# endif -#endif /* !HAVE_STRCHR */ - -#if ! HAVE_STRRCHR - -# if HAVE_RINDEX -# define strrchr rindex -# else -# define strrchr rpl_strrchr - -static const char* -strrchr(str, ch) - const char *str; - int ch; -{ - const char *p, *q = 0; - - for (p = str; *p != '\0'; ++p) - { - if (*p == (char) ch) - { - q = p; - } - } - - return q; -} - -# endif -#endif - -/* NOTE: Neither bcopy nor the memcpy implementation below can - reliably handle copying in overlapping areas of memory, so - do not rely on this behaviour when invoking memcpy later. */ -#if ! HAVE_MEMCPY - -# if HAVE_BCOPY -# define memcpy(dest, src, size) bcopy (src, dest, size) -# else -# define memcpy rpl_memcpy - -static char * -memcpy (dest, src, size) - char *dest; - const char *src; +lt_ptr +lt_erealloc (addr, size) + lt_ptr addr; size_t size; { - size_t i = 0; - - for (i = 0; i < size; ++i) - { - dest[i] = src[i]; - } - - return dest; + lt_ptr mem = realloc (addr, size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; } -# endif -#endif - -/* According to Alexandre Oliva , - ``realloc is not entirely portable'' - In any case we want to use the allocator supplied by the user without - burdening them with an lt_dlrealloc function pointer to maintain. - Instead implement our own version (with known boundary conditions) - using lt_dlmalloc and lt_dlfree. */ -static lt_ptr -rpl_realloc (ptr, size) - lt_ptr ptr; - size_t size; +char * +lt_estrdup (str) + const char *str; { - if (size < 1) - { - /* For zero or less bytes, free the original memory */ - if (ptr != 0) - { - lt_dlfree (ptr); - } - - return (lt_ptr) 0; - } - else if (ptr == 0) - { - /* Allow reallocation of a NULL pointer. */ - return lt_dlmalloc (size); - } - else - { - /* Allocate a new block, copy and free the old block. */ - lt_ptr mem = lt_dlmalloc (size); - - if (mem) - { - memcpy (mem, ptr, size); - lt_dlfree (ptr); - } - - /* Note that the contents of PTR are not damaged if there is - insufficient memory to realloc. */ - return mem; - } + char *dup = strdup (str); + if (LT_STRLEN (str) && !dup) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return dup; } @@ -831,21 +1137,18 @@ sys_wll_open (loader_data, filename) if (ext) { /* FILENAME already has an extension. */ - searchname = strdup (filename); + searchname = lt_estrdup (filename); } else { /* Append a `.' to stop Windows from adding an implicit `.dll' extension. */ - searchname = LT_DLMALLOC (char, 2+ LT_DLSTRLEN (filename)); - if (!searchname) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 0; - } - strcpy (searchname, filename); - strcat (searchname, "."); + searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename)); + if (searchname) + sprintf (searchname, "%s.", filename); } + if (!searchname) + return 0; #if __CYGWIN__ { @@ -856,7 +1159,7 @@ sys_wll_open (loader_data, filename) #else module = LoadLibrary (searchname); #endif - LT_DLFREE (searchname); + LT_FREE (searchname); /* libltdl expects this function to fail if it is unable to physically load the library. Sadly, LoadLibrary @@ -1033,15 +1336,10 @@ sys_dld_open (loader_data, filename) { lt_module module = strdup (filename); - if (!module) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - module = 0; - } - else if (dld_link (filename) != 0) + if (dld_link (filename) != 0) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); - LT_DLFREE (module); + LT_FREE (module); module = 0; } @@ -1062,7 +1360,7 @@ sys_dld_close (loader_data, module) } else { - LT_DLFREE (module); + LT_FREE (module); } return errors; @@ -1139,7 +1437,7 @@ presym_free_symlists () lt_dlsymlists_t *tmp = lists; lists = lists->next; - LT_DLFREE (tmp); + LT_FREE (tmp); } preloaded_symbols = 0; @@ -1176,20 +1474,19 @@ presym_add_symlist (preloaded) lists = lists->next; } - tmp = LT_DLMALLOC (lt_dlsymlists_t, 1); + tmp = LT_EMALLOC (lt_dlsymlists_t, 1); if (tmp) { - memset (tmp, 0, 1*sizeof(lt_dlsymlists_t)); + memset (tmp, 0, sizeof(lt_dlsymlists_t)); tmp->syms = preloaded; tmp->next = preloaded_symbols; preloaded_symbols = tmp; } else { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); ++errors; } - + done: LT_DLMUTEX_UNLOCK (); return errors; @@ -1212,6 +1509,10 @@ presym_open (loader_data, filename) goto done; } + /* Can't use NULL as the reflective symbol header, as NULL is + used to mark the end of the entire symbol list. Self-dlpreopened + symbols follow this magic number, chosen to be an unlikely + clash with a real module name. */ if (!filename) { filename = "@PROGRAM@"; @@ -1303,7 +1604,11 @@ static int foreachfile_callback LT_PARA lt_ptr data2)); -static char *canonicalize_path LT_PARAMS((const char *path)); +static int canonicalize_path LT_PARAMS((const char *path, + char **pcanonical)); +static int argzize_path LT_PARAMS((const char *path, + char **pargz, + size_t *pargz_len)); static FILE *find_file LT_PARAMS((const char *search_path, const char *base_name, char **pdir)); @@ -1531,10 +1836,9 @@ tryall_dlopen (handle, filename) cur = *handle; if (filename) { - cur->info.filename = strdup (filename); + cur->info.filename = lt_estrdup (filename); if (!cur->info.filename) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); ++errors; goto done; } @@ -1559,13 +1863,13 @@ tryall_dlopen (handle, filename) if (!loader) { - LT_DLFREE (cur->info.filename); + LT_FREE (cur->info.filename); ++errors; goto done; } cur->loader = loader; - lt_dllast_error = saved_error; + LT_DLMUTEX_SETERROR (saved_error); done: LT_DLMUTEX_UNLOCK (); @@ -1574,6 +1878,55 @@ tryall_dlopen (handle, filename) } static int +tryall_dlopen_module (handle, prefix, dirname, dlname) + lt_dlhandle *handle; + const char *prefix; + const char *dirname; + const char *dlname; +{ + int error = 0; + char *filename = 0; + size_t filename_len = 0; + size_t dirname_len = LT_STRLEN (dirname); + + assert (handle); + assert (dirname); + assert (dlname); +#ifdef LT_DIRSEP_CHAR + /* Only canonicalized names (i.e. with DIRSEP chars already converted) + should make it into this function: */ + assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); +#endif + + if (dirname[dirname_len -1] == '/') + --dirname_len; + filename_len = dirname_len + 1 + LT_STRLEN (dlname); + + /* Allocate memory, and combine DIRNAME and MODULENAME into it. + The PREFIX (if any) is handled below. */ + filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1); + if (!filename) + return 1; + + sprintf (filename, "%.*s/%s", dirname_len, dirname, dlname); + + /* Now that we have combined DIRNAME and MODULENAME, if there is + also a PREFIX to contend with, simply recurse with the arguments + shuffled. Otherwise, attempt to open FILENAME as a module. */ + if (prefix) + { + tryall_dlopen_module (handle, 0, prefix, filename); + } + else if (tryall_dlopen (handle, filename) != 0) + { + ++error; + } + + LT_FREE (filename); + return error; +} + +static int find_module (handle, dir, libdir, dlname, old_name, installed) lt_dlhandle *handle; const char *dir; @@ -1585,15 +1938,15 @@ find_module (handle, dir, libdir, dlname int error; char *filename; - /* try to open the old library first; if it was dlpreopened, + /* Try to open the old library first; if it was dlpreopened, we want the preopened version of it, even if a dlopenable - module is available */ - if (old_name && tryall_dlopen(handle, old_name) == 0) + module is available. */ + if (old_name && tryall_dlopen (handle, old_name) == 0) { return 0; } - /* try to open the dynamic library */ + /* Try to open the dynamic library. */ if (dlname) { size_t len; @@ -1601,111 +1954,120 @@ find_module (handle, dir, libdir, dlname /* try to open the installed module */ if (installed && libdir) { - len = strlen (libdir) + 1 + strlen (dlname); - filename = LT_DLMALLOC (char, 1+ len); - - if (!filename) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 1; - } - - sprintf (filename, "%s/%s", libdir, dlname); - error = (tryall_dlopen (handle, filename) != 0); - LT_DLFREE (filename); - - if (!error) - { - return 0; - } + if (tryall_dlopen_module (handle, 0, libdir, dlname) == 0) + return 0; } /* try to open the not-installed module */ if (!installed) { - len = LT_DLSTRLEN (dir) + strlen (objdir) + strlen (dlname); - filename = LT_DLMALLOC (char, 1+ len); + if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0) + return 0; + } - if (!filename) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 1; - } + /* maybe it was moved to another directory */ + { + if (tryall_dlopen_module (handle, 0, dir, dlname) == 0) + return 0; + } + } - if (dir) - { - strcpy (filename, dir); - } - else - { - *filename = 0; - } - strcat(filename, objdir); - strcat(filename, dlname); + return 1; +} - error = tryall_dlopen (handle, filename) != 0; - LT_DLFREE (filename); - if (!error) - { - return 0; - } - } - /* maybe it was moved to another directory */ - { - len = LT_DLSTRLEN (dir) + strlen (dlname); - filename = LT_DLMALLOC (char, 1+ len); +static int +canonicalize_path (path, pcanonical) + const char *path; + char **pcanonical; +{ + char *canonical = 0; + + assert (path && *path); + assert (pcanonical); - if (dir) + canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path)); + if (!canonical) + return 1; + + { + size_t dest = 0; + size_t src; + for (src = 0; path[src] != LT_EOS_CHAR; ++src) + { + /* Path separators are not copied to the beginning or end of + the destination, or if another separator would follow + immediately. */ + if (path[src] == LT_PATHSEP_CHAR) { - strcpy (filename, dir); + if ((dest == 0) + || (path[1+ src] == LT_PATHSEP_CHAR) + || (path[1+ src] == LT_EOS_CHAR)) + continue; } - else + /* Anything other than a directory separator is copied verbatim. */ + else if ((path[src] != '/') +#ifdef LT_DIRSEP_CHAR + && (path[src] != LT_DIRSEP_CHAR) +#endif + ) { - *filename = 0; + canonical[dest++] = path[src]; } - strcat(filename, dlname); - - error = (tryall_dlopen (handle, filename) != 0); - LT_DLFREE (filename); - if (!error) + /* Directory separators are converted and copied only if they are + not at the end of a path -- i.e. before a path separator or + NULL terminator. */ + else if ((path[1+ src] == LT_PATHSEP_CHAR) + || (path[1 + src] == LT_EOS_CHAR)) { - return 0; + canonical[dest++] = '/'; } } - } - return 1; + /* Add an end-of-string marker at the end. */ + canonical[dest] = LT_EOS_CHAR; + } + + /* Assign new value. */ + *pcanonical = canonical; + + return 0; } -static char * -canonicalize_path (path) +static int +argzize_path (path, pargz, pargz_len) const char *path; + char **pargz; + size_t *pargz_len; { - char *canonical = 0; + error_t error; + + assert (path); + assert (pargz); + assert (pargz_len); - if (path && *path) + if ((error = __argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len))) { - char *ptr = strdup (path); - canonical = ptr; - -#ifdef LT_DIRSEP_CHAR - /* Avoid this overhead where '/' is the only separator. */ - while (ptr = strchr (ptr, LT_DIRSEP_CHAR)) + switch (error) { - *ptr++ = '/'; + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; } -#endif + + return 1; } - return canonical; + return 0; } /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element - of SEARCH_PATH and a copy of DATA, until FUNC returns non-zero or - all elements are exhausted. If BASE_NAME is non-NULL, it is appended - to each SEARCH_PATH element (with a separating '/' added if - necessary) before FUNC is called. */ + of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns + non-zero or all elements are exhausted. If BASE_NAME is non-NULL, + it is appended to each SEARCH_PATH element before FUNC is called. */ static int foreach_dirinpath (search_path, base_name, func, data1, data2) const char *search_path; @@ -1714,81 +2076,73 @@ foreach_dirinpath (search_path, base_nam lt_ptr data1; lt_ptr data2; { - int result = 0; - int filenamesize = 0; - int lenbase = LT_DLSTRLEN (base_name); - char *filename = 0; - char *canonical, *next; + int result = 0; + char *canonical = 0; + char *filename = 0; + size_t filename_len = 0; + char *pathz = 0; + size_t pathz_len = 0; - LT_DLMUTEX_LOCK (); + assert (func); - if (!search_path || !*search_path) + /* If there is nowhere to look then give up immediately. */ + if (!(search_path && *search_path)) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - goto cleanup; + return 0; } - canonical = canonicalize_path (search_path); - if (!canonical) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - goto cleanup; - } + LT_DLMUTEX_LOCK (); - next = canonical; - while (next) - { - char *cur = next; - int lendir; + if (canonicalize_path (search_path, &canonical) != 0) + goto cleanup; - next = strchr (cur, LT_PATHSEP_CHAR); - if (!next) - next = cur + strlen (cur); - - lendir = next - cur; - if (*next == LT_PATHSEP_CHAR) - ++next; - else - next = 0; + if (argzize_path (canonical, &pathz, &pathz_len) != 0) + goto cleanup; - if (lendir == 0) - continue; + { + char *entry = 0; + while ((entry = __argz_next (pathz, pathz_len, entry))) + { + size_t len = LT_STRLEN (entry); - if (lendir +1 +lenbase >= filenamesize) - { - LT_DLFREE (filename); - filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */ - filename = LT_DLMALLOC (char, filenamesize); + if (base_name) + len += 1+ LT_STRLEN (base_name); - if (!filename) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + if (len > filename_len) + { + char *mem = LT_EMALLOC (char, 1+ len); + + if (!mem) goto cleanup; - } - } - strncpy (filename, cur, lendir); - if (filename[lendir -1] != '/') - filename[lendir++] = '/'; - if (base_name && *base_name) - strcpy (filename +lendir, base_name); + LT_DLMEM_REASSIGN (filename, mem); + filename_len = len; + } - if ((result = (*func) (filename, data1, data2))) - { - break; - } - } + if (base_name) + sprintf (filename, "%s/%s", entry, base_name); + else + strcpy (filename, entry); + + if ((result = (*func) (filename, data1, data2))) + { + break; + } + } + } cleanup: - LT_DLFREE (canonical); - LT_DLFREE (filename); + LT_FREE (pathz); + LT_FREE (canonical); + LT_FREE (filename); LT_DLMUTEX_UNLOCK (); return result; } -/* If FILEPATH can be opened, store the name of the directory component +/* If FILENAME can be opened, store the name of the directory component in DATA1, and the opened FILE* structure address in DATA2. Otherwise DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */ static int @@ -1797,32 +2151,27 @@ find_file_callback (filename, data1, dat lt_ptr data1; lt_ptr data2; { - char **pdir = (char **) data1; - FILE **pfile = (FILE **) data2; - int is_done = 0; + char **pdir = (char **) data1; + FILE **pfile = (FILE **) data2; + int is_done = 0; + + assert (filename && *filename); + assert (pdir); + assert (pfile); - *pfile = fopen (filename, LT_READTEXT_MODE); - - if (*pfile) + if ((*pfile = fopen (filename, LT_READTEXT_MODE))) { char *dirend = strrchr (filename, '/'); - LT_DLFREE (*pdir); - *dirend = '\0'; - *pdir = strdup (filename); - if (!*pdir) - { - /* We could have even avoided the strdup, - but there would be some memory overhead. */ - *pdir = filename; - filename = 0; /* prevent the foreach function from freeing */ - } + LT_FREE (*pdir); + *pdir = filename; + filename = 0; + + if (dirend > filename) + *dirend = LT_EOS_CHAR; + is_done = 1; } - else - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - } return is_done; } @@ -1876,7 +2225,7 @@ load_deplibs (handle, deplibs) char *deplibs; { #if LTDL_DLOPEN_DEPLIBS - char *p, *save_search_path; + char *p, *save_search_path = 0; int depcount = 0; int i; char **names = 0; @@ -1893,11 +2242,11 @@ load_deplibs (handle, deplibs) ++errors; LT_DLMUTEX_LOCK (); - save_search_path = strdup (user_search_path); - if (user_search_path && !save_search_path) + if (user_search_path) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - goto cleanup; + save_search_path = lt_estrdup (user_search_path); + if (!save_search_path) + goto cleanup; } /* extract search paths and count deplibs */ @@ -1936,7 +2285,7 @@ load_deplibs (handle, deplibs) } /* restore the old search path */ - LT_DLFREE (user_search_path); + LT_FREE (user_search_path); user_search_path = save_search_path; LT_DLMUTEX_UNLOCK (); @@ -1947,11 +2296,9 @@ load_deplibs (handle, deplibs) goto cleanup; } - names = LT_DLMALLOC (char *, depcount * sizeof (char*)); + names = LT_EMALLOC (char *, depcount * sizeof (char*)); if (!names) - { - goto cleanup; - } + goto cleanup; /* now only extract the actual deplibs */ depcount = 0; @@ -1977,25 +2324,17 @@ load_deplibs (handle, deplibs) *end = 0; /* set a temporary string terminator */ if (strncmp(p, "-l", 2) == 0) { - name = LT_DLMALLOC (char, 3+ /* "lib" */ strlen (p+2) + 1); - if (name) - { - sprintf (name, "lib%s", p+2); - } + size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); + name = LT_EMALLOC (1+ name_len); + sprintf (name, "lib%s", p+2); } else - { - name = strdup(p); - } + name = lt_estrdup(p); - if (name) - { - names[depcount++] = name; - } - else - { - goto cleanup_names; - } + if (!name) + goto cleanup_names; + + names[depcount++] = name; *end = save; } p = end; @@ -2011,11 +2350,9 @@ load_deplibs (handle, deplibs) { int j = 0; - handle->deplibs = (lt_dlhandle*) LT_DLMALLOC (lt_dlhandle *, depcount); + handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount); if (!handle->deplibs) - { - goto cleanup; - } + goto cleanup; for (i = 0; i < depcount; ++i) { @@ -2033,11 +2370,11 @@ load_deplibs (handle, deplibs) cleanup_names: for (i = 0; i < depcount; ++i) { - LT_DLFREE (names[i]); + LT_FREE (names[i]); } cleanup: - LT_DLFREE (names); + LT_FREE (names); #endif return errors; @@ -2072,22 +2409,19 @@ trim (dest, str) /* remove the leading and trailing "'" from str and store the result in dest */ const char *end = strrchr (str, '\''); - int len = LT_DLSTRLEN (str); + int len = LT_STRLEN (str); char *tmp; - LT_DLFREE (*dest); + LT_FREE (*dest); if (len > 3 && str[0] == '\'') { - tmp = LT_DLMALLOC (char, end - str); + tmp = LT_EMALLOC (char, end - str); if (!tmp) - { - lt_dllast_error = LT_DLSTRERROR (NO_MEMORY); - return 1; - } + return 1; strncpy(tmp, &str[1], (end - str) - 1); - tmp[len-3] = '\0'; + tmp[len-3] = LT_EOS_CHAR; *dest = tmp; } else @@ -2099,16 +2433,16 @@ trim (dest, str) } static int -free_vars( dlname, oldname, libdir, deplibs) +free_vars (dlname, oldname, libdir, deplibs) char *dlname; char *oldname; char *libdir; char *deplibs; { - LT_DLFREE (dlname); - LT_DLFREE (oldname); - LT_DLFREE (libdir); - LT_DLFREE (deplibs); + LT_FREE (dlname); + LT_FREE (oldname); + LT_FREE (libdir); + LT_FREE (deplibs); return 0; } @@ -2122,61 +2456,54 @@ lt_dlopen (filename) const char *saved_error; char *canonical = 0, *base_name = 0, *dir = 0, *name = 0; + /* Doing this immediately allows internal functions to safely + assume only canonicalized paths are passed. */ + if (filename && (canonicalize_path (filename, &canonical) != 0)) + return 0; + LT_DLMUTEX_GETERROR (saved_error); /* dlopen self? */ if (!filename) { - handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1); + handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); if (!handle) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 0; - } + return 0; memset (handle, 0, 1*sizeof(struct lt_dlhandle_struct)); - newhandle = handle; + newhandle = handle; /* lt_dlclose()ing yourself is very bad! Disallow it. */ LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); if (tryall_dlopen (&newhandle, 0) != 0) { - LT_DLFREE (handle); + LT_FREE (handle); return 0; } goto register_handle; } - canonical = canonicalize_path (filename); - if (!canonical) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - LT_DLFREE (handle); - return 0; - } + assert (filename && *filename); /* If the canonical module name is a path (relative or absolute) then split it into a directory part and a name part. */ base_name = strrchr (canonical, '/'); if (base_name) { - ++base_name; - dir = LT_DLMALLOC (char, base_name - canonical + 1); + size_t dirlen = (1+ base_name) - canonical; + + dir = LT_EMALLOC (char, 1+ dirlen); if (!dir) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - handle = 0; - goto cleanup; - } + goto cleanup; - strncpy (dir, canonical, base_name - canonical); - dir[base_name - canonical] = '\0'; + strncpy (dir, canonical, dirlen); + dir[dirlen] = LT_EOS_CHAR; } else - { - base_name = canonical; - } + LT_DLMEM_REASSIGN (base_name, canonical); + + assert (base_name && *base_name); /* Check whether we are opening a libtool module (.la extension). */ ext = strrchr(base_name, '.'); @@ -2197,13 +2524,9 @@ lt_dlopen (filename) int installed = 1; /* extract the module name from the file name */ - name = LT_DLMALLOC (char, ext - base_name + 1); + name = LT_EMALLOC (char, ext - base_name + 1); if (!name) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - handle = 0; - goto cleanup; - } + goto cleanup; /* canonicalize the module name */ for (i = 0; i < ext - base_name; ++i) @@ -2218,7 +2541,7 @@ lt_dlopen (filename) } } - name[ext - base_name] = '\0'; + name[ext - base_name] = LT_EOS_CHAR; /* Now try to open the .la file. If there is no directory name component, try to find it first in user_search_path and then other @@ -2255,18 +2578,13 @@ lt_dlopen (filename) } if (!file) - { - handle = 0; - goto cleanup; - } + goto cleanup; line_len = LT_FILENAME_MAX; - line = LT_DLMALLOC (char, line_len); + line = LT_EMALLOC (char, line_len); if (!line) { fclose (file); - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - handle = 0; goto cleanup; } @@ -2281,9 +2599,9 @@ lt_dlopen (filename) /* Handle the case where we occasionally need to read a line that is longer than the initial buffer size. */ - while (line[strlen(line) -1] != '\n') + while (line[LT_STRLEN(line) -1] != '\n') { - line = LT_DLREALLOC (char, line, line_len *2); + line = LT_REALLOC (char, line, line_len *2); if (!fgets (&line[line_len -1], line_len +1, file)) { break; @@ -2341,38 +2659,40 @@ lt_dlopen (filename) char *last_libname; error = trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); if (! error && dlname && - (last_libname = strrchr (dlname, ' ')) != NULL) + (last_libname = strrchr (dlname, ' ')) != 0) { - last_libname = strdup (last_libname + 1); + last_libname = lt_estrdup (last_libname + 1); + if (!last_libname) + { + ++error; + goto cleanup; + } LT_DLMEM_REASSIGN (dlname, last_libname); } } if (error) - { - break; - } + break; } fclose (file); - LT_DLFREE (line); + LT_FREE (line); /* allocate the handle */ - handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1); - if (!handle || error) - { - LT_DLFREE (handle); - if (!error) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - } + handle = (lt_dlhandle) LT_MALLOC (struct lt_dlhandle_struct, 1); + if (!handle) + ++error; + if (error) + { free_vars (dlname, old_name, libdir, deplibs); - /* handle is already set to 0 */ + LT_FREE (handle); goto cleanup; } - memset (handle, 0, 1*sizeof(struct lt_dlhandle_struct)); + assert (handle); + + memset (handle, 0, sizeof(struct lt_dlhandle_struct)); if (load_deplibs (handle, deplibs) == 0) { newhandle = handle; @@ -2391,7 +2711,7 @@ lt_dlopen (filename) free_vars (dlname, old_name, libdir, deplibs); if (error) { - LT_DLFREE (handle); + LT_FREE (handle); goto cleanup; } @@ -2403,18 +2723,12 @@ lt_dlopen (filename) else { /* not a libtool module */ - handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1); + handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); if (!handle) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - /* handle is already set to 0 */ - goto cleanup; - } - handle->info.ref_count = 0; - /* non-libtool modules don't have dependencies */ - handle->depcount = 0; - handle->deplibs = 0; - newhandle = handle; + goto cleanup; + + memset (handle, 0, sizeof(struct lt_dlhandle_struct)); + newhandle = handle; /* If the module has no directory name component, try to find it first in user_search_path and then other prescribed paths. @@ -2432,7 +2746,7 @@ lt_dlopen (filename) #endif )) && tryall_dlopen (&newhandle, filename)) { - LT_DLFREE (handle); + LT_FREE (handle); goto cleanup; } } @@ -2443,22 +2757,20 @@ lt_dlopen (filename) if (handle->info.ref_count == 0) { handle->info.ref_count = 1; - handle->info.name = name; - handle->next = handles; + LT_DLMEM_REASSIGN (handle->info.name, name); LT_DLMUTEX_LOCK (); + handle->next = handles; handles = handle; LT_DLMUTEX_UNLOCK (); - - name = 0; /* don't free this during `cleanup' */ } LT_DLMUTEX_SETERROR (saved_error); cleanup: - LT_DLFREE (dir); - LT_DLFREE (name); - LT_DLFREE (canonical); + LT_FREE (dir); + LT_FREE (name); + LT_FREE (canonical); return handle; } @@ -2479,7 +2791,7 @@ lt_dlopenext (filename) return lt_dlopen (filename); } - len = strlen (filename); + len = LT_STRLEN (filename); if (!len) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); @@ -2487,38 +2799,34 @@ lt_dlopenext (filename) } /* try "filename.la" */ - tmp = LT_DLMALLOC (char, len+4); + tmp = LT_EMALLOC (char, len+4); if (!tmp) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 0; - } + return 0; + strcpy (tmp, filename); strcat (tmp, ".la"); handle = lt_dlopen (tmp); if (handle) { LT_DLMUTEX_SETERROR (saved_error); - LT_DLFREE (tmp); + LT_FREE (tmp); return handle; } #ifdef LTDL_SHLIB_EXT /* try "filename.EXT" */ - if (strlen(shlib_ext) > 3) + if (LT_STRLEN(shlib_ext) > 3) { - LT_DLFREE (tmp); - tmp = LT_DLMALLOC (char, len + strlen (shlib_ext) + 1); + LT_FREE (tmp); + tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); if (!tmp) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 0; - } + return 0; + strcpy (tmp, filename); } else { - tmp[len] = '\0'; + tmp[len] = LT_EOS_CHAR; } strcat(tmp, shlib_ext); @@ -2526,7 +2834,7 @@ lt_dlopenext (filename) if (handle) { LT_DLMUTEX_SETERROR (saved_error); - LT_DLFREE (tmp); + LT_FREE (tmp); return handle; } #endif @@ -2539,79 +2847,192 @@ lt_dlopenext (filename) } LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - LT_DLFREE (tmp); + LT_FREE (tmp); return 0; } -/* If there are any files in DIRNAME, try to load them as modules, and if - successful call the verify function passed as DATA1 (with the loaded - module handle and DATA2 as arguments). If that function returns - non-zero, then unload that module, otherwise leave it loaded. */ -static int -foreachfile_callback (dirname, data1, data2) - char *dirname; - lt_ptr data1; - lt_ptr data2; -{ - int (*func) LT_PARAMS((const char *filename, lt_ptr data)) - = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1; +int +lt_argz_insert (pargz, pargz_len, entry) + char **pargz; + size_t *pargz_len; + const char *entry; +{ + char *before = 0; + + assert (pargz); + assert (pargz_len); + assert (entry && *entry); - char *filename = 0; - int filenamesize = 0; - int lendir = LT_DLSTRLEN (dirname); - DIR *dirp = opendir (dirname); - struct dirent *direntp; + if (*pargz) + while ((before = __argz_next (*pargz, *pargz_len, before))) + { + int cmp = strcmp (entry, before); - if (!dirp) - return 0; + if (cmp < 0) break; + if (cmp == 0) return 0; /* No duplicates! */ + } + + { + error_t error; - LT_DLMUTEX_LOCK (); + if ((error = __argz_insert (pargz, pargz_len, before, entry))) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + return 1; + } + } - rewinddir (dirp); - while ((direntp = readdir (dirp))) - { - /* Don't try to use `.' or `..' as useful filenames. */ - if ((direntp->d_name[0] == '.') - && (((direntp->d_name[1] == '.') && (direntp->d_name[2] == '\0')) - || (direntp->d_name[1] == '\0'))) - { - continue; - } + return 0; +} - if (lendir +1 +LT_D_NAMLEN(direntp) >= filenamesize) - { - LT_DLFREE (filename); - filenamesize = lendir +1 + LT_D_NAMLEN(direntp) +1; - filename = LT_DLMALLOC (char, filenamesize); +int +lt_argz_insertdir (pargz, pargz_len, dirnam, dp) + char **pargz; + size_t *pargz_len; + const char *dirnam; + struct dirent *dp; +{ + char *buf = 0; + size_t buf_len = 0; + char *end = 0; + size_t end_offset = 0; + size_t dir_len = 0; + int errors = 0; + + assert (pargz); + assert (pargz_len); + assert (dp); - if (!filename) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - goto cleanup; - } - } + dir_len = LT_STRLEN (dirnam); + end = dp->d_name + LT_D_NAMLEN(dp); + + /* Ignore version numbers. */ + { + char *p; + for (p = end; p -1 > dp->d_name; --p) + if (strchr (".0123456789", p[-1]) == 0) + break; - strcpy (filename, dirname); - if (filename[lendir -1] != '/') - filename[lendir++] = '/'; - strcpy (filename +lendir, direntp->d_name); + if (*p == '.') + end = p; + } - /* Call the user function for this FILENAME. */ - if ((*func) (filename, data2)) + /* Ignore filename extension. */ + { + char *p; + for (p = end -1; p > dp->d_name; --p) + if (*p == '.') { + end = p; break; } + } + + /* Prepend the directory name. */ + end_offset = end - dp->d_name; + buf_len = dir_len + 1+ end_offset; + buf = LT_MALLOC (char, 1+ buf_len); + if (!buf) + return ++errors; + + assert (buf); + + strcpy (buf, dirnam); + strcat (buf, "/"); + strncat (buf, dp->d_name, end_offset); + buf[buf_len] = LT_EOS_CHAR; + + /* Try to insert (in order) into ARGZ/ARGZ_LEN. */ + if (lt_argz_insert (pargz, pargz_len, buf) != 0) + ++errors; + + LT_FREE (buf); + + return errors; +} + +int +list_files_by_dir (dirnam, pargz, pargz_len) + const char *dirnam; + char **pargz; + size_t *pargz_len; +{ + DIR *dirp = 0; + char *argz = 0; + size_t argz_len = 0; + int errors = 0; + + assert (dirnam && *dirnam); + assert (pargz); + assert (pargz_len); + assert (dirnam[LT_STRLEN(dirnam) -1] != '/'); + + dirp = opendir (dirnam); + if (dirp) + { + struct dirent *dp = 0; + + while ((dp = readdir (dirp))) + if (dp->d_name[0] != '.') + if (lt_argz_insertdir (&argz, &argz_len, dirnam, dp)) + { + ++errors; + break; + } + + closedir (dirp); } + return errors; +} + + +/* If there are any files in DIRNAME, call the function passed in + DATA1 (with the name of each file and DATA2 as arguments). */ +static int +foreachfile_callback (dirname, data1, data2) + char *dirname; + lt_ptr data1; + lt_ptr data2; +{ + int (*func) LT_PARAMS((const char *filename, lt_ptr data)) + = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1; + + int is_done = 0; + char *argz; + size_t argz_len; + + if (list_files_by_dir (dirname, &argz, &argz_len) != 0) + goto cleanup; + + { + char *filename = 0; + while ((filename = __argz_next (argz, argz_len, filename))) + if ((is_done = (*func) (filename, data2))) + break; + } + cleanup: - LT_DLFREE (filename); - closedir (dirp); - - LT_DLMUTEX_UNLOCK (); + LT_FREE (argz); - return 0; + return is_done; } + +/* Call FUNC for each unique extensionless file in SEARCH_PATH, along + with DATA. The filenames passed to FUNC would be suitable for + passing to lt_dlopenext. The extensions are stripped so that + individual modules do not generate several entries (e.g. libfoo.la, + libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL, + then the same directories that lt_dlopen would search are examined. */ int lt_dlforeachfile (search_path, func, data) const char *search_path; @@ -2703,9 +3124,9 @@ lt_dlclose (handle) errors += handle->loader->module_close (data, handle->module); errors += unload_deplibs(handle); - LT_DLFREE (handle->info.filename); - LT_DLFREE (handle->info.name); - LT_DLFREE (handle); + LT_FREE (handle->info.filename); + LT_FREE (handle->info.name); + LT_FREE (handle); goto done; } @@ -2745,8 +3166,8 @@ lt_dlsym (handle, symbol) return 0; } - lensym = strlen (symbol) + LT_DLSTRLEN (handle->loader->sym_prefix) - + LT_DLSTRLEN (handle->info.name); + lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix) + + LT_STRLEN (handle->info.name); if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH) { @@ -2754,13 +3175,12 @@ lt_dlsym (handle, symbol) } else { - sym = LT_DLMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); - } - - if (!sym) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW)); - return 0; + sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); + if (!sym) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW)); + return 0; + } } data = handle->loader->dlloader_data; @@ -2790,7 +3210,7 @@ lt_dlsym (handle, symbol) { if (sym != lsym) { - LT_DLFREE (sym); + LT_FREE (sym); } return address; } @@ -2811,7 +3231,7 @@ lt_dlsym (handle, symbol) address = handle->loader->find_sym (data, handle->module, sym); if (sym != lsym) { - LT_DLFREE (sym); + LT_FREE (sym); } return address; @@ -2825,7 +3245,7 @@ lt_dlerror () LT_DLMUTEX_GETERROR (error); LT_DLMUTEX_SETERROR (0); - return error; + return error ? error : LT_DLSTRERROR (UNKNOWN); } int @@ -2834,7 +3254,7 @@ lt_dladdsearchdir (search_dir) { int errors = 0; - if (!search_dir || !strlen(search_dir)) + if (!search_dir || !LT_STRLEN(search_dir)) { return errors; } @@ -2842,21 +3262,17 @@ lt_dladdsearchdir (search_dir) LT_DLMUTEX_LOCK (); if (!user_search_path) { - user_search_path = strdup (search_dir); + user_search_path = lt_estrdup (search_dir); if (!user_search_path) - { - lt_dllast_error = LT_DLSTRERROR (NO_MEMORY); - ++errors; - } + ++errors; } else { - size_t len = strlen (user_search_path) + 1 + strlen (search_dir); - char *new_search_path = LT_DLMALLOC (char, 1+ len); + size_t len = LT_STRLEN (user_search_path) + 1 + LT_STRLEN (search_dir); + char *new_search_path = LT_EMALLOC (char, 1+ len); if (!new_search_path) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); ++errors; } else @@ -2879,20 +3295,18 @@ lt_dlsetsearchpath (search_path) int errors = 0; LT_DLMUTEX_LOCK (); - LT_DLFREE (user_search_path); + LT_FREE (user_search_path); LT_DLMUTEX_UNLOCK (); - if (!search_path || !strlen (search_path)) + if (!search_path || !LT_STRLEN (search_path)) { return errors; } LT_DLMUTEX_LOCK (); - user_search_path = strdup (search_path); + user_search_path = lt_estrdup (search_path); if (!user_search_path) - { - ++errors; - } + ++errors; LT_DLMUTEX_UNLOCK (); return errors; @@ -3041,18 +3455,15 @@ lt_dlcaller_set_data (key, handle, data) if (i == n_elements) { lt_caller_data *temp - = LT_DLREALLOC (lt_caller_data, handle->caller_data, 1+ n_elements); + = LT_REALLOC (lt_caller_data, handle->caller_data, 1+ n_elements); - if (temp == 0) + if (!temp) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - stale = (lt_ptr) 0; + stale = 0; goto done; } - else - { - handle->caller_data = temp; - } + + handle->caller_data = temp; /* We only need this if we needed to allocate a new caller_data. */ handle->caller_data[i].key = key; @@ -3123,12 +3534,9 @@ lt_dlloader_add (place, dlloader, loader } /* Create a new dlloader node with copies of the user callbacks. */ - node = LT_DLMALLOC (lt_dlloader, 1); - if (node == 0) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 1; - } + node = LT_EMALLOC (lt_dlloader, 1); + if (!node) + return 1; node->next = 0; node->loader_name = loader_name; @@ -3172,7 +3580,7 @@ lt_dlloader_add (place, dlloader, loader if (ptr->next != place) { - lt_dllast_error = LT_DLSTRERROR (INVALID_LOADER); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); ++errors; } else @@ -3241,7 +3649,7 @@ lt_dlloader_remove (loader_name) errors = place->dlloader_exit (place->dlloader_data); } - LT_DLFREE (place); + LT_FREE (place); done: LT_DLMUTEX_UNLOCK (); diff -urpN libtool-1.4c/libltdl/ltdl.h libtool/libltdl/ltdl.h --- libtool-1.4c/libltdl/ltdl.h Mon Jul 2 02:14:19 2001 +++ libtool/libltdl/ltdl.h Fri Jul 27 13:04:22 2001 @@ -34,6 +34,9 @@ Software Foundation, Inc., 59 Temple Pla /* --- MACROS FOR PORTABILITY --- */ +/* Saves on those hard to debug '\0' typos.... */ +#define LT_EOS_CHAR '\0' + /* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations, so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at the end of C declarations. */ @@ -82,6 +85,8 @@ LT_BEGIN_C_DECLS # define LT_CONC(s,t) s/**/t #endif +/* LT_STRLEN can be used safely on NULL pointers. */ +#define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) @@ -189,8 +194,13 @@ extern int lt_dlmutex_register LT_PARAMS /* --- MEMORY HANDLING --- */ -/* Pointers to memory management functions to be used by libltdl. */ +/* By default, the realloc function pointer is set to our internal + realloc implementation which iself uses lt_dlmalloc and lt_dlfree. + libltdl relies on a featureful realloc, but if you are sure yours + has the right semantics then you can assign it directly. Generally, + it is safe to assign just a malloc() and a free() function. */ LT_SCOPE lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)); +LT_SCOPE lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)); LT_SCOPE void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)); diff -urpN libtool-1.4c/libltdl/stamp-h.in libtool/libltdl/stamp-h.in --- libtool-1.4c/libltdl/stamp-h.in Thu Jan 1 01:00:00 1970 +++ libtool/libltdl/stamp-h.in Tue Jul 24 09:10:42 2001 @@ -0,0 +1 @@ +timestamp diff -urpN libtool-1.4c/ltdl.m4 libtool/ltdl.m4 --- libtool-1.4c/ltdl.m4 Mon Jul 23 01:23:50 2001 +++ libtool/ltdl.m4 Thu Jul 26 18:09:08 2001 @@ -20,160 +20,166 @@ ## configuration script generated by Autoconf, you may include it under ## the same distribution terms that you use for the rest of that program. -# serial 3 AC_LIB_LTDL +# serial 4 AC_LIB_LTDL # AC_LIB_LTDL # ----------- -AC_DEFUN([AC_LIB_LTDL], -[AC_PREREQ(2.13)dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_C_CONST])dnl - # Perform all the checks necessary for compilation of the ltdl objects -# -- including compiler checks (above) and header checks (below). -AC_REQUIRE([AC_HEADER_STDC])dnl -AC_REQUIRE([AC_HEADER_DIRENT])dnl -AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl - -AC_CHECK_HEADERS(malloc.h memory.h stdlib.h stdio.h ctype.h dl.h sys/dl.h dld.h) -AC_CHECK_HEADERS(string.h strings.h, break) -AC_CHECK_FUNCS(strchr index, break) -AC_CHECK_FUNCS(strrchr rindex, break) -AC_CHECK_FUNCS(memcpy bcopy, break) -AC_CHECK_FUNCS(strcmp) - -AC_REQUIRE([AC_LTDL_ENABLE_INSTALL])dnl -AC_REQUIRE([AC_LTDL_SHLIBEXT])dnl -AC_REQUIRE([AC_LTDL_SHLIBPATH])dnl -AC_REQUIRE([AC_LTDL_SYSSEARCHPATH])dnl -AC_REQUIRE([AC_LTDL_OBJDIR])dnl -AC_REQUIRE([AC_LTDL_DLPREOPEN])dnl -AC_REQUIRE([AC_LTDL_DLLIB])dnl -AC_REQUIRE([AC_LTDL_SYMBOL_USCORE])dnl -AC_REQUIRE([AC_LTDL_DLSYM_USCORE])dnl -AC_REQUIRE([AC_LTDL_SYS_DLOPEN_DEPLIBS])dnl +# -- including compiler checks and header checks. +AC_DEFUN([AC_LIB_LTDL], +[AC_PREREQ(2.50) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_C_CONST]) +AC_REQUIRE([AC_HEADER_STDC]) +AC_REQUIRE([AC_HEADER_DIRENT]) +AC_REQUIRE([_LT_AC_CHECK_DLFCN]) +AC_REQUIRE([AC_LTDL_ENABLE_INSTALL]) +AC_REQUIRE([AC_LTDL_SHLIBEXT]) +AC_REQUIRE([AC_LTDL_SHLIBPATH]) +AC_REQUIRE([AC_LTDL_SYSSEARCHPATH]) +AC_REQUIRE([AC_LTDL_OBJDIR]) +AC_REQUIRE([AC_LTDL_DLPREOPEN]) +AC_REQUIRE([AC_LTDL_DLLIB]) +AC_REQUIRE([AC_LTDL_SYMBOL_USCORE]) +AC_REQUIRE([AC_LTDL_DLSYM_USCORE]) +AC_REQUIRE([AC_LTDL_SYS_DLOPEN_DEPLIBS]) +AC_REQUIRE([AC_LTDL_FUNC_ARGZ]) + +AC_CHECK_HEADERS([ctype.h errno.h malloc.h memory.h stdlib.h stdio.h]) +AC_CHECK_HEADERS([dl.h sys/dl.h dld.h]) +AC_CHECK_HEADERS([string.h strings.h], [break]) + +AC_CHECK_FUNCS([strchr index], [break]) +AC_CHECK_FUNCS([strrchr rindex], [break]) +AC_CHECK_FUNCS([memcpy bcopy], [break]) +AC_CHECK_FUNCS([memmove strcmp]) ])# AC_LIB_LTDL + # AC_LTDL_ENABLE_INSTALL # ---------------------- AC_DEFUN([AC_LTDL_ENABLE_INSTALL], -[AC_ARG_ENABLE(ltdl-install, -[ --enable-ltdl-install install libltdl]) - +[AC_ARG_ENABLE([ltdl-install], + [ --enable-ltdl-install install libltdl]) AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno) AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno) ])])# AC_LTDL_ENABLE_INSTALL + # AC_LTDL_SYS_DLOPEN_DEPLIBS # -------------------------- AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], [AC_REQUIRE([AC_CANONICAL_HOST]) AC_CACHE_CHECK([whether deplibs are loaded by dlopen], - libltdl_cv_sys_dlopen_deplibs, [dnl - # PORTME does your system automatically load deplibs for dlopen? - # or its logical equivalent (e.g. shl_load for HP-UX < 11) - # For now, we just catch OSes we know something about -- in the - # future, we'll try test this programmatically. - libltdl_cv_sys_dlopen_deplibs=unknown - case "$host_os" in - aix3*|aix4.1.*|aix4.2.*) - # Unknown whether this is true for these versions of AIX, but - # we want this `case' here to explicitly catch those versions. - libltdl_cv_sys_dlopen_deplibs=unknown - ;; - aix[45]*) - libltdl_cv_sys_dlopen_deplibs=yes - ;; - gnu*) - libltdl_cv_sys_dlopen_deplibs=yes - ;; - irix[12345]*|irix6.[01]*) - # Catch all versions of IRIX before 6.2, and indicate that we don't - # know how it worked for any of those versions. - libltdl_cv_sys_dlopen_deplibs=unknown - ;; - irix*) - # The case above catches anything before 6.2, and it's known that - # at 6.2 and later dlopen does load deplibs. - libltdl_cv_sys_dlopen_deplibs=yes - ;; - linux*) - libltdl_cv_sys_dlopen_deplibs=yes - ;; - netbsd*) - libltdl_cv_sys_dlopen_deplibs=yes - ;; - osf[1234]*) - # dlopen did load deplibs (at least at 4.x), but until the 5.x series, - # it did *not* use an RPATH in a shared library to find objects the - # library depends on, so we explictly say `no'. - libltdl_cv_sys_dlopen_deplibs=no - ;; - osf5.0|osf5.0a|osf5.1) - # dlopen *does* load deplibs and with the right loader patch applied - # it even uses RPATH in a shared library to search for shared objects - # that the library depends on, but there's no easy way to know if that - # patch is installed. Since this is the case, all we can really - # say is unknown -- it depends on the patch being installed. If - # it is, this changes to `yes'. Without it, it would be `no'. - libltdl_cv_sys_dlopen_deplibs=unknown - ;; - osf*) - # the two cases above should catch all versions of osf <= 5.1. Read - # the comments above for what we know about them. - # At > 5.1, deplibs are loaded *and* any RPATH in a shared library - # is used to find them so we can finally say `yes'. - libltdl_cv_sys_dlopen_deplibs=yes - ;; - solaris*) - libltdl_cv_sys_dlopen_deplibs=yes - ;; - esac -]) + [libltdl_cv_sys_dlopen_deplibs], + [# PORTME does your system automatically load deplibs for dlopen? + # or its logical equivalent (e.g. shl_load for HP-UX < 11) + # For now, we just catch OSes we know something about -- in the + # future, we'll try test this programmatically. + libltdl_cv_sys_dlopen_deplibs=unknown + case "$host_os" in + aix3*|aix4.1.*|aix4.2.*) + # Unknown whether this is true for these versions of AIX, but + # we want this `case' here to explicitly catch those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + aix[45]*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + gnu*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + irix[12345]*|irix6.[01]*) + # Catch all versions of IRIX before 6.2, and indicate that we don't + # know how it worked for any of those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + irix*) + # The case above catches anything before 6.2, and it's known that + # at 6.2 and later dlopen does load deplibs. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + linux*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + netbsd*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + osf[1234]*) + # dlopen did load deplibs (at least at 4.x), but until the 5.x series, + # it did *not* use an RPATH in a shared library to find objects the + # library depends on, so we explictly say `no'. + libltdl_cv_sys_dlopen_deplibs=no + ;; + osf5.0|osf5.0a|osf5.1) + # dlopen *does* load deplibs and with the right loader patch applied + # it even uses RPATH in a shared library to search for shared objects + # that the library depends on, but there's no easy way to know if that + # patch is installed. Since this is the case, all we can really + # say is unknown -- it depends on the patch being installed. If + # it is, this changes to `yes'. Without it, it would be `no'. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + osf*) + # the two cases above should catch all versions of osf <= 5.1. Read + # the comments above for what we know about them. + # At > 5.1, deplibs are loaded *and* any RPATH in a shared library + # is used to find them so we can finally say `yes'. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + solaris*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + esac + ]) if test "$libltdl_cv_sys_dlopen_deplibs" != yes; then - AC_DEFINE(LTDL_DLOPEN_DEPLIBS, 1, - [Define if the OS needs help to load dependent libraries for dlopen(). ]) + AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], + [Define if the OS needs help to load dependent libraries for dlopen()]) fi ])# AC_LTDL_SYS_DLOPEN_DEPLIBS + # AC_LTDL_SHLIBEXT # ---------------- AC_DEFUN([AC_LTDL_SHLIBEXT], [AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) AC_CACHE_CHECK([which extension is used for shared libraries], - libltdl_cv_shlibext, -[ac_last= + [libltdl_cv_shlibext], + [ac_last= for ac_spec in $library_names_spec; do ac_last="$ac_spec" done echo "$ac_last" | [sed 's/\[.*\]//;s/^[^.]*//;s/\$.*$//;s/\.$//'] > conftest -libltdl_cv_shlibext=`cat conftest` -rm -f conftest -]) + libltdl_cv_shlibext=`cat conftest` + rm -f conftest + ]) if test -n "$libltdl_cv_shlibext"; then AC_DEFINE_UNQUOTED(LTDL_SHLIB_EXT, "$libltdl_cv_shlibext", [Define to the extension used for shared libraries, say, ".so". ]) fi ])# AC_LTDL_SHLIBEXT + # AC_LTDL_SHLIBPATH # ----------------- AC_DEFUN([AC_LTDL_SHLIBPATH], [AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) AC_CACHE_CHECK([which variable specifies run-time library path], - libltdl_cv_shlibpath_var, [libltdl_cv_shlibpath_var="$shlibpath_var"]) + [libltdl_cv_shlibpath_var], [libltdl_cv_shlibpath_var="$shlibpath_var"]) if test -n "$libltdl_cv_shlibpath_var"; then AC_DEFINE_UNQUOTED(LTDL_SHLIBPATH_VAR, "$libltdl_cv_shlibpath_var", [Define to the name of the environment variable that determines the dynamic library search path. ]) fi ])# AC_LTDL_SHLIBPATH + # AC_LTDL_SYSSEARCHPATH # --------------------- AC_DEFUN([AC_LTDL_SYSSEARCHPATH], [AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) AC_CACHE_CHECK([for the default library search path], - libltdl_cv_sys_search_path, [libltdl_cv_sys_search_path="$sys_lib_dlsearch_path_spec"]) + [libltdl_cv_sys_search_path], + [libltdl_cv_sys_search_path="$sys_lib_dlsearch_path_spec"]) if test -n "$libltdl_cv_sys_search_path"; then case "$host" in *-*-mingw*) pathsep=";" ;; @@ -192,143 +198,157 @@ if test -n "$libltdl_cv_sys_search_path" fi ])# AC_LTDL_SYSSEARCHPATH + # AC_LTDL_OBJDIR # -------------- AC_DEFUN([AC_LTDL_OBJDIR], [AC_CACHE_CHECK([for objdir], - libltdl_cv_objdir, [libltdl_cv_objdir="$objdir" -if test -n "$objdir"; then - : -else - rm -f .libs 2>/dev/null - mkdir .libs 2>/dev/null - if test -d .libs; then - libltdl_cv_objdir=.libs + [libltdl_cv_objdir], + [libltdl_cv_objdir="$objdir" + if test -n "$objdir"; then + : else - # MS-DOS does not allow filenames that begin with a dot. - libltdl_cv_objdir=_libs + rm -f .libs 2>/dev/null + mkdir .libs 2>/dev/null + if test -d .libs; then + libltdl_cv_objdir=.libs + else + # MS-DOS does not allow filenames that begin with a dot. + libltdl_cv_objdir=_libs + fi + rmdir .libs 2>/dev/null fi -rmdir .libs 2>/dev/null -fi]) + ]) AC_DEFINE_UNQUOTED(LTDL_OBJDIR, "$libltdl_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries. ]) ])# AC_LTDL_OBJDIR + # AC_LTDL_DLPREOPEN # ----------------- AC_DEFUN([AC_LTDL_DLPREOPEN], -[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], - libltdl_cv_preloaded_symbols, [dnl - if test -n "$global_symbol_pipe"; then + [libltdl_cv_preloaded_symbols], + [if test -n "$global_symbol_pipe"; then libltdl_cv_preloaded_symbols=yes else libltdl_cv_preloaded_symbols=no fi -]) -if test x"$libltdl_cv_preloaded_symbols" = x"yes"; then + ]) +if test x"$libltdl_cv_preloaded_symbols" = xyes; then AC_DEFINE(HAVE_PRELOADED_SYMBOLS, 1, [Define if libtool can extract symbol lists from object files. ]) fi ])# AC_LTDL_DLPREOPEN + # AC_LTDL_DLLIB # ------------- AC_DEFUN([AC_LTDL_DLLIB], [LIBADD_DL= AC_SUBST(LIBADD_DL) AC_LANG_PUSH([C]) -AC_CHECK_LIB(dl, dlopen, - [AC_DEFINE(HAVE_LIBDL, 1, - [Define if you have the libdl library or equivalent. ]) - LIBADD_DL="-ldl"], +AC_CHECK_LIB([dl], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent. ]) + LIBADD_DL="-ldl"], [AC_TRY_LINK([#if HAVE_DLFCN_H # include #endif -], [dlopen();], - [AC_DEFINE(HAVE_LIBDL, 1, - [Define if you have the libdl library or equivalent.])], + ], + [dlopen();], + [AC_DEFINE(HAVE_LIBDL, 1, + [Define if you have the libdl library or equivalent. ])], [AC_CHECK_LIB(svld, dlopen, - [AC_DEFINE(HAVE_LIBDL, 1, - [Define if you have the libdl library or equivalent.]) - LIBADD_DL="-lsvld"])])]) + [AC_DEFINE(HAVE_LIBDL, 1, + [Define if you have the libdl library or equivalent. ]) + LIBADD_DL="-lsvld" + ]) + ]) + ]) AC_CHECK_FUNC(shl_load, - [AC_DEFINE(HAVE_SHL_LOAD, 1, [Define if you have the shl_load function.])], - [AC_CHECK_LIB(dld, shl_load, - [AC_DEFINE(HAVE_SHL_LOAD, 1, [Define if you have the shl_load function.]) - LIBADD_DL="$LIBADD_DL -ldld"])]) - -AC_CHECK_LIB(dld, dld_link, - [AC_DEFINE(HAVE_DLD, 1, [Define if you have the GNU dld library.]) - test "x$ac_cv_lib_dld_shl_load" = yes || LIBADD_DL="$LIBADD_DL -ldld"]) - + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function. ])], + [AC_CHECK_LIB([dld], [shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function. ]) + LIBADD_DL="$LIBADD_DL -ldld" + ]) + ]) + +AC_CHECK_LIB([dld], [dld_link], + [AC_DEFINE([HAVE_DLD], [1], + [Define if you have the GNU dld library.]) + test x"$ac_cv_lib_dld_shl_load" = xyes || LIBADD_DL="$LIBADD_DL -ldld" + ]) -if test "x$ac_cv_func_dlopen" = xyes || test "x$ac_cv_lib_dl_dlopen" = xyes +if test x"$ac_cv_func_dlopen" = xyes || test x"$ac_cv_lib_dl_dlopen" = xyes then lt_save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DL" - AC_CHECK_FUNCS(dlerror) + AC_CHECK_FUNCS([dlerror]) LIBS="$lt_save_LIBS" fi AC_LANG_POP ])# AC_LTDL_DLLIB + # AC_LTDL_SYMBOL_USCORE # --------------------- +# does the compiler prefix global symbols with an underscore? AC_DEFUN([AC_LTDL_SYMBOL_USCORE], -[dnl does the compiler prefix global symbols with an underscore? -AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl -AC_MSG_CHECKING([for _ prefix in compiled symbols]) -AC_CACHE_VAL(ac_cv_sys_symbol_underscore, -[ac_cv_sys_symbol_underscore=no -cat > conftest.$ac_ext < conftest.$ac_ext < $ac_nlist) && test -s "$ac_nlist"; then - # See whether the symbols have a leading underscore. - if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then - ac_cv_sys_symbol_underscore=yes - else - if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then - : + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + ac_nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + ac_cv_sys_symbol_underscore=yes else - echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC + if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC + fi fi + else + echo "configure: cannot run $global_symbol_pipe" >&AC_FD_CC fi else - echo "configure: cannot run $global_symbol_pipe" >&AC_FD_CC + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC fi -else - echo "configure: failed program was:" >&AC_FD_CC - cat conftest.c >&AC_FD_CC -fi -rm -rf conftest* -]) -AC_MSG_RESULT($ac_cv_sys_symbol_underscore) + rm -rf conftest* + ]) ])# AC_LTDL_SYMBOL_USCORE # AC_LTDL_DLSYM_USCORE # -------------------- AC_DEFUN([AC_LTDL_DLSYM_USCORE], -[AC_REQUIRE([AC_LTDL_SYMBOL_USCORE])dnl +[AC_REQUIRE([AC_LTDL_SYMBOL_USCORE]) if test x"$ac_cv_sys_symbol_underscore" = xyes; then if test x"$ac_cv_func_dlopen" = xyes || test x"$ac_cv_lib_dl_dlopen" = xyes ; then AC_CACHE_CHECK([whether we have to add an underscore for dlsym], - libltdl_cv_need_uscore, [dnl - libltdl_cv_need_uscore=unknown - save_LIBS="$LIBS" - LIBS="$LIBS $LIBADD_DL" - _LT_AC_TRY_DLOPEN_SELF( - libltdl_cv_need_uscore=no, libltdl_cv_need_uscore=yes, - [], libltdl_cv_need_uscore=cross) - LIBS="$save_LIBS" + [libltdl_cv_need_uscore], + [libltdl_cv_need_uscore=unknown + save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DL" + _LT_AC_TRY_DLOPEN_SELF( + [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes], + [], [libltdl_cv_need_uscore=cross]) + LIBS="$save_LIBS" ]) fi fi @@ -338,3 +358,15 @@ if test x"$libltdl_cv_need_uscore" = xye [Define if dlsym() requires a leading underscode in symbol names. ]) fi ])# AC_LTDL_DLSYM_USCORE + +# AC_LTDL_FUNC_ARGZ +# ----------------- +AC_DEFUN([AC_LTDL_FUNC_ARGZ], +[AC_CHECK_HEADERS([argz.h]) +AC_CHECK_TYPE([error_t], + [], + [AC_DEFINE([error_t], [int], + [Define to a type to use for `error_t' if it is not otherwise available]) +]) +AC_CHECK_FUNCS([__argz_append __argz_create_sep __argz_insert __argz_next]) +])# AC_LTDL_FUNC_ARGZ \ No newline at end of file diff -urpN libtool-1.4c/ltdldemo/Makefile.am libtool/ltdldemo/Makefile.am --- libtool-1.4c/ltdldemo/Makefile.am Thu Jan 1 01:00:00 1970 +++ libtool/ltdldemo/Makefile.am Fri Jul 27 15:06:19 2001 @@ -0,0 +1,51 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = no-dependencies foreign + +INCLUDES = $(INCLTDL) + +EXTRA_DIST = acinclude.m4 + +lib_LTLIBRARIES = libsub.la foo1.la libfoo2.la + +foo1_la_SOURCES = foo1.c +foo1_la_LIBADD = $(LIBM) libsub.la +foo1_la_LDFLAGS = -module -avoid-version + +libfoo2_la_SOURCES = foo2.c +libfoo2_la_LIBADD = $(LIBM) libsub.la +libfoo2_la_LDFLAGS = -no-undefined -module -export-symbols-regex "libfoo2.*" + +libsub_la_SOURCES = sub.c +libsub_la_LDFLAGS = -no-undefined + +noinst_HEADERS = foo.h + +bin_PROGRAMS = mdemo mdemo.static + +## use @LIBLTDL@ because some broken makes do not accept macros in targets +## we can only do this because our LIBLTDL does not contain ${top_builddir} address@hidden@: ../libtool ../libltdl/libtool ../libltdl/config.h \ + $(srcdir)/../libltdl/ltdl.c $(srcdir)/../libltdl/ltdl.h + (cd ../libltdl; $(MAKE) `echo $(LIBLTDL) | sed 's,.*\.\./libltdl/,,g'`) +# Without the following line, the check may fail if libltdl/libtool is +# removed after libltdl is configured +../libltdl/libtool ../libltdl/config.h: + +# Create a version of mdemo that does dlopen. +mdemo_SOURCES = main.c +mdemo_LDFLAGS = -export-dynamic +## The quotes around -dlopen below fool automake into accepting it +mdemo_LDADD = @LIBLTDL@ libsub.la "-dlopen" self \ + "-dlopen" foo1.la "-dlopen" libfoo2.la +mdemo_DEPENDENCIES = @LIBLTDL@ libsub.la foo1.la libfoo2.la + +# Create a statically linked version of mdemo. +mdemo_static_SOURCES = $(mdemo_SOURCES) +mdemo_static_LDFLAGS = $(STATIC) $(mdemo_LDFLAGS) +mdemo_static_LDADD = $(mdemo_LDADD) +mdemo_static_DEPENDENCIES = $(mdemo_DEPENDENCIES) + +$(OBJECTS): libtool +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck diff -urpN libtool-1.4c/ltdldemo/README libtool/ltdldemo/README --- libtool-1.4c/ltdldemo/README Thu Jan 1 01:00:00 1970 +++ libtool/ltdldemo/README Fri Jul 27 15:06:19 2001 @@ -0,0 +1,17 @@ +This is mdemo, an example package that uses GNU libtool with an +Automake-generated environment to build two simple modules and +a program. + +It demonstrates how to build both dynamic and static libraries +that can be dlopened. mdemo uses libtool's portable dlopen +wrapper called "libltdl". +All exported symbols are prefixed with "libname_LTX_" to avoid +symbols conflicts, especially when linking statically. +libltdl will automatically cut the prefix off to get the real name. + +Note that on Windows, for the purposes of illustrating ltdl, the +libraries *are* built as dll's, but do not have the __declspec +machinery to make them suitable for loading at link time. This is +only for clarity inside this example, look at the example in ../demo +to see how the __declspec macros should be set up. + diff -urpN libtool-1.4c/ltdldemo/configure.ac libtool/ltdldemo/configure.ac --- libtool-1.4c/ltdldemo/configure.ac Thu Jan 1 01:00:00 1970 +++ libtool/ltdldemo/configure.ac Fri Jul 27 15:06:21 2001 @@ -0,0 +1,35 @@ +dnl Process this file with autoconf to create configure. -*-Autoconf-*- + +AC_PREREQ(2.50) +AC_INIT(mdemo, 0.1) +AC_CONFIG_SRCDIR([main.c]) +AM_INIT_AUTOMAKE(mdemo,0.1) + +AC_PROG_CC +AC_C_CONST +AC_EXEEXT + +AC_LIBLTDL_CONVENIENCE(../libltdl) +AC_SUBST(INCLTDL) +AC_SUBST(LIBLTDL) + +AC_LIBTOOL_WIN32_DLL +AC_LIBTOOL_DLOPEN +AM_PROG_LIBTOOL +AC_SUBST(LIBTOOL_DEPS) + +if ${CONFIG_SHELL} ./libtool --features | grep "enable static" >/dev/null; then + STATIC=-static +else + STATIC= +fi +AC_SUBST(STATIC) + +AC_CHECK_HEADERS(math.h) + +AC_CHECK_LIBM +AC_SUBST(LIBM) + +dnl Output the makefile +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff -urpN libtool-1.4c/ltdldemo/foo.h libtool/ltdldemo/foo.h --- libtool-1.4c/ltdldemo/foo.h Thu Jan 1 01:00:00 1970 +++ libtool/ltdldemo/foo.h Fri Jul 27 15:06:21 2001 @@ -0,0 +1,31 @@ +/* foo.h -- interface to the libfoo* libraries + Copyright (C) 1998-1999 Free Software Foundation, Inc. + Originally by Thomas Tanner + This file is part of GNU Libtool. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA. */ + +/* Only include this header file once. */ +#ifndef _FOO_H_ +#define _FOO_H_ 1 + +/* Silly constants that the functions return. */ +#define HELLO_RET 0xe110 +#define FOO_RET 0xf00 + +extern void sub(); + +#endif /* !_FOO_H_ */ diff -urpN libtool-1.4c/ltdldemo/foo1.c libtool/ltdldemo/foo1.c --- libtool-1.4c/ltdldemo/foo1.c Thu Jan 1 01:00:00 1970 +++ libtool/ltdldemo/foo1.c Fri Jul 27 15:06:21 2001 @@ -0,0 +1,57 @@ +/* foo1.c -- trivial test library + Copyright (C) 1998-1999 Free Software Foundation, Inc. + Originally by Thomas Tanner + This file is part of GNU Libtool. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA. */ + +#include "foo.h" +#include + +#ifdef HAVE_MATH_H +#include +#endif + +#define nothing foo1_LTX_nothing +#define foo1 foo1_LTX_foo1 +#define hello foo1_LTX_hello + +/* Give a global variable definition. */ +int nothing; + +/* private function */ +int +_foo1_helper() +{ + sub(); + return FOO_RET; +} + +/* exported functions */ + +int +foo1() +{ + printf ("cos (0.0) = %g\n", (double) cos ((double) 0.0)); + return _foo1_helper(); +} + +int +hello() +{ + printf ("** This is foolib 1 **\n"); + return HELLO_RET; +} diff -urpN libtool-1.4c/ltdldemo/foo2.c libtool/ltdldemo/foo2.c --- libtool-1.4c/ltdldemo/foo2.c Thu Jan 1 01:00:00 1970 +++ libtool/ltdldemo/foo2.c Fri Jul 27 15:06:21 2001 @@ -0,0 +1,57 @@ +/* foo2.c -- trivial test library + Copyright (C) 1998-1999 Free Software Foundation, Inc. + Originally by Thomas Tanner + This file is part of GNU Libtool. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA. */ + +#include "foo.h" +#include + +#ifdef HAVE_MATH_H +#include +#endif + +#define nothing libfoo2_LTX_nothing +#define foo2 libfoo2_LTX_foo2 +#define hello libfoo2_LTX_hello + +/* Give a global variable definition. */ +int nothing; + +/* private function */ +int +_foo2_helper() +{ + sub(); + return FOO_RET; +} + +/* exported functions */ + +int +foo2() +{ + printf ("sin (0.0) = %g\n", (double) sin ((double) 0.0)); + return _foo2_helper(); +} + +int +hello() +{ + printf ("** This is foolib 2 **\n"); + return HELLO_RET; +} diff -urpN libtool-1.4c/ltdldemo/main.c libtool/ltdldemo/main.c --- libtool-1.4c/ltdldemo/main.c Thu Jan 1 01:00:00 1970 +++ libtool/ltdldemo/main.c Fri Jul 27 15:06:21 2001 @@ -0,0 +1,195 @@ +/* main.c -- mdemo test program + Copyright (C) 1998-2000 Free Software Foundation, Inc. + Originally by Thomas Tanner + This file is part of GNU Libtool. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA. */ + +#include "foo.h" +#include "ltdl.h" +#include + +int +test_dl (filename) + char *filename; +{ + lt_dlhandle handle; + const lt_dlinfo *info; + int (*pfoo1)() = 0; + int (*pfoo2)() = 0; + int (*phello)() = 0; + int *pnothing = 0; + int ret = 0; + + handle = lt_dlopen(filename); + if (!handle) { + fprintf (stderr, "can't open the module %s!\n", filename); + fprintf (stderr, "error was: %s\n", lt_dlerror()); + return 1; + } + + info = lt_dlgetinfo(handle); + if (!info) { + fprintf (stderr, "can't get module info: %s\n", lt_dlerror()); + return 1; + } + if (info->name) { + printf ("module name: %s\n", info->name); + } else { + printf ("module is not a libtool module\n"); + } + printf ("module filename: %s\n", info->filename); + printf ("module reference count: %i\n", info->ref_count); + + phello = (int(*)())lt_dlsym(handle, "hello"); + if (phello) + { + int value = (*phello) (); + + printf ("hello returned: %i\n", value); + if (value == HELLO_RET) + printf("hello is ok!\n"); + } + else + { + fprintf (stderr, "did not find the `hello' function\n"); + fprintf (stderr, "error was: %s\n", lt_dlerror()); + ret = 1; + } + + pnothing = (int*)lt_dlsym(handle, "nothing"); + /* Try assigning to the nothing variable. */ + if (pnothing) + *pnothing = 1; + else + { + fprintf (stderr, "did not find the `nothing' variable\n"); + fprintf (stderr, "error was: %s\n", lt_dlerror()); + ret = 1; + } + + pfoo1 = (int(*)())lt_dlsym(handle, "foo1"); + /* Just call the functions and check return values. */ + if (pfoo1) + { + if ((*pfoo1) () == FOO_RET) + printf("foo1 is ok!\n"); + else + ret = 1; + } + else { + pfoo2 = (int(*)())lt_dlsym(handle, "foo2"); + if (pfoo2) + { + if ((*pfoo2) () == FOO_RET) + printf("foo2 is ok!\n"); + else ret = 1; + } + else + { + fprintf (stderr, "did not find any of the `foo' functions\n"); + fprintf (stderr, "error was: %s\n", lt_dlerror()); + ret = 1; + } + } + lt_dlclose(handle); + return ret; +} + +int +myfunc () +{ + return HELLO_RET; +} + +int myvar; + +int +test_dlself () +{ + lt_dlhandle handle; + int (*pmyfunc)() = 0; + int *pmyvar = 0; + int ret = 0; + + handle = lt_dlopen(0); + if (!handle) { + fprintf (stderr, "can't dlopen the program!\n"); + fprintf (stderr, "error was: %s\n", lt_dlerror()); + return 1; + } + + pmyfunc = (int(*)())lt_dlsym(handle, "myfunc"); + if (pmyfunc) + { + int value = (*pmyfunc) (); + + printf ("myfunc returned: %i\n", value); + if (value == HELLO_RET) + printf("myfunc is ok!\n"); + } + else + { + fprintf (stderr, "did not find the `myfunc' function\n"); + fprintf (stderr, "error was: %s\n", lt_dlerror()); + ret = 1; + } + + pmyvar = (int*)lt_dlsym(handle, "myvar"); + /* Try assigning to the variable. */ + if (pmyvar) + *pmyvar = 1; + else + { + fprintf (stderr, "did not find the `myvar' variable\n"); + fprintf (stderr, "error was: %s\n", lt_dlerror()); + ret = 1; + } + + lt_dlclose(handle); + return ret; +} + +int +main (argc, argv) + int argc; + char **argv; +{ + int i; + int ret = 0; + + printf ("Welcome to GNU libtool mdemo!\n"); + + if (argc < 2) { + fprintf (stderr, "usage: %s module [module...]\n", argv[0]); + } + + LTDL_SET_PRELOADED_SYMBOLS(); + if (lt_dlinit() != 0) { + fprintf (stderr, "error during initialization: %s\n", lt_dlerror()); + return 1; + } + + for (i = 1; i < argc; i++) + if (test_dl(argv[i])) + ret = 1; + + if (test_dlself()) + ret = 1; + + lt_dlexit(); + return ret; +} diff -urpN libtool-1.4c/ltdldemo/sub.c libtool/ltdldemo/sub.c --- libtool-1.4c/ltdldemo/sub.c Thu Jan 1 01:00:00 1970 +++ libtool/ltdldemo/sub.c Fri Jul 27 15:06:21 2001 @@ -0,0 +1,27 @@ +/* sub.c -- trivial test library + Copyright (C) 1998-1999 Free Software Foundation, Inc. + Originally by Thomas Tanner + This file is part of GNU Libtool. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA. */ + +#include + +void +sub() +{ + printf ("sub() called\n"); +} Binary files libtool-1.4c/mdemo/.libs/.nfs8E97 and libtool/mdemo/.libs/.nfs8E97 differ Binary files libtool-1.4c/mdemo/.libs/.nfs9E97 and libtool/mdemo/.libs/.nfs9E97 differ