diff -uNr arts-1.3.2/admin/ltmain.sh arts-1.3.2-new/admin/ltmain.sh --- arts-1.3.2/admin/ltmain.sh Tue Jun 15 12:47:06 2004 +++ arts-1.3.2-new/admin/ltmain.sh Wed Dec 15 13:41:49 2004 @@ -4397,6 +4397,7 @@ # We should set the shlibpath_var rpath= for dir in $temp_rpath; do + if test "$dir" != "@FINKPREFIX@/lib"; then case $dir in [\\/]* | [A-Za-z]:[\\/]*) # Absolute path. @@ -4407,6 +4408,7 @@ rpath="$rpath\$thisdir/$dir:" ;; esac + fi done temp_rpath="$rpath" fi diff -uNr arts-1.3.2/configure arts-1.3.2-new/configure --- arts-1.3.2/configure Mon Nov 29 10:03:07 2004 +++ arts-1.3.2-new/configure Wed Dec 15 13:42:07 2004 @@ -9529,10 +9529,21 @@ archive_cmds_need_lc=no case "$host_os" in rhapsody* | darwin1.[012]) - allow_undefined_flag='-undefined suppress' + allow_undefined_flag='-Wl,-undefined -Wl,suppress' ;; *) # Darwin 1.3 on - test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag='-flat_namespace -undefined suppress' + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + ;; + 10.*) + allow_undefined_flag='-Wl,-undefined -Wl,dynamic_lookup' + ;; + esac + fi ;; esac lt_int_apple_cc_single_mod=no @@ -11379,10 +11390,21 @@ archive_cmds_need_lc=no case "$host_os" in rhapsody* | darwin1.[012]) - allow_undefined_flag='-undefined suppress' + allow_undefined_flag='-Wl,-undefined -Wl,suppress' ;; *) # Darwin 1.3 on - test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag='-flat_namespace -undefined suppress' + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + ;; + 10.*) + allow_undefined_flag='-Wl,-undefined -Wl,dynamic_lookup' + ;; + esac + fi ;; esac output_verbose_link_cmd='echo' @@ -12430,10 +12452,21 @@ archive_cmds_need_lc_CXX=no case "$host_os" in rhapsody* | darwin1.[012]) - allow_undefined_flag_CXX='-undefined suppress' + allow_undefined_flag_CXX='-Wl,-undefined -Wl,suppress' ;; *) # Darwin 1.3 on - test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag_CXX='-flat_namespace -undefined suppress' + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + ;; + 10.*) + allow_undefined_flag='-Wl,-undefined -Wl,dynamic_lookup' + ;; + esac + fi ;; esac lt_int_apple_cc_single_mod=no @@ -16253,10 +16286,21 @@ archive_cmds_need_lc_F77=no case "$host_os" in rhapsody* | darwin1.[012]) - allow_undefined_flag_F77='-undefined suppress' + allow_undefined_flag_F77='-Wl,-undefined -Wl,suppress' ;; *) # Darwin 1.3 on - test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag_F77='-flat_namespace -undefined suppress' + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + ;; + 10.*) + allow_undefined_flag='-Wl,-undefined -Wl,dynamic_lookup' + ;; + esac + fi ;; esac lt_int_apple_cc_single_mod=no @@ -18535,10 +18579,21 @@ archive_cmds_need_lc_GCJ=no case "$host_os" in rhapsody* | darwin1.[012]) - allow_undefined_flag_GCJ='-undefined suppress' + allow_undefined_flag_GCJ='-Wl,-undefined -Wl,suppress' ;; *) # Darwin 1.3 on - test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag_GCJ='-flat_namespace -undefined suppress' + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='-Wl,-flat_namespace -Wl,-undefined -Wl,suppress' + ;; + 10.*) + allow_undefined_flag='-Wl,-undefined -Wl,dynamic_lookup' + ;; + esac + fi ;; esac lt_int_apple_cc_single_mod=no @@ -22393,6 +22448,9 @@ libltdl_cv_sys_dlopen_deplibs=unknown case "$host_os" in cygwin*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + darwin*) libltdl_cv_sys_dlopen_deplibs=yes ;; linux*) diff -uNr arts-1.3.2/examples/Makefile.in arts-1.3.2-new/examples/Makefile.in --- arts-1.3.2/examples/Makefile.in Mon Nov 29 10:03:05 2004 +++ arts-1.3.2-new/examples/Makefile.in Wed Dec 15 13:41:49 2004 @@ -540,7 +540,7 @@ testasubsys_SOURCES = testasubsys.cc testasubsys_LDADD = $(FLOWLIBS) testthreads_SOURCES = testthreads.cc -testthreads_LDFLAGS = $(LDFLAGS) +testthreads_LDFLAGS = $(all_libraries) testthreads_LDADD = $(top_builddir)/mcop_mt/libmcop_mt.la testnothreads_SOURCES = testthreads.cc testaggregation_SOURCES = aggregation.cc testaggregation.cc @@ -560,7 +560,7 @@ artsccat_SOURCES = artsccat.c artscrec_LDADD = $(top_builddir)/artsc/libartsc.la artscrec_SOURCES = artscrec.c -artscmt_LDFLAGS = $(LDFLAGS) $(USE_THREADS) +artscmt_LDFLAGS = $(all_libraries) $(USE_THREADS) artscmt_LDADD = $(top_builddir)/artsc/libartsc.la -lm $(LIBPTHREAD) $(LIBPOSIX4) artscmt_SOURCES = artscmt.c playtofile_SOURCES = playtofile.cc playtofile_impl.cc playtofile_main.cc diff -uNr arts-1.3.2/flow/Makefile.in arts-1.3.2-new/flow/Makefile.in --- arts-1.3.2/flow/Makefile.in Mon Nov 29 10:03:05 2004 +++ arts-1.3.2-new/flow/Makefile.in Wed Dec 15 13:41:49 2004 @@ -424,7 +424,7 @@ libartsflow_la_LIBADD = $(top_builddir)/mcop/libmcop.la libartsflow_idl.la $(top_builddir)/flow/gslpp/libgslpp.la $(LIBAUDIOFILE) $(LIBASOUND) $(LIBAUDIOIO) $(LIBOSSAUDIO) $(LIBAUDIONAS) $(LIBCSL) $(SGILIBAUDIO) $(LIBESD) $(LIBMAS) $(JACK_LIBADD) -lm \ $(top_builddir)/flow/gsl/libgsl.la -#>- libartsflow_la_LDFLAGS = $(MAS_LDFLAGS) $(JACK_LDFLAGS) -no-undefined -version-info 1:0 +#>- libartsflow_la_LDFLAGS = $(MAS_LDFLAGS) $(JACK_LDFLAGS) $(all_libraries) -no-undefined -version-info 1:0 #>+ 1 libartsflow_la_LDFLAGS = $(MAS_LDFLAGS) $(JACK_LDFLAGS) -no-undefined $(KDE_NO_UNDEFINED) -version-info 1:0 libartsflow_la_COMPILE_FIRST = artsflow.h diff -uNr arts-1.3.2/libltdl/Makefile.in arts-1.3.2-new/libltdl/Makefile.in --- arts-1.3.2/libltdl/Makefile.in Mon Nov 29 10:03:05 2004 +++ arts-1.3.2-new/libltdl/Makefile.in Wed Dec 15 13:41:49 2004 @@ -106,7 +106,7 @@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ +DEFS = @DEFS@ -DHAVE_UNISTD_H -DHAVE_MEMMOVE -DHAVE_CLOSEDIR -DHAVE_OPENDIR -DHAVE_READDIR -Derror_t=int -DHAVE_ERRNO_H DEPDIR = @DEPDIR@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ @@ -591,7 +591,7 @@ .NOEXPORT: #>+ 2 -KDE_DIST=Makefile.in ltdl.m4 Makefile.am +KDE_DIST=Makefile.in ltdl.m4 Makefile.am #>+ 2 docs-am: diff -uNr arts-1.3.2/libltdl/ltdl.c arts-1.3.2-new/libltdl/ltdl.c --- arts-1.3.2/libltdl/ltdl.c Fri Apr 2 08:48:51 2004 +++ arts-1.3.2-new/libltdl/ltdl.c Wed Dec 15 13:41:49 2004 @@ -29,12 +29,22 @@ # include #endif +#if HAVE_UNISTD_H +# include +#endif + #if HAVE_STDIO_H # include #endif +/* Include the header defining malloc. On K&R C compilers, + that's , on ANSI C and ISO C compilers, that's . */ #if HAVE_STDLIB_H # include +#else +# if HAVE_MALLOC_H +# include +# endif #endif #if HAVE_STRING_H @@ -49,27 +59,79 @@ # include #endif -#if HAVE_MALLOC_H -# include -#endif - #if HAVE_MEMORY_H # include #endif -#ifdef _AIX -#include -#include -#include -#endif /* _AIX */ +#if HAVE_ERRNO_H +# include +#endif + + +#ifndef __WINDOWS__ +# ifdef __WIN32__ +# define __WINDOWS__ +# endif +#endif + + +#undef LT_USE_POSIX_DIRENT +#ifdef HAVE_CLOSEDIR +# ifdef HAVE_OPENDIR +# ifdef HAVE_READDIR +# ifdef HAVE_DIRENT_H +# define LT_USE_POSIX_DIRENT +# endif /* HAVE_DIRENT_H */ +# endif /* HAVE_READDIR */ +# endif /* HAVE_OPENDIR */ +#endif /* HAVE_CLOSEDIR */ + + +#undef LT_USE_WINDOWS_DIRENT_EMULATION +#ifndef LT_USE_POSIX_DIRENT +# ifdef __WINDOWS__ +# define LT_USE_WINDOWS_DIRENT_EMULATION +# endif /* __WINDOWS__ */ +#endif /* LT_USE_POSIX_DIRENT */ + + +#ifdef LT_USE_POSIX_DIRENT +# include +# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) +#else +# ifdef LT_USE_WINDOWS_DIRENT_EMULATION +# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) +# else +# define dirent direct +# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen) +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +# endif +#endif + +#if HAVE_ARGZ_H +# include +#endif + +#if HAVE_ASSERT_H +# include +#else +# define assert(arg) ((void) 0) +#endif #include "ltdl.h" -/* Bah. We don't want inline. Needs autoconf check, which we don't want. */ -#ifdef inline -# undef inline +#if WITH_DMALLOC +# include #endif -#define inline + @@ -90,12 +152,41 @@ # define LT_READTEXT_MODE "r" #endif +#ifdef LT_USE_WINDOWS_DIRENT_EMULATION +#include + +#define dirent lt_dirent +#define DIR lt_DIR + +struct dirent +{ + char d_name[2048]; + int d_namlen; +}; + +typedef struct _DIR +{ + HANDLE hSearch; + WIN32_FIND_DATA Win32FindData; + BOOL firsttime; + struct dirent file_info; +} DIR; + +#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */ /* --- MANIFEST CONSTANTS --- */ +/* Standard libltdl search path environment variable name */ +#undef LTDL_SEARCHPATH_VAR +#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" + +/* Standard libtool archive file extension. */ +#undef LTDL_ARCHIVE_EXT +#define LTDL_ARCHIVE_EXT ".la" + /* max. filename length */ #ifndef LT_FILENAME_MAX # define LT_FILENAME_MAX 1024 @@ -112,6 +203,593 @@ +/* --- 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)); */ +#define rpl_realloc realloc + +/* 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. */ +#if WITH_DMALLOC + +#define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) +#define LT_DLFREE(p) \ + LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) + +#else + +#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((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_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp))) + +#endif + +#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ + if ((p) != (q)) { if (p) 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)); + +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 LT_PARAMS((const char *str1, const char *str2)); + +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 LT_PARAMS((const char *str, int ch)); + +static 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)); + +static 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)); + +static 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)); + +static 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 */ + +#ifdef LT_USE_WINDOWS_DIRENT_EMULATION + +static void closedir LT_PARAMS((DIR *entry)); + +static void +closedir(entry) + DIR *entry; +{ + assert(entry != (DIR *) NULL); + FindClose(entry->hSearch); + lt_dlfree((lt_ptr)entry); +} + + +static DIR * opendir LT_PARAMS((const char *path)); + +static DIR* +opendir (path) + const char *path; +{ + char file_specification[LT_FILENAME_MAX]; + DIR *entry; + + assert(path != (char *) NULL); + (void) strncpy(file_specification,path,LT_FILENAME_MAX-1); + (void) strcat(file_specification,"\\"); + entry = LT_DLMALLOC (DIR,sizeof(DIR)); + if (entry != (DIR *) 0) + { + entry->firsttime = TRUE; + entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData); + } + if (entry->hSearch == INVALID_HANDLE_VALUE) + { + (void) strcat(file_specification,"\\*.*"); + entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData); + if (entry->hSearch == INVALID_HANDLE_VALUE) + { + LT_DLFREE (entry); + return (DIR *) 0; + } + } + return(entry); +} + + +static struct dirent *readdir LT_PARAMS((DIR *entry)); + +static struct dirent *readdir(entry) + DIR *entry; +{ + int + status; + + if (entry == (DIR *) 0) + return((struct dirent *) 0); + if (!entry->firsttime) + { + status = FindNextFile(entry->hSearch,&entry->Win32FindData); + if (status == 0) + return((struct dirent *) 0); + } + entry->firsttime = FALSE; + (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName, + LT_FILENAME_MAX-1); + entry->file_info.d_namlen = strlen(entry->file_info.d_name); + return(&entry->file_info); +} + +#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */ + +/* 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 +*/ +#if 0 + /* You can't (re)define realloc unless you also (re)define malloc. + Right now, this code uses the size of the *destination* to decide + how much to copy. That's not right, but you can't know the size + of the source unless you know enough about, or wrote malloc. So + this code is disabled... */ + +static 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; + } +} +#endif + + +#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)); + +static 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_DLREALLOC (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)); + +static 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 = 1+ LT_STRLEN (str); + if (argz_len) + { + const char *p; + char *q; + + argz = LT_DLMALLOC (char, 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; + } + /* Copy terminating LT_EOS_CHAR. */ + *q = *p; + } + + /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ + if (!argz_len) + LT_DLFREE (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)); + +static 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); + + /* 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_DLREALLOC (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)); + +static 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 */ + + + +#if ! HAVE_ARGZ_STRINGIFY +# define argz_stringify rpl_argz_stringify + +static void argz_stringify LT_PARAMS((char *argz, size_t argz_len, + int sep)); + +static void +argz_stringify (argz, argz_len, sep) + char *argz; + size_t argz_len; + int sep; +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (sep) + { + --argz_len; /* don't stringify the terminating EOS */ + while (--argz_len > 0) + { + if (argz[argz_len] == LT_EOS_CHAR) + argz[argz_len] = sep; + } + } +} +#endif /* !HAVE_ARGZ_STRINGIFY */ + + + + /* --- TYPE DEFINITIONS -- */ @@ -128,7 +806,7 @@ /* 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[] = { @@ -169,10 +847,6 @@ #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag)) #define LT_DLRESIDENT_FLAG (0x01 << 0) -#ifdef _AIX -#define LT_DLNOTFOUND_FLAG (0x01 << 1) /* may be linked statically */ -#define LT_DLMEMBER_FLAG RTLD_MEMBER -#endif /* _AIX */ /* ...add more flags here... */ #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG) @@ -181,6 +855,7 @@ #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] static const char objdir[] = LTDL_OBJDIR; +static const char archive_ext[] = LTDL_ARCHIVE_EXT; #ifdef LTDL_SHLIB_EXT static const char shlib_ext[] = LTDL_SHLIB_EXT; #endif @@ -194,29 +869,33 @@ /* --- MUTEX LOCKING --- */ -/* Macros to make it easier to run the lock functions only if they have +/* Macros to make it easier to run the lock functions only if they have been registered. The reason for the complicated lock macro is to - ensure that the stored error message from the last error is not + ensure that the stored error message from the last error is not accidentally erased if the current function doesn't generate an error of its own. */ -#define MUTEX_LOCK() LT_STMT_START { \ - if (mutex_lock) (*mutex_lock)(); } LT_STMT_END -#define MUTEX_UNLOCK() LT_STMT_START { \ - if (mutex_unlock) (*mutex_unlock)(); } LT_STMT_END -#define MUTEX_SETERROR(errormsg) LT_STMT_START { \ - if (mutex_seterror) (*mutex_seterror) (errormsg); \ - else last_error = (errormsg); } LT_STMT_END -#define MUTEX_GETERROR(errormsg) LT_STMT_START { \ - if (mutex_seterror) errormsg = (*mutex_geterror)(); \ - else (errormsg) = last_error; } LT_STMT_END +#define LT_DLMUTEX_LOCK() LT_STMT_START { \ + if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \ + } LT_STMT_END +#define LT_DLMUTEX_UNLOCK() LT_STMT_START { \ + if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\ + } LT_STMT_END +#define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \ + if (lt_dlmutex_seterror_func) \ + (*lt_dlmutex_seterror_func) (errormsg); \ + else lt_dllast_error = (errormsg); } LT_STMT_END +#define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \ + if (lt_dlmutex_seterror_func) \ + (errormsg) = (*lt_dlmutex_geterror_func) (); \ + else (errormsg) = lt_dllast_error; } LT_STMT_END /* The mutex functions stored here are global, and are necessarily the same for all threads that wish to share access to libltdl. */ -static lt_dlmutex_lock *mutex_lock = 0; -static lt_dlmutex_unlock *mutex_unlock = 0; -static lt_dlmutex_seterror *mutex_seterror = 0; -static lt_dlmutex_geterror *mutex_geterror = 0; -static const char *last_error = 0; +static lt_dlmutex_lock *lt_dlmutex_lock_func = 0; +static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0; +static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0; +static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0; +static const char *lt_dllast_error = 0; /* Either set or reset the mutex functions. Either all the arguments must @@ -229,296 +908,130 @@ lt_dlmutex_unlock *unlock; lt_dlmutex_seterror *seterror; lt_dlmutex_geterror *geterror; -{ - lt_dlmutex_unlock *old_unlock = unlock; - int errors = 0; - - /* Lock using the old lock() callback, if any. */ - MUTEX_LOCK (); - - if ((lock && unlock && seterror && geterror) - || !(lock || unlock || seterror || geterror)) - { - mutex_lock = lock; - mutex_unlock = unlock; - mutex_geterror = geterror; - } - else - { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS)); - ++errors; - } - - /* Use the old unlock() callback we saved earlier, if any. Otherwise - record any errors using internal storage. */ - if (old_unlock) - (*old_unlock) (); - - /* Return the number of errors encountered during the execution of - this function. */ - return errors; -} - - - - -/* --- 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 --- */ - - -static const char **user_error_strings = 0; -static int errorcount = LT_ERROR_MAX; - -int -lt_dladderror (diagnostic) - const char *diagnostic; -{ - int _index = 0; - int result = -1; - const char **temp = (const char **) 0; - - MUTEX_LOCK (); - - _index = errorcount - LT_ERROR_MAX; - temp = LT_DLREALLOC (const char *, user_error_strings, 1 + _index); - if (temp == 0) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - } - else - { - user_error_strings = temp; - user_error_strings[_index] = diagnostic; - result = errorcount++; - } - - MUTEX_UNLOCK (); - - return result; -} - -int -lt_dlseterror (_index) - int _index; -{ - int errors = 0; - - MUTEX_LOCK (); - - if (_index >= errorcount || _index < 0) - { - /* Ack! Error setting the error message! */ - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE)); - ++errors; - } - else if (_index < LT_ERROR_MAX) - { - /* No error setting the error message! */ - MUTEX_SETERROR (lt_dlerror_strings[errorcount]); - } - else - { - /* No error setting the error message! */ - MUTEX_SETERROR (user_error_strings[errorcount - LT_ERROR_MAX]); - } - - MUTEX_UNLOCK (); - - return errors; -} - - - - -/* --- REPLACEMENT FUNCTIONS --- */ - - -#undef strdup -#define strdup rpl_strdup - -static inline 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 inline 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; +{ + lt_dlmutex_unlock *old_unlock = unlock; + int errors = 0; - for (;*str1 && *str2; ++str1, ++str2) + /* Lock using the old lock() callback, if any. */ + LT_DLMUTEX_LOCK (); + + if ((lock && unlock && seterror && geterror) + || !(lock || unlock || seterror || geterror)) { - if (*str1 != *str2) - break; + lt_dlmutex_lock_func = lock; + lt_dlmutex_unlock_func = unlock; + lt_dlmutex_geterror_func = geterror; + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS)); + ++errors; } - return (int)(*str1 - *str2); -} -#endif - + /* Use the old unlock() callback we saved earlier, if any. Otherwise + record any errors using internal storage. */ + if (old_unlock) + (*old_unlock) (); -#if ! HAVE_STRCHR + /* Return the number of errors encountered during the execution of + this function. */ + return errors; +} -# if HAVE_INDEX -# define strchr index -# else -# define strchr rpl_strchr -static inline const char* -strchr(str, ch) - const char *str; - int ch; -{ - const char *p; - for (p = str; *p != (char)ch && *p != '\0'; ++p) - /*NOWORK*/; + +/* --- ERROR HANDLING --- */ - return (*p == (char)ch) ? p : 0; -} -# endif -#endif /* !HAVE_STRCHR */ +static const char **user_error_strings = 0; +static int errorcount = LT_ERROR_MAX; -#if ! HAVE_STRRCHR +int +lt_dladderror (diagnostic) + const char *diagnostic; +{ + int errindex = 0; + int result = -1; + const char **temp = (const char **) 0; -# if HAVE_RINDEX -# define strrchr rindex -# else -# define strrchr rpl_strrchr + assert (diagnostic); -static inline const char* -strrchr(str, ch) - const char *str; - int ch; -{ - const char *p, *q = 0; + LT_DLMUTEX_LOCK (); - for (p = str; *p != '\0'; ++p) + errindex = errorcount - LT_ERROR_MAX; + temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex); + if (temp) { - if (*p == (char) ch) - { - q = p; - } + user_error_strings = temp; + user_error_strings[errindex] = diagnostic; + result = errorcount++; } - 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 behavior when invoking memcpy later. */ -#if ! HAVE_MEMCPY + LT_DLMUTEX_UNLOCK (); -# if HAVE_BCOPY -# define memcpy(dest, src, size) bcopy (src, dest, size) -# else -# define memcpy rpl_memcpy + return result; +} -static inline char * -memcpy (dest, src, size) - char *dest; - const char *src; - size_t size; +int +lt_dlseterror (errindex) + int errindex; { - size_t i = 0; + int errors = 0; - for (i = 0; i < size; ++i) + LT_DLMUTEX_LOCK (); + + if (errindex >= errorcount || errindex < 0) { - dest[i] = src[i]; + /* Ack! Error setting the error message! */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE)); + ++errors; + } + else if (errindex < LT_ERROR_MAX) + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]); + } + else + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]); } - return dest; -} + LT_DLMUTEX_UNLOCK (); -# endif -#endif + return errors; +} -/* 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; +lt_emalloc (size) size_t size; { - if (size < 1) - { - /* For zero or less bytes, free the original memory */ - if (ptr != 0) - { - lt_dlfree (ptr); - } + lt_ptr mem = lt_dlmalloc (size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} - 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_ptr) realloc (ptr, size); +static lt_ptr +lt_erealloc (addr, size) + lt_ptr addr; + size_t size; +{ + lt_ptr mem = lt_dlrealloc (addr, size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} - /* Note that the contents of PTR are not damaged if there is - insufficient memory to realloc. */ - return mem; - } +static char * +lt_estrdup (str) + const char *str; +{ + char *copy = strdup (str); + if (LT_STRLEN (str) && !copy) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return copy; } @@ -526,11 +1039,8 @@ /* --- DLOPEN() INTERFACE LOADER --- */ -/* The Cygwin dlopen implementation prints a spurious error message to - stderr if its call to LoadLibrary() fails for any reason. We can - mitigate this by not using the Cygwin implementation, and falling - back to our own LoadLibrary() wrapper. */ -#if HAVE_LIBDL && !defined(__CYGWIN__) + +#if HAVE_LIBDL /* dynamic linking with dlopen/dlsym */ @@ -538,6 +1048,10 @@ # include #endif +#if HAVE_SYS_DL_H +# include +#endif + #ifdef RTLD_GLOBAL # define LT_GLOBAL RTLD_GLOBAL #else @@ -581,38 +1095,16 @@ int lt_dlopen_flag = LT_LAZY_OR_NOW; -#ifdef _AIX -/*------------------------------------------------------------------*/ -/* implementations found at the end */ -/*------------------------------------------------------------------*/ - -static void -sys_dl_init( ); - -static lt_dlhandle -sys_dl_search_by_name( const char* name ); - -static void -sys_dl_not_found_entry( const char* tmp ); -#endif /* _AIX */ - static lt_module sys_dl_open (loader_data, filename) lt_user_data loader_data; const char *filename; { - lt_module module; -#ifdef _AIX - /* If the basename is of the form "libname.a(member)", - set the appropriate flag. */ - if (strrchr(filename, '(')) - lt_dlopen_flag |= LT_DLMEMBER_FLAG; -#endif - module = dlopen (filename, lt_dlopen_flag); + lt_module module = dlopen (filename, LT_GLOBAL | lt_dlopen_flag); if (!module) { - MUTEX_SETERROR (DLERROR (CANNOT_OPEN)); + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN)); } return module; @@ -627,7 +1119,7 @@ if (dlclose (module) != 0) { - MUTEX_SETERROR (DLERROR (CANNOT_CLOSE)); + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE)); ++errors; } @@ -644,7 +1136,7 @@ if (!address) { - MUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND)); + LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND)); } return address; @@ -720,20 +1212,33 @@ lt_user_data loader_data; const char *filename; { - /* A NULL handle is used to get symbols from self and everything - else already loaded that was exported with -E compiler flag. */ - lt_module module = (lt_module) 0; + static shl_t self = (shl_t) 0; + lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); - if (filename) + /* Since searching for a symbol against a NULL module handle will also + look in everything else that was already loaded and exported with + the -E compiler flag, we always cache a handle saved before any + modules are loaded. */ + if (!self) + { + lt_ptr address; + shl_findsym (&self, "main", TYPE_UNDEFINED, &address); + } + + if (!filename) + { + module = self; + } + else { module = shl_load (filename, LT_BIND_FLAGS, 0L); if (!module) { - MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); } } - + return module; } @@ -746,7 +1251,7 @@ if (module && (shl_unload ((shl_t) (module)) != 0)) { - MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } @@ -759,23 +1264,20 @@ lt_module module; const char *symbol; { - int is_module_self = (module == (lt_module) 0); - lt_ptr address = 0; + lt_ptr address = 0; - /* shl_findsym considers zero valued MODULE as an indicator to search - for a symbol among all loaded (and exported) symbols including those - in the main executable. However, it sets MODULE to a valid module - address which breaks the semantics of libltdl's module management. */ - if (shl_findsym ((shl_t*) &module, symbol, TYPE_UNDEFINED, &address) == 0) + /* sys_shl_open should never return a NULL module handle */ + if (module == (lt_module) 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + } + else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address)) { if (!address) { - MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); } } - - if (is_module_self) - module = (lt_module) 0; return address; } @@ -791,7 +1293,7 @@ /* --- LOADLIBRARY() INTERFACE LOADER --- */ -#if defined(__WINDOWS__) || defined(__CYGWIN__) +#ifdef __WINDOWS__ /* dynamic linking for Win32 */ @@ -827,21 +1329,18 @@ 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+ strlen (filename)); - if (!searchname) - { - MUTEX_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__ { @@ -862,7 +1361,7 @@ We check whether LoadLibrary is returning a handle to an already loaded module, and simulate failure if we find one. */ - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); cur = handles; while (cur) { @@ -879,11 +1378,11 @@ cur = cur->next; } - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); if (cur || !module) { - MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); module = 0; } @@ -899,7 +1398,7 @@ if (FreeLibrary(module) == 0) { - MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } @@ -916,7 +1415,7 @@ if (!address) { - MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); } return address; @@ -961,7 +1460,7 @@ if (image <= 0) { - MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); image = 0; } @@ -977,7 +1476,7 @@ if (unload_add_on ((image_id) module) != B_OK) { - MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); ++errors; } @@ -995,7 +1494,7 @@ if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) { - MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); address = 0; } @@ -1014,79 +1513,417 @@ /* --- DLD_LINK() INTERFACE LOADER --- */ -#if HAVE_DLD +#if HAVE_DLD + +/* dynamic linking with dld */ + +#if HAVE_DLD_H +#include +#endif + +static lt_module +sys_dld_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_module module = strdup (filename); + + if (dld_link (filename) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + LT_DLFREE (module); + module = 0; + } + + return module; +} + +static int +sys_dld_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (dld_unlink_by_file ((char*)(module), 1) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + else + { + LT_DLFREE (module); + } + + return errors; +} + +static lt_ptr +sys_dld_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = dld_get_func (symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_dld = { + 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 +}; + +#endif /* HAVE_DLD */ + +/* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */ +#if HAVE_DYLD + + +#if HAVE_MACH_O_DYLD_H +#if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__) +/* Is this correct? Does it still function properly? */ +#define __private_extern__ extern +#endif +# include +#endif +#include + +/* We have to put some stuff here that isn't in older dyld.h files */ +#ifndef ENUM_DYLD_BOOL +# define ENUM_DYLD_BOOL +# undef FALSE +# undef TRUE + enum DYLD_BOOL { + FALSE, + TRUE + }; +#endif +#ifndef LC_REQ_DYLD +# define LC_REQ_DYLD 0x80000000 +#endif +#ifndef LC_LOAD_WEAK_DYLIB +# define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) +#endif +static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0; +static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0; +static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0; +static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0; + +#ifndef NSADDIMAGE_OPTION_NONE +#define NSADDIMAGE_OPTION_NONE 0x0 +#endif +#ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR +#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1 +#endif +#ifndef NSADDIMAGE_OPTION_WITH_SEARCHING +#define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2 +#endif +#ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4 +#endif +#ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME +#define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR +#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4 +#endif + + +static const char * +lt_int_dyld_error(othererror) + char* othererror; +{ +/* return the dyld error string, or the passed in error string if none */ + NSLinkEditErrors ler; + int lerno; + const char *errstr; + const char *file; + NSLinkEditError(&ler,&lerno,&file,&errstr); + if (!errstr || !strlen(errstr)) errstr = othererror; + return errstr; +} + +static const struct mach_header * +lt_int_dyld_get_mach_header_from_nsmodule(module) + NSModule module; +{ +/* There should probably be an apple dyld api for this */ + int i=_dyld_image_count(); + int j; + const char *modname=NSNameOfModule(module); + const struct mach_header *mh=NULL; + if (!modname) return NULL; + for (j = 0; j < i; j++) + { + if (!strcmp(_dyld_get_image_name(j),modname)) + { + mh=_dyld_get_image_header(j); + break; + } + } + return mh; +} + +static const char* lt_int_dyld_lib_install_name(mh) + const struct mach_header *mh; +{ +/* NSAddImage is also used to get the loaded image, but it only works if the lib + is installed, for uninstalled libs we need to check the install_names against + each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a + different lib was loaded as a result +*/ + int j; + struct load_command *lc; + unsigned long offset = sizeof(struct mach_header); + const char* retStr=NULL; + for (j = 0; j < mh->ncmds; j++) + { + lc = (struct load_command*)(((unsigned long)mh) + offset); + if (LC_ID_DYLIB == lc->cmd) + { + retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset + + (unsigned long)lc); + } + offset += lc->cmdsize; + } + return retStr; +} + +static const struct mach_header * +lt_int_dyld_match_loaded_lib_by_install_name(const char *name) +{ + int i=_dyld_image_count(); + int j; + const struct mach_header *mh=NULL; + const char *id=NULL; + for (j = 0; j < i; j++) + { + id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j)); + if ((id) && (!strcmp(id,name))) + { + mh=_dyld_get_image_header(j); + break; + } + } + return mh; +} -/* dynamic linking with dld */ +static NSSymbol +lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh) + const char *symbol; + const struct mach_header *mh; +{ + /* Safe to assume our mh is good */ + int j; + struct load_command *lc; + unsigned long offset = sizeof(struct mach_header); + NSSymbol retSym = 0; + const struct mach_header *mh1; + if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) ) + { + for (j = 0; j < mh->ncmds; j++) + { + lc = (struct load_command*)(((unsigned long)mh) + offset); + if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd)) + { + mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset + + (unsigned long)lc)); + if (!mh1) + { + /* Maybe NSAddImage can find it */ + mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset + + (unsigned long)lc), + NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED + + NSADDIMAGE_OPTION_WITH_SEARCHING + + NSADDIMAGE_OPTION_RETURN_ON_ERROR ); + } + if (mh1) + { + retSym = ltdl_NSLookupSymbolInImage(mh1, + symbol, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR + ); + if (retSym) break; + } + } + offset += lc->cmdsize; + } + } + return retSym; +} -#if HAVE_DLD_H -#include -#endif +static int +sys_dyld_init() +{ + int retCode = 0; + int err = 0; + if (!_dyld_present()) { + retCode=1; + } + else { + err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage); + err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage); + err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage); + err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic); + } + return retCode; +} static lt_module -sys_dld_open (loader_data, filename) +sys_dyld_open (loader_data, filename) lt_user_data loader_data; const char *filename; { - lt_module module = strdup (filename); - - if (!module) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - module = 0; - } - else if (dld_link (filename) != 0) - { - MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); - LT_DLFREE (module); - module = 0; - } - + lt_module module = 0; + NSObjectFileImage ofi = 0; + NSObjectFileImageReturnCode ofirc; + + if (!filename) + return (lt_module)-1; + ofirc = NSCreateObjectFileImageFromFile(filename, &ofi); + switch (ofirc) + { + case NSObjectFileImageSuccess: + module = NSLinkModule(ofi, filename, + NSLINKMODULE_OPTION_RETURN_ON_ERROR + | NSLINKMODULE_OPTION_PRIVATE + | NSLINKMODULE_OPTION_BINDNOW); + NSDestroyObjectFileImage(ofi); + if (module) + ltdl_NSMakePrivateModulePublic(module); + break; + case NSObjectFileImageInappropriateFile: + if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage) + { + module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR); + break; + } + default: + LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN))); + return 0; + } + if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN))); return module; } static int -sys_dld_close (loader_data, module) +sys_dyld_close (loader_data, module) lt_user_data loader_data; lt_module module; { - int errors = 0; - - if (dld_unlink_by_file ((char*)(module), 1) != 0) - { - MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); - ++errors; - } - else - { - LT_DLFREE (module); - } + int retCode = 0; + int flags = 0; + if (module == (lt_module)-1) return 0; +#ifdef __BIG_ENDIAN__ + if (((struct mach_header *)module)->magic == MH_MAGIC) +#else + if (((struct mach_header *)module)->magic == MH_CIGAM) +#endif + { + LT_DLMUTEX_SETERROR("Can not close a dylib"); + retCode = 1; + } + else + { +#if 1 +/* Currently, if a module contains c++ static destructors and it is unloaded, we + get a segfault in atexit(), due to compiler and dynamic loader differences of + opinion, this works around that. +*/ + if ((const struct section *)NULL != + getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module), + "__DATA","__mod_term_func")) + { + flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; + } +#endif +#ifdef __ppc__ + flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES; +#endif + if (!NSUnLinkModule(module,flags)) + { + retCode=1; + LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE))); + } + } - return errors; + return retCode; } static lt_ptr -sys_dld_sym (loader_data, module, symbol) +sys_dyld_sym (loader_data, module, symbol) lt_user_data loader_data; lt_module module; const char *symbol; { - lt_ptr address = dld_get_func (symbol); - - if (!address) - { - MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); - } + lt_ptr address = 0; + NSSymbol *nssym = 0; + void *unused; + const struct mach_header *mh=NULL; + char saveError[256] = "Symbol not found"; + if (module == (lt_module)-1) + { + _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused); + return address; + } +#ifdef __BIG_ENDIAN__ + if (((struct mach_header *)module)->magic == MH_MAGIC) +#else + if (((struct mach_header *)module)->magic == MH_CIGAM) +#endif + { + if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage) + { + mh=module; + if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol)) + { + nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module, + symbol, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR + ); + } + } - return address; + } + else { + nssym = NSLookupSymbolInModule(module, symbol); + } + if (!nssym) + { + strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255); + saveError[255] = 0; + if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module); + nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh); + } + if (!nssym) + { + LT_DLMUTEX_SETERROR (saveError); + return NULL; + } + return NSAddressOfSymbol(nssym); } -static struct lt_user_dlloader sys_dld = { - 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 -}; - -#endif /* HAVE_DLD */ +static struct lt_user_dlloader sys_dyld = + { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 }; +#endif /* HAVE_DYLD */ /* --- DLPREOPEN() INTERFACE LOADER --- */ @@ -1109,7 +1946,7 @@ { int errors = 0; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); preloaded_symbols = 0; if (default_preloaded_symbols) @@ -1117,7 +1954,7 @@ errors = lt_dlpreload (default_preloaded_symbols); } - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return errors; } @@ -1127,7 +1964,7 @@ { lt_dlsymlists_t *lists; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); lists = preloaded_symbols; while (lists) @@ -1139,7 +1976,7 @@ } preloaded_symbols = 0; - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return 0; } @@ -1160,7 +1997,7 @@ lt_dlsymlists_t *lists; int errors = 0; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); lists = preloaded_symbols; while (lists) @@ -1172,21 +2009,21 @@ lists = lists->next; } - tmp = LT_DLMALLOC (lt_dlsymlists_t, 1); + tmp = LT_EMALLOC (lt_dlsymlists_t, 1); if (tmp) { + memset (tmp, 0, sizeof(lt_dlsymlists_t)); tmp->syms = preloaded; tmp->next = preloaded_symbols; preloaded_symbols = tmp; } else { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); ++errors; } done: - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return errors; } @@ -1198,15 +2035,19 @@ lt_dlsymlists_t *lists; lt_module module = (lt_module) 0; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); lists = preloaded_symbols; if (!lists) { - MUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS)); 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@"; @@ -1229,10 +2070,10 @@ lists = lists->next; } - MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); done: - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return module; } @@ -1265,7 +2106,7 @@ ++syms; } - MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); return 0; } @@ -1281,6 +2122,70 @@ /* --- DYNAMIC MODULE LOADING --- */ +/* The type of a function used at each iteration of foreach_dirinpath(). */ +typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + +static int foreach_dirinpath LT_PARAMS((const char *search_path, + const char *base_name, + foreach_callback_func *func, + lt_ptr data1, lt_ptr data2)); + +static int find_file_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + + +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)); +static lt_dlhandle *find_handle LT_PARAMS((const char *search_path, + const char *base_name, + lt_dlhandle *handle)); +static int find_module LT_PARAMS((lt_dlhandle *handle, + const char *dir, + const char *libdir, + const char *dlname, + const char *old_name, + int installed)); +static int free_vars LT_PARAMS((char *dlname, char *oldname, + char *libdir, char *deplibs)); +static int load_deplibs LT_PARAMS((lt_dlhandle handle, + char *deplibs)); +static int trim LT_PARAMS((char **dest, + const char *str)); +static int try_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); +static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); +static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); +static int lt_argz_insert LT_PARAMS((char **pargz, + size_t *pargz_len, + char *before, + const char *entry)); +static int lt_argz_insertinorder LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *entry)); +static int lt_argz_insertdir LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *dirnam, + struct dirent *dp)); +static int lt_dlpath_insertdir LT_PARAMS((char **ppath, + char *before, + const char *dir)); +static int list_files_by_dir LT_PARAMS((const char *dirnam, + char **pargz, + size_t *pargz_len)); +static int file_not_found LT_PARAMS((void)); + static char *user_search_path= 0; static lt_dlloader *loaders = 0; static lt_dlhandle handles = 0; @@ -1292,7 +2197,7 @@ { int errors = 0; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); /* Initialize only at first call. */ if (++initialized == 1) @@ -1300,16 +2205,13 @@ handles = 0; user_search_path = 0; /* empty search path */ -#if HAVE_LIBDL && !defined(__CYGWIN__) +#if HAVE_LIBDL errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen"); -#ifdef _AIX - sys_dl_init(); -#endif /* _AIX */ #endif #if HAVE_SHL_LOAD errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen"); #endif -#if defined(__WINDOWS__) || defined(__CYGWIN__) +#ifdef __WINDOWS__ errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen"); #endif #ifdef __BEOS__ @@ -1318,21 +2220,25 @@ #if HAVE_DLD errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld"); #endif +#if HAVE_DYLD + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld"); + errors += sys_dyld_init(); +#endif errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload"); if (presym_init (presym.dlloader_data)) { - MUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); ++errors; } else if (errors != 0) { - MUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED)); ++errors; } } - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return errors; } @@ -1349,16 +2255,14 @@ } else { - const char *errormsg = 0; - presym_free_symlists(); - - MUTEX_LOCK (); + + LT_DLMUTEX_LOCK (); if (default_preloaded_symbols) { errors = lt_dlpreload (default_preloaded_symbols); } - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); } return errors; @@ -1368,9 +2272,9 @@ lt_dlpreload_default (preloaded) const lt_dlsymlist *preloaded; { - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); default_preloaded_symbols = preloaded; - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return 0; } @@ -1379,15 +2283,14 @@ { /* shut down libltdl */ lt_dlloader *loader; - const char *errormsg; int errors = 0; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); loader = loaders; if (!initialized) { - MUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN)); ++errors; goto done; } @@ -1406,11 +2309,14 @@ for (level = 1; handles; ++level) { lt_dlhandle cur = handles; + int saw_nonresident = 0; while (cur) { lt_dlhandle tmp = cur; cur = cur->next; + if (!LT_DLIS_RESIDENT (tmp)) + saw_nonresident = 1; if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level) { if (lt_dlclose (tmp)) @@ -1419,6 +2325,9 @@ } } } + /* done if only resident modules are left */ + if (!saw_nonresident) + break; } /* close all loaders */ @@ -1437,7 +2346,7 @@ } done: - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return errors; } @@ -1451,8 +2360,8 @@ const char *saved_error; int errors = 0; - MUTEX_GETERROR (saved_error); - MUTEX_LOCK (); + LT_DLMUTEX_GETERROR (saved_error); + LT_DLMUTEX_LOCK (); cur = handles; loader = loaders; @@ -1485,18 +2394,27 @@ cur = *handle; if (filename) { - LT_DLFREE( cur->info.filename ); - cur->info.filename = strdup (filename); + /* Comment out the check of file permissions using access. + This call seems to always return -1 with error EACCES. + */ + /* We need to catch missing file errors early so that + file_not_found() can detect what happened. + if (access (filename, R_OK) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + ++errors; + goto done; + } */ + + cur->info.filename = lt_estrdup (filename); if (!cur->info.filename) { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); ++errors; goto done; } } else { - LT_DLFREE( cur->info.filename ); cur->info.filename = 0; } @@ -1521,15 +2439,66 @@ } cur->loader = loader; - last_error = saved_error; - + LT_DLMUTEX_SETERROR (saved_error); + done: - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return errors; } 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_len > 0) + 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", (int) 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) + { + error += tryall_dlopen_module (handle, + (const char *) 0, prefix, filename); + } + else if (tryall_dlopen (handle, filename) != 0) + { + ++error; + } + + LT_DLFREE (filename); + return error; +} + +static int find_module (handle, dir, libdir, dlname, old_name, installed) lt_dlhandle *handle; const char *dir; @@ -1538,252 +2507,304 @@ const char *old_name; int installed; { - 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; - /* try to open the installed module */ if (installed && libdir) { - len = strlen (libdir) + 1 + strlen (dlname); - filename = LT_DLMALLOC (char, 1+ len); - - if (!filename) - { - MUTEX_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, + (const char *) 0, libdir, dlname) == 0) + return 0; } /* try to open the not-installed module */ if (!installed) { - len = (dir ? strlen (dir) : 0) + strlen (objdir) + strlen (dlname); - filename = LT_DLMALLOC (char, 1+ len); - - if (!filename) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 1; - } - - if (dir) - { - strcpy (filename, dir); - } - else - { - *filename = 0; - } - strcat(filename, objdir); - strcat(filename, dlname); - - error = tryall_dlopen (handle, filename) != 0; - LT_DLFREE (filename); - if (!error) - { - return 0; - } + if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0) + return 0; } /* maybe it was moved to another directory */ { - len = (dir ? strlen (dir) : 0) + strlen (dlname); - filename = LT_DLMALLOC (char, 1+ len); + if (tryall_dlopen_module (handle, + (const char *) 0, dir, dlname) == 0) + return 0; + } + } + + return 1; +} - if (dir) + +static int +canonicalize_path (path, pcanonical) + const char *path; + char **pcanonical; +{ + char *canonical = 0; + + assert (path && *path); + assert (pcanonical); + + 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. */ + 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) +#ifdef LT_DIRSEP_CHAR + && (path[1+ src] != LT_DIRSEP_CHAR) +#endif + && (path[1+ src] != '/')) { - 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; - if (path && *path) - { - char *ptr = strdup (path); - canonical = ptr; + assert (path); + assert (pargz); + assert (pargz_len); -#ifdef LT_DIRSEP_CHAR - /* Avoid this overhead where '/' is the only separator. */ - while (ptr = strchr (ptr, LT_DIRSEP_CHAR)) + if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len))) + { + 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; } -static lt_ptr -find_file (basename, search_path, pdir, handle) - const char *basename; +/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element + 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; - char **pdir; - lt_dlhandle *handle; -{ - /* When handle != NULL search a library, otherwise a file - return NULL on failure, otherwise the file/handle. */ + const char *base_name; + foreach_callback_func *func; + lt_ptr data1; + lt_ptr data2; +{ + int result = 0; + int filenamesize = 0; + size_t lenbase = LT_STRLEN (base_name); + size_t argz_len = 0; + char *argz = 0; + char *filename = 0; + char *canonical = 0; - lt_ptr result = 0; - char *filename = 0; - int filenamesize= 0; - int lenbase = strlen (basename); - char *canonical = 0; - char *next = 0; - - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); if (!search_path || !*search_path) { - MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); goto cleanup; } - canonical = canonicalize_path (search_path); - if (!canonical) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - goto cleanup; - } + if (canonicalize_path (search_path, &canonical) != 0) + goto cleanup; - next = canonical; - while (next) - { - int lendir; - char *cur = next; + if (argzize_path (canonical, &argz, &argz_len) != 0) + goto cleanup; - next = strchr (cur, LT_PATHSEP_CHAR); - if (!next) - { - next = cur + strlen (cur); - } + { + char *dir_name = 0; + while ((dir_name = argz_next (argz, argz_len, dir_name))) + { + size_t lendir = LT_STRLEN (dir_name); - lendir = next - cur; - if (*next == LT_PATHSEP_CHAR) + if (lendir +1 +lenbase >= filenamesize) { - ++next; - } - else - { - next = 0; + LT_DLFREE (filename); + filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */ + filename = LT_EMALLOC (char, filenamesize); + if (!filename) + goto cleanup; } - if (lendir == 0) - { - continue; - } + assert (filenamesize > lendir); + strcpy (filename, dir_name); - if (lendir + 1 + lenbase >= filenamesize) - { - LT_DLFREE (filename); - filenamesize = lendir + 1 + lenbase + 1; - filename = LT_DLMALLOC (char, filenamesize); + if (base_name && *base_name) + { + if (filename[lendir -1] != '/') + filename[lendir++] = '/'; + strcpy (filename +lendir, base_name); + } - if (!filename) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - goto cleanup; - } - } + if ((result = (*func) (filename, data1, data2))) + { + break; + } + } + } - strncpy(filename, cur, lendir); - if (filename[lendir-1] != '/') - { - filename[lendir++] = '/'; - } - strcpy(filename+lendir, basename); - if (handle) - { - if (tryall_dlopen (handle, filename) == 0) - { - result = (lt_ptr) handle; - goto cleanup; - } - } - else - { - FILE *file = fopen (filename, LT_READTEXT_MODE); - if (file) - { - LT_DLFREE (*pdir); + cleanup: + LT_DLFREE (argz); + LT_DLFREE (canonical); + LT_DLFREE (filename); - filename[lendir] = '\0'; - *pdir = strdup(filename); - if (!*pdir) - { - /* We could have even avoided the strdup, - but there would be some memory overhead. */ - *pdir = filename; - filename = 0; - } + LT_DLMUTEX_UNLOCK (); + + return result; +} + +/* If FILEPATH 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 +find_file_callback (filename, data1, data2) + char *filename; + lt_ptr data1; + lt_ptr data2; +{ + char **pdir = (char **) data1; + FILE **pfile = (FILE **) data2; + int is_done = 0; + + assert (filename && *filename); + assert (pdir); + assert (pfile); + + if ((*pfile = fopen (filename, LT_READTEXT_MODE))) + { + char *dirend = strrchr (filename, '/'); + + if (dirend > filename) + *dirend = LT_EOS_CHAR; + + LT_DLFREE (*pdir); + *pdir = lt_estrdup (filename); + is_done = (*pdir == 0) ? -1 : 1; + } + + return is_done; +} + +static FILE * +find_file (search_path, base_name, pdir) + const char *search_path; + const char *base_name; + char **pdir; +{ + FILE *file = 0; + + foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); + + return file; +} + +static int +find_handle_callback (filename, data, ignored) + char *filename; + lt_ptr data; + lt_ptr ignored; +{ + lt_dlhandle *handle = (lt_dlhandle *) data; + int notfound = access (filename, R_OK); + + /* Bail out if file cannot be read... */ + if (notfound) + return 0; - result = (lt_ptr) file; - goto cleanup; - } - } - } + /* Try to dlopen the file, but do not continue searching in any + case. */ + if (tryall_dlopen (handle, filename) != 0) + *handle = 0; - MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + return 1; +} - cleanup: - LT_DLFREE (filename); - LT_DLFREE (canonical); +/* If HANDLE was found return it, otherwise return 0. If HANDLE was + found but could not be opened, *HANDLE will be set to 0. */ +static lt_dlhandle * +find_handle (search_path, base_name, handle) + const char *search_path; + const char *base_name; + lt_dlhandle *handle; +{ + if (!search_path) + return 0; - MUTEX_UNLOCK (); + if (!foreach_dirinpath (search_path, base_name, find_handle_callback, + handle, 0)) + return 0; - return result; + return handle; } static int -load_deplibs(handle, deplibs) +load_deplibs (handle, deplibs) lt_dlhandle handle; 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; @@ -1799,12 +2820,12 @@ } ++errors; - MUTEX_LOCK (); - save_search_path = strdup (user_search_path); - if (user_search_path && !save_search_path) + LT_DLMUTEX_LOCK (); + if (user_search_path) { - MUTEX_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 */ @@ -1846,7 +2867,7 @@ LT_DLFREE (user_search_path); user_search_path = save_search_path; - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); if (!depcount) { @@ -1854,11 +2875,9 @@ 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; @@ -1884,25 +2903,18 @@ *end = 0; /* set a temporary string terminator */ if (strncmp(p, "-l", 2) == 0) { - name = LT_DLMALLOC (char, 3+ /* "lib" */ strlen (p+2) + 1); + size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); + name = LT_EMALLOC (char, 1+ name_len); if (name) - { - sprintf (name, "lib%s", p+2); - } + 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; @@ -1918,11 +2930,9 @@ { 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) { @@ -1951,7 +2961,7 @@ } static int -unload_deplibs(handle) +unload_deplibs (handle) lt_dlhandle handle; { int i; @@ -1971,7 +2981,7 @@ return errors; } -static inline int +static int trim (dest, str) char **dest; const char *str; @@ -1979,22 +2989,19 @@ /* remove the leading and trailing "'" from str and store the result in dest */ const char *end = strrchr (str, '\''); - int len = strlen (str); + size_t len = LT_STRLEN (str); char *tmp; LT_DLFREE (*dest); if (len > 3 && str[0] == '\'') { - tmp = LT_DLMALLOC (char, end - str); + tmp = LT_EMALLOC (char, end - str); if (!tmp) - { - last_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 @@ -2005,8 +3012,8 @@ return 0; } -static inline int -free_vars( dlname, oldname, libdir, deplibs) +static int +free_vars (dlname, oldname, libdir, deplibs) char *dlname; char *oldname; char *libdir; @@ -2020,87 +3027,93 @@ return 0; } -lt_dlhandle -lt_dlopen (filename) +static int +try_dlopen (phandle, filename) + lt_dlhandle *phandle; const char *filename; { - lt_dlhandle handle = 0, newhandle; - const char *ext; - const char *saved_error; - char *canonical = 0, *basename = 0, *dir = 0, *name = 0; + const char * ext = 0; + const char * saved_error = 0; + char * canonical = 0; + char * base_name = 0; + char * dir = 0; + char * name = 0; + int errors = 0; + lt_dlhandle newhandle; + + assert (phandle); + assert (*phandle == 0); - MUTEX_GETERROR (saved_error); + LT_DLMUTEX_GETERROR (saved_error); /* dlopen self? */ if (!filename) { - handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1); - if (!handle) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 0; - } - memset( handle, 0, sizeof( struct lt_dlhandle_struct ) ); + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + return 1; - handle->info.ref_count = 0; - handle->depcount = 0; - handle->deplibs = 0; - handle->caller_data = 0; - newhandle = handle; + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + newhandle = *phandle; /* lt_dlclose()ing yourself is very bad! Disallow it. */ - LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); + LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG); if (tryall_dlopen (&newhandle, 0) != 0) { - LT_DLFREE (handle); - return 0; + LT_DLFREE (*phandle); + return 1; } + goto register_handle; } - canonical = canonicalize_path (filename); - if (!canonical) + assert (filename && *filename); + + /* Doing this immediately allows internal functions to safely + assume only canonicalized paths are passed. */ + if (canonicalize_path (filename, &canonical) != 0) { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - LT_DLFREE (handle); - return 0; + ++errors; + goto cleanup; } /* If the canonical module name is a path (relative or absolute) then split it into a directory part and a name part. */ - basename = strrchr (canonical, '/'); - if (basename) + base_name = strrchr (canonical, '/'); + if (base_name) { - ++basename; - dir = LT_DLMALLOC (char, basename - canonical + 1); + size_t dirlen = (1+ base_name) - canonical; + + dir = LT_EMALLOC (char, 1+ dirlen); if (!dir) { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - handle = 0; + ++errors; goto cleanup; } - strncpy (dir, canonical, basename - canonical); - dir[basename - canonical] = '\0'; + strncpy (dir, canonical, dirlen); + dir[dirlen] = LT_EOS_CHAR; + + ++base_name; } else - { - basename = canonical; - } + LT_DLMEM_REASSIGN (base_name, canonical); + + assert (base_name && *base_name); /* Check whether we are opening a libtool module (.la extension). */ - ext = strrchr(basename, '.'); - if (ext && strcmp(ext, ".la") == 0) + ext = strrchr (base_name, '.'); + if (ext && strcmp (ext, archive_ext) == 0) { /* this seems to be a libtool module */ - FILE *file = 0; - int i; - char *dlname = 0, *old_name = 0; - char *libdir = 0, *deplibs = 0; - char *line; + FILE * file = 0; + char * dlname = 0; + char * old_name = 0; + char * libdir = 0; + char * deplibs = 0; + char * line = 0; size_t line_len; - int error = 0; /* if we can't find the installed flag, it is probably an installed libtool archive, produced with an old version @@ -2108,403 +3121,644 @@ int installed = 1; /* extract the module name from the file name */ - name = LT_DLMALLOC (char, ext - basename + 1); + name = LT_EMALLOC (char, ext - base_name + 1); if (!name) { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - handle = 0; + ++errors; goto cleanup; - } + } - /* canonicalize the module name */ - for (i = 0; i < ext - basename; ++i) + /* canonicalize the module name */ { - if (isalnum ((int)(basename[i]))) - { - name[i] = basename[i]; - } - else + size_t i; + for (i = 0; i < ext - base_name; ++i) { - name[i] = '_'; + if (isalnum ((int)(base_name[i]))) + { + name[i] = base_name[i]; + } + else + { + name[i] = '_'; + } } + name[ext - base_name] = LT_EOS_CHAR; } - name[ext - basename] = '\0'; + /* 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 + prescribed paths. Otherwise (or in any case if the module was not + yet found) try opening just the module name as passed. */ + if (!dir) + { + const char *search_path; - /* 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 - prescribed paths. Otherwise (or in any case if the module was not - yet found) try opening just the module name as passed. */ - if (!dir) - { - file = (FILE*) find_file(basename, user_search_path, &dir, 0); - if (!file) - { - file = (FILE*) find_file(basename, getenv("LTDL_LIBRARY_PATH"), - &dir, 0); - } + LT_DLMUTEX_LOCK (); + search_path = user_search_path; + if (search_path) + file = find_file (user_search_path, base_name, &dir); + LT_DLMUTEX_UNLOCK (); + + if (!file) + { + search_path = getenv (LTDL_SEARCHPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } #ifdef LTDL_SHLIBPATH_VAR - if (!file) - { - file = (FILE*) find_file(basename, getenv(LTDL_SHLIBPATH_VAR), - &dir, 0); - } + if (!file) + { + search_path = getenv (LTDL_SHLIBPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } #endif #ifdef LTDL_SYSSEARCHPATH - if (!file) - { - file = (FILE*) find_file(basename, sys_search_path, &dir, 0); - } + if (!file && sys_search_path) + { + file = find_file (sys_search_path, base_name, &dir); + } #endif - } - if (!file) - { - file = fopen (filename, LT_READTEXT_MODE); - } - if (!file) - { - MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - } - - if (!file) - { - handle = 0; - goto cleanup; - } + } + if (!file) + { + file = fopen (filename, LT_READTEXT_MODE); + } - line_len = LT_FILENAME_MAX; - line = LT_DLMALLOC (char, line_len); - if (!line) - { - fclose (file); - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - handle = 0; - goto cleanup; - } + /* If we didn't find the file by now, it really isn't there. Set + the status flag, and bail out. */ + if (!file) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + ++errors; + goto cleanup; + } - /* read the .la file */ - while (!feof(file)) - { - if (!fgets (line, line_len, file)) - { - break; - } + line_len = LT_FILENAME_MAX; + line = LT_EMALLOC (char, line_len); + if (!line) + { + fclose (file); + ++errors; + goto cleanup; + } + /* read the .la file */ + while (!feof (file)) + { + if (!fgets (line, (int) line_len, file)) + { + break; + } - /* 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') - { - line = LT_DLREALLOC (char, line, line_len *2); - if (!fgets (&line[line_len -1], line_len +1, file)) - { - break; - } - line_len *= 2; - } + /* Handle the case where we occasionally need to read a line + that is longer than the initial buffer size. */ + while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file))) + { + line = LT_DLREALLOC (char, line, line_len *2); + if (!fgets (&line[line_len -1], (int) line_len +1, file)) + { + break; + } + line_len *= 2; + } - if (line[0] == '\n' || line[0] == '#') - { - continue; - } + if (line[0] == '\n' || line[0] == '#') + { + continue; + } #undef STR_DLNAME #define STR_DLNAME "dlname=" - if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) - { - error = trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); - } + if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) + { + errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); + } #undef STR_OLD_LIBRARY #define STR_OLD_LIBRARY "old_library=" - else if (strncmp (line, STR_OLD_LIBRARY, - sizeof (STR_OLD_LIBRARY) - 1) == 0) - { - error = trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); - } + else if (strncmp (line, STR_OLD_LIBRARY, + sizeof (STR_OLD_LIBRARY) - 1) == 0) + { + errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); + } #undef STR_LIBDIR #define STR_LIBDIR "libdir=" - else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) - { - error = trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); - } + else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) + { + errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); + } #undef STR_DL_DEPLIBS #define STR_DL_DEPLIBS "dependency_libs=" - else if (strncmp (line, STR_DL_DEPLIBS, - sizeof (STR_DL_DEPLIBS) - 1) == 0) - { - error = trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); - } - else if (strcmp (line, "installed=yes\n") == 0) - { - installed = 1; - } - else if (strcmp (line, "installed=no\n") == 0) - { - installed = 0; - } + else if (strncmp (line, STR_DL_DEPLIBS, + sizeof (STR_DL_DEPLIBS) - 1) == 0) + { + errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); + } + else if (strcmp (line, "installed=yes\n") == 0) + { + installed = 1; + } + else if (strcmp (line, "installed=no\n") == 0) + { + installed = 0; + } #undef STR_LIBRARY_NAMES #define STR_LIBRARY_NAMES "library_names=" - else if (! dlname && strncmp (line, STR_LIBRARY_NAMES, - sizeof (STR_LIBRARY_NAMES) - 1) == 0) - { - char *last_libname; - error = trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); - if (! error && dlname && - (last_libname = strrchr (dlname, ' ')) != NULL) - { - last_libname = strdup (last_libname + 1); - LT_DLMEM_REASSIGN (dlname, last_libname); - } - } + else if (! dlname && strncmp (line, STR_LIBRARY_NAMES, + sizeof (STR_LIBRARY_NAMES) - 1) == 0) + { + char *last_libname; + errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); + if (!errors + && dlname + && (last_libname = strrchr (dlname, ' ')) != 0) + { + last_libname = lt_estrdup (last_libname + 1); + if (!last_libname) + { + ++errors; + goto cleanup; + } + LT_DLMEM_REASSIGN (dlname, last_libname); + } + } - if (error) - { + if (errors) break; - } - } + } - fclose (file); - LT_DLFREE (line); + fclose (file); + LT_DLFREE (line); - /* allocate the handle */ - handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1); - if (!handle || error) - { - LT_DLFREE (handle); - if (!error) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - } + /* allocate the handle */ + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + ++errors; - free_vars (dlname, old_name, libdir, deplibs); - /* handle is already set to 0 */ - goto cleanup; - } - memset( handle, 0, sizeof( struct lt_dlhandle_struct ) ); + if (errors) + { + free_vars (dlname, old_name, libdir, deplibs); + LT_DLFREE (*phandle); + goto cleanup; + } - handle->info.ref_count = 0; - if (load_deplibs (handle, deplibs) == 0) - { - newhandle = handle; - /* find_module may replace newhandle */ - if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) - { - unload_deplibs (handle); - error = 1; - } - } - else - { - error = 1; - } + assert (*phandle); - free_vars (dlname, old_name, libdir, deplibs); - if (error) - { - LT_DLFREE (handle); - goto cleanup; - } + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + if (load_deplibs (*phandle, deplibs) == 0) + { + newhandle = *phandle; + /* find_module may replace newhandle */ + if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) + { + unload_deplibs (*phandle); + ++errors; + } + } + else + { + ++errors; + } - if (handle != newhandle) - { - unload_deplibs (handle); - } else { - LT_DLFREE( handle->info.filename ); - handle->info.filename = strdup( filename ); - } + free_vars (dlname, old_name, libdir, deplibs); + if (errors) + { + LT_DLFREE (*phandle); + goto cleanup; + } + + if (*phandle != newhandle) + { + unload_deplibs (*phandle); + } } else { /* not a libtool module */ - handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1); - if (!handle) + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - /* handle is already set to 0 */ + ++errors; goto cleanup; } - memset( handle, 0, sizeof( struct lt_dlhandle_struct ) ); - handle->info.ref_count = 0; - /* non-libtool modules don't have dependencies */ - handle->depcount = 0; - handle->deplibs = 0; - newhandle = handle; + + memset (*phandle, 0, sizeof (struct lt_dlhandle_struct)); + newhandle = *phandle; /* If the module has no directory name component, try to find it first in user_search_path and then other prescribed paths. Otherwise (or in any case if the module was not yet found) try opening just the module name as passed. */ - if ((dir || (!find_file (basename, user_search_path, 0, &newhandle) - && !find_file (basename, getenv ("LTDL_LIBRARY_PATH"), - 0, &newhandle) + if ((dir || (!find_handle (user_search_path, base_name, &newhandle) + && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, + &newhandle) #ifdef LTDL_SHLIBPATH_VAR - && !find_file (basename, getenv (LTDL_SHLIBPATH_VAR), - 0, &newhandle) + && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, + &newhandle) #endif #ifdef LTDL_SYSSEARCHPATH - && !find_file (basename, sys_search_path, 0, &newhandle) + && !find_handle (sys_search_path, base_name, &newhandle) #endif - )) && tryall_dlopen (&newhandle, filename)) + ))) { - LT_DLFREE (handle); + if (tryall_dlopen (&newhandle, filename) != 0) + { + newhandle = NULL; + } + } + + if (!newhandle) + { + LT_DLFREE (*phandle); + ++errors; goto cleanup; } } register_handle: - LT_DLMEM_REASSIGN (handle, newhandle); + LT_DLMEM_REASSIGN (*phandle, newhandle); - if (handle->info.ref_count == 0) + if ((*phandle)->info.ref_count == 0) { - handle->info.ref_count = 1; - handle->info.name = name; - handle->next = handles; + (*phandle)->info.ref_count = 1; + LT_DLMEM_REASSIGN ((*phandle)->info.name, name); - MUTEX_LOCK (); - handles = handle; - MUTEX_UNLOCK (); - - name = 0; /* don't free this during `cleanup' */ + LT_DLMUTEX_LOCK (); + (*phandle)->next = handles; + handles = *phandle; + LT_DLMUTEX_UNLOCK (); } - MUTEX_SETERROR (saved_error); + LT_DLMUTEX_SETERROR (saved_error); cleanup: LT_DLFREE (dir); LT_DLFREE (name); LT_DLFREE (canonical); + return errors; +} + +lt_dlhandle +lt_dlopen (filename) + const char *filename; +{ + lt_dlhandle handle = 0; + + /* Just incase we missed a code path in try_dlopen() that reports + an error, but forgets to reset handle... */ + if (try_dlopen (&handle, filename) != 0) + return 0; + return handle; } +/* If the last error messge store was `FILE_NOT_FOUND', then return + non-zero. */ +static int +file_not_found () +{ + const char *error = 0; + + LT_DLMUTEX_GETERROR (error); + if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) + return 1; + + return 0; +} + +/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, + and if a file is still not found try again with SHLIB_EXT appended + instead. */ lt_dlhandle lt_dlopenext (filename) const char *filename; { - lt_dlhandle handle; - char *tmp; - int len; - const char *saved_error; - - MUTEX_GETERROR (saved_error); + lt_dlhandle handle = 0; + char * tmp = 0; + char * ext = 0; + size_t len; + int errors = 0; if (!filename) { return lt_dlopen (filename); } - len = strlen (filename); - if (!len) - { - MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - return 0; - } - - tmp = LT_DLMALLOC (char, len+4); - if (!tmp) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return 0; - } - strcpy (tmp, filename); + assert (filename); -#ifdef _AIX - tmp[len] = '\0'; + len = LT_STRLEN (filename); + ext = strrchr (filename, '.'); - /* find by info.name in the list */ - handle = sys_dl_search_by_name( tmp ); - if (handle) + /* If FILENAME already bears a suitable extension, there is no need + to try appending additional extensions. */ + if (ext && ((strcmp (ext, archive_ext) == 0) +#ifdef LTDL_SHLIB_EXT + || (strcmp (ext, shlib_ext) == 0) +#endif + )) { - if( LT_DLGET_FLAG (handle, LT_DLNOTFOUND_FLAG) ) - { - /* don't search libm and libstdc++ over and over again, - * they are hardlinked and symbols are exported by the - * executable */ - MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - LT_DLFREE (tmp); - return 0; - } - MUTEX_SETERROR (saved_error); - LT_DLFREE (tmp); - return handle; + return lt_dlopen (filename); } -#endif /* _AIX */ - /* try "filename.la" */ - strcat (tmp, ".la"); - handle = lt_dlopen (tmp); - if (handle) - { - MUTEX_SETERROR (saved_error); - LT_DLFREE (tmp); - return handle; - } + /* First try appending ARCHIVE_EXT. */ + tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1); + if (!tmp) + return 0; + strcpy (tmp, filename); + strcat (tmp, archive_ext); + errors = try_dlopen (&handle, tmp); -#ifdef _AIX - tmp[len] = '\0'; /* delete the ".la" again. */ - - /* versioned shared objects can be in .a's */ - strcat(tmp, ".a"); - handle = lt_dlopen (tmp); - if (handle) + /* If we found FILENAME, stop searching -- whether we were able to + load the file as a module or not. If the file exists but loading + failed, it is better to return an error message here than to + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not + in the module search path. */ + if (handle || ((errors > 0) && !file_not_found ())) { - MUTEX_SETERROR (saved_error); LT_DLFREE (tmp); return handle; } -#endif /* _AIX */ #ifdef LTDL_SHLIB_EXT - /* try "filename.EXT" */ - if (strlen(shlib_ext) > 3) + /* Try appending SHLIB_EXT. */ + if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext)) { LT_DLFREE (tmp); - tmp = LT_DLMALLOC (char, len + strlen (shlib_ext) + 1); + tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); if (!tmp) - { - MUTEX_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); - handle = lt_dlopen (tmp); - if (handle) + errors = try_dlopen (&handle, tmp); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && !file_not_found ())) { - MUTEX_SETERROR (saved_error); LT_DLFREE (tmp); return handle; } #endif - /* try the normal file name */ - handle = lt_dlopen (filename); - if (handle) + /* Still here? Then we really did fail to locate any of the file + names we tried. */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + LT_DLFREE (tmp); + return 0; +} + + +static int +lt_argz_insert (pargz, pargz_len, before, entry) + char **pargz; + size_t *pargz_len; + char *before; + const char *entry; +{ + error_t error; + + if ((error = argz_insert (pargz, pargz_len, before, entry))) { - return handle; + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + return 1; } -#ifdef _AIX - /* put into the can't be found list */ - tmp[len] = '\0'; - sys_dl_not_found_entry( tmp ); -#endif /* _AIX */ - - MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - LT_DLFREE (tmp); return 0; } +static int +lt_argz_insertinorder (pargz, pargz_len, entry) + char **pargz; + size_t *pargz_len; + const char *entry; +{ + char *before = 0; + + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + if (*pargz) + while ((before = argz_next (*pargz, *pargz_len, before))) + { + int cmp = strcmp (entry, before); + + if (cmp < 0) break; + if (cmp == 0) return 0; /* No duplicates! */ + } + + return lt_argz_insert (pargz, pargz_len, before, entry); +} + +static 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); + + 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; + + if (*p == '.') + end = p; + } + + /* 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_EMALLOC (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_insertinorder (pargz, pargz_len, buf) != 0) + ++errors; + + LT_DLFREE (buf); + + return errors; +} + +static int +list_files_by_dir (dirnam, pargz, pargz_len) + const char *dirnam; + char **pargz; + size_t *pargz_len; +{ + DIR *dirp = 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 (pargz, pargz_len, dirnam, dp)) + { + ++errors; + break; + } + + closedir (dirp); + } + else + ++errors; + + 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 = 0; + size_t argz_len = 0; + + if (list_files_by_dir (dirname, &argz, &argz_len) != 0) + goto cleanup; + if (!argz) + goto cleanup; + + { + char *filename = 0; + while ((filename = argz_next (argz, argz_len, filename))) + if ((is_done = (*func) (filename, data2))) + break; + } + + cleanup: + LT_DLFREE (argz); + + 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; + int (*func) LT_PARAMS ((const char *filename, lt_ptr data)); + lt_ptr data; +{ + int is_done = 0; + + if (search_path) + { + /* If a specific path was passed, search only the directories + listed in it. */ + is_done = foreach_dirinpath (search_path, 0, + foreachfile_callback, func, data); + } + else + { + /* Otherwise search the default paths. */ + is_done = foreach_dirinpath (user_search_path, 0, + foreachfile_callback, func, data); + if (!is_done) + { + is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0, + foreachfile_callback, func, data); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0, + foreachfile_callback, func, data); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0, + foreachfile_callback, func, data); + } +#endif + } + + return is_done; +} + int lt_dlclose (handle) lt_dlhandle handle; @@ -2512,7 +3766,7 @@ lt_dlhandle cur, last; int errors = 0; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); /* check whether the handle is valid */ last = cur = handles; @@ -2524,7 +3778,7 @@ if (!cur) { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); ++errors; goto done; } @@ -2551,6 +3805,9 @@ errors += handle->loader->module_close (data, handle->module); errors += unload_deplibs(handle); + /* It is up to the callers to free the data itself. */ + LT_DLFREE (handle->caller_data); + LT_DLFREE (handle->info.filename); LT_DLFREE (handle->info.name); LT_DLFREE (handle); @@ -2560,12 +3817,12 @@ if (LT_DLIS_RESIDENT (handle)) { - MUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE)); ++errors; } done: - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return errors; } @@ -2575,7 +3832,7 @@ lt_dlhandle handle; const char *symbol; { - int lensym; + size_t lensym; char lsym[LT_SYMBOL_LENGTH]; char *sym; lt_ptr address; @@ -2583,26 +3840,18 @@ if (!handle) { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); return 0; } if (!symbol) { - MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); return 0; } - lensym = strlen(symbol); - if (handle->loader->sym_prefix) - { - lensym += strlen(handle->loader->sym_prefix); - } - - if (handle->info.name) - { - lensym += strlen(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) { @@ -2610,13 +3859,12 @@ } else { - sym = LT_DLMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); - } - - if (!sym) - { - MUTEX_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; @@ -2624,7 +3872,7 @@ { const char *saved_error; - MUTEX_GETERROR (saved_error); + LT_DLMUTEX_GETERROR (saved_error); /* this is a libtool module */ if (handle->loader->sym_prefix) @@ -2650,7 +3898,7 @@ } return address; } - MUTEX_SETERROR (saved_error); + LT_DLMUTEX_SETERROR (saved_error); } /* otherwise try "symbol" */ @@ -2678,10 +3926,82 @@ { const char *error; - MUTEX_GETERROR (error); - MUTEX_SETERROR (0); + LT_DLMUTEX_GETERROR (error); + LT_DLMUTEX_SETERROR (0); - return error; + return error ? error : NULL; +} + +static int +lt_dlpath_insertdir (ppath, before, dir) + char **ppath; + char *before; + const char *dir; +{ + int errors = 0; + char *canonical = 0; + char *argz = 0; + size_t argz_len = 0; + + assert (ppath); + assert (dir && *dir); + + if (canonicalize_path (dir, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + assert (canonical && *canonical); + + /* If *PPATH is empty, set it to DIR. */ + if (*ppath == 0) + { + assert (!before); /* BEFORE cannot be set without PPATH. */ + assert (dir); /* Without DIR, don't call this function! */ + + *ppath = lt_estrdup (dir); + if (*ppath == 0) + ++errors; + + return errors; + } + + assert (ppath && *ppath); + + if (argzize_path (*ppath, &argz, &argz_len) != 0) + { + ++errors; + goto cleanup; + } + + /* Convert BEFORE into an equivalent offset into ARGZ. This only works + if *PPATH is already canonicalized, and hence does not change length + with respect to ARGZ. We canonicalize each entry as it is added to + the search path, and don't call this function with (uncanonicalized) + user paths, so this is a fair assumption. */ + if (before) + { + assert (*ppath <= before); + assert (before - *ppath <= strlen (*ppath)); + + before = before - *ppath + argz; + } + + if (lt_argz_insert (&argz, &argz_len, before, dir) != 0) + { + ++errors; + goto cleanup; + } + + argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); + LT_DLMEM_REASSIGN (*ppath, argz); + + cleanup: + LT_DLFREE (canonical); + LT_DLFREE (argz); + + return errors; } int @@ -2690,40 +4010,47 @@ { int errors = 0; - if (!search_dir || !strlen(search_dir)) + if (search_dir && *search_dir) { - return errors; + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); } - MUTEX_LOCK (); - if (!user_search_path) + return errors; +} + +int +lt_dlinsertsearchdir (before, search_dir) + const char *before; + const char *search_dir; +{ + int errors = 0; + + if (before) { - user_search_path = strdup (search_dir); - if (!user_search_path) + LT_DLMUTEX_LOCK (); + if ((before < user_search_path) + || (before >= user_search_path + LT_STRLEN (user_search_path))) { - last_error = LT_DLSTRERROR (NO_MEMORY); - ++errors; + LT_DLMUTEX_UNLOCK (); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION)); + return 1; } + LT_DLMUTEX_UNLOCK (); } - else - { - size_t len = strlen (user_search_path) + 1 + strlen (search_dir); - char *new_search_path = LT_DLMALLOC (char, 1+ len); - if (!new_search_path) + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, + (char *) before, search_dir) != 0) { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); ++errors; } - else - { - sprintf (new_search_path, "%s%c%s", user_search_path, - LT_PATHSEP_CHAR, search_dir); - - LT_DLMEM_REASSIGN (user_search_path, new_search_path); - } + LT_DLMUTEX_UNLOCK (); } - MUTEX_UNLOCK (); return errors; } @@ -2732,24 +4059,21 @@ lt_dlsetsearchpath (search_path) const char *search_path; { - int errors = 0; + int errors = 0; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); LT_DLFREE (user_search_path); - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); - if (!search_path || !strlen (search_path)) + if (!search_path || !LT_STRLEN (search_path)) { return errors; } - MUTEX_LOCK (); - user_search_path = strdup (search_path); - if (!user_search_path) - { - ++errors; - } - MUTEX_UNLOCK (); + LT_DLMUTEX_LOCK (); + if (canonicalize_path (search_path, &user_search_path) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); return errors; } @@ -2759,9 +4083,9 @@ { const char *saved_path; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); saved_path = user_search_path; - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return saved_path; } @@ -2774,7 +4098,7 @@ if (!handle) { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); ++errors; } else @@ -2791,7 +4115,7 @@ { if (!handle) { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); return -1; } @@ -2809,7 +4133,7 @@ { if (!handle) { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); return 0; } @@ -2820,7 +4144,7 @@ lt_dlhandle_next (place) lt_dlhandle place; { - return place ? place->next : (lt_dlhandle) 0; + return place ? place->next : handles; } int @@ -2831,7 +4155,7 @@ int errors = 0; lt_dlhandle cur; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); cur = handles; while (cur) @@ -2846,7 +4170,7 @@ } } - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return errors; } @@ -2854,18 +4178,16 @@ lt_dlcaller_id lt_dlcaller_register () { - static int last_caller_id = -1; + static lt_dlcaller_id last_caller_id = 0; int result; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); result = ++last_caller_id; - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return result; } -#define N_ELEMENTS(a) (sizeof(a) / sizeof(*(a))) - lt_ptr lt_dlcaller_set_data (key, handle, data) lt_dlcaller_id key; @@ -2878,10 +4200,11 @@ /* This needs to be locked so that the caller data can be updated simultaneously by different threads. */ - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); if (handle->caller_data) - n_elements = N_ELEMENTS (handle->caller_data); + while (handle->caller_data[n_elements].key) + ++n_elements; for (i = 0; i < n_elements; ++i) { @@ -2893,31 +4216,29 @@ } /* Ensure that there is enough room in this handle's caller_data - array to accept a new element. */ + array to accept a new element (and an empty end marker). */ if (i == n_elements) { lt_caller_data *temp - = LT_DLREALLOC (lt_caller_data, handle->caller_data, 1+ n_elements); + = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements); - if (temp == 0) + if (!temp) { - MUTEX_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; + handle->caller_data[1+ i].key = 0; } handle->caller_data[i].data = data; done: - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return stale; } @@ -2928,19 +4249,15 @@ lt_dlhandle handle; { lt_ptr result = (lt_ptr) 0; - int n_elements = 0; /* This needs to be locked so that the caller data isn't updated by another thread part way through this function. */ - MUTEX_LOCK (); - - if (handle->caller_data) - n_elements = N_ELEMENTS (handle->caller_data); + LT_DLMUTEX_LOCK (); /* Locate the index of the element with a matching KEY. */ { int i; - for (i = 0; i < n_elements; ++i) + for (i = 0; handle->caller_data[i].key; ++i) { if (handle->caller_data[i].key == key) { @@ -2950,7 +4267,7 @@ } } - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return result; } @@ -2974,17 +4291,14 @@ || (dlloader->module_close == 0) || (dlloader->find_sym == 0)) { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); return 1; } /* Create a new dlloader node with copies of the user callbacks. */ - node = LT_DLMALLOC (lt_dlloader, 1); - if (node == 0) - { - MUTEX_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; @@ -2995,7 +4309,7 @@ node->find_sym = dlloader->find_sym; node->dlloader_data = dlloader->dlloader_data; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); if (!loaders) { /* If there are no loaders, NODE becomes the list! */ @@ -3028,7 +4342,7 @@ if (ptr->next != place) { - last_error = LT_DLSTRERROR (INVALID_LOADER); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); ++errors; } else @@ -3039,7 +4353,7 @@ } } - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return errors; } @@ -3054,18 +4368,18 @@ if (!place) { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); return 1; } - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); /* Fail if there are any open modules which use this loader. */ for (handle = handles; handle; handle = handle->next) { if (handle->loader == place) { - MUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER)); ++errors; goto done; } @@ -3100,7 +4414,7 @@ LT_DLFREE (place); done: - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return errors; } @@ -3111,9 +4425,9 @@ { lt_dlloader *next; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); next = place ? place->next : loaders; - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return next; } @@ -3126,13 +4440,13 @@ if (place) { - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); name = place ? place->loader_name : 0; - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); } else { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); } return name; @@ -3146,13 +4460,13 @@ if (place) { - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); data = place ? &(place->dlloader_data) : 0; - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); } else { - MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); } return data; @@ -3164,7 +4478,7 @@ { lt_dlloader *place = 0; - MUTEX_LOCK (); + LT_DLMUTEX_LOCK (); for (place = loaders; place; place = place->next) { if (strcmp (place->loader_name, loader_name) == 0) @@ -3172,236 +4486,7 @@ break; } } - MUTEX_UNLOCK (); + LT_DLMUTEX_UNLOCK (); return place; } - -#ifdef _AIX - -/* #define DBG_PRNT(a) fprintf a ; */ -#define DBG_PRNT(a) - -static void -sys_dl_debug_print_loaded( const char* filename ) -{ - int ret; - static unsigned char buffer[1024*1024]; - struct ld_info* info; - - ret = loadquery( L_GETINFO, buffer, 1024*1024 ); - if( ret >= 0 ) - { - DBG_PRNT((stderr, "%d: Successfully loaded %s\n", - __LINE__, filename )) - info = (struct ld_info*)buffer; - do - { - const char* c; - const char* d; - c = info->ldinfo_filename; - d = &c[strlen(c)]; - d++; - DBG_PRNT((stderr, "%d: path name %s, member name %s\n", - __LINE__, - c,d)) - info = (struct ld_info*)(((char*)info)+info->ldinfo_next); - } - while( info->ldinfo_next != 0 ); - } - else if( errno == ENOMEM ) - { - DBG_PRNT((stderr, "%d: Successfully loaded %s, loadquery needs larger buffer\n", - __LINE__, filename )) - } - else - { - DBG_PRNT((stderr, "Loadquery failure\n")) - } -} - -static void -sys_dl_debug_print_handle( lt_dlhandle handle ) -{ - DBG_PRNT((stderr," > next = %ld\n", (long)handle->next )) - DBG_PRNT((stderr," > loader = %ld\n", (long)handle->loader )) - DBG_PRNT((stderr," > info.filename = %s\n", handle->info.filename )) - DBG_PRNT((stderr," > info.name = %s\n", handle->info.name )) - DBG_PRNT((stderr," > info.ref_count= %d\n", handle->info.ref_count )) - DBG_PRNT((stderr," > depcount = %d\n", handle->depcount )) - DBG_PRNT((stderr," > resident flags %s\n", - (LT_DLGET_FLAG (handle, LT_DLRESIDENT_FLAG)?"yes":"no"))) - DBG_PRNT((stderr," > not found flags %s\n", - (LT_DLGET_FLAG (handle, LT_DLNOTFOUND_FLAG)?"yes":"no"))) -} - -static void -sys_dl_init( ) -{ - char* buffer = NULL; - size_t buf_size = 512; - int ret; - const char* libname; - const char* modname; - struct ld_info* info; - lt_dlhandle cur; - lt_dlhandle handle; - int already_listed; - const char* last_slash; - const char* last_dot; - - do - { - buf_size *= 2; - if( buffer != NULL ) LT_DLFREE( buffer ); - buffer = LT_DLMALLOC( char, buf_size ); - ret = loadquery( L_GETINFO, buffer, buf_size ); - } - while( ret==-1 && errno==ENOMEM ); - - if( ret >= 0 ) - { - info = (struct ld_info*)buffer; - do - { - libname = info->ldinfo_filename; - modname = &libname[strlen(libname)]; - modname += 1; - already_listed = 0; - - cur = handles; - while (cur) - { - if( cur->info.filename && - !strcmp( cur->info.filename, libname ) ) - { - already_listed = 1; - break; - } - cur = cur->next; - } - - if( already_listed == 0 ) - { - handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1); - if (!handle) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - LT_DLFREE( buffer ); - return; - } - memset( handle, 0, sizeof( struct lt_dlhandle_struct ) ); - - last_slash = strrchr( libname, '/' ); - if( last_slash == NULL ) - { - last_slash = libname; - } - else - { - last_slash++; - } - last_dot = strrchr( last_slash, '.' ); - if( last_dot == NULL ) - { - last_dot = &last_slash[strlen(last_slash)]; - } - - handle->info.name = LT_DLMALLOC( char, last_dot-last_slash+1 ); - strncpy( handle->info.name, last_slash, last_dot-last_slash ); - handle->info.name[last_dot-last_slash] = '\0'; - - handle->loader = lt_dlloader_find ("dlopen"); - handle->info.filename = strdup( libname ); - handle->info.ref_count = 1; - handle->depcount = 0; - handle->deplibs = 0; - handle->module = dlopen( libname, lt_dlopen_flag ); - handle->system = 0; - handle->caller_data = 0; - LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); - - MUTEX_LOCK (); - handle->next = handles; - handles = handle; - MUTEX_UNLOCK (); - } - - info = (struct ld_info*)(((char*)info)+info->ldinfo_next); - } - while( info->ldinfo_next != 0 ); - } - - if( buffer != NULL ) LT_DLFREE( buffer ); -} - -static lt_dlhandle -sys_dl_search_by_name( const char* name ) -{ - lt_dlhandle cur; - const char* la; - int inlen; - - cur = handles; - - while (cur) - { - if( cur->info.name && name ) - { - if( !strcmp( cur->info.name, name ) ) - { - if( cur->info.filename ) - { - la = strrchr( cur->info.filename, '.' ); - if( !la || strcmp(la,".la") ) - { - return cur; - } - } - } - } - if( cur->info.filename && name ) - { - if( !strcmp( cur->info.filename, name ) ) - { - return cur; - } - } - cur = cur->next; - } - return NULL; -} - -static void -sys_dl_not_found_entry( const char* tmp ) -{ - lt_dlhandle handle; - - handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1); - if (!handle) - { - MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return; - } - memset( handle, 0, sizeof( struct lt_dlhandle_struct ) ); - - handle->loader = NULL; - - handle->info.filename = strdup( tmp ); - handle->info.name = strdup( tmp ); - handle->info.ref_count = 0; - handle->depcount = 0; - handle->deplibs = 0; - handle->module = 0; - handle->system = 0; - handle->caller_data = 0; - - LT_DLSET_FLAG (handle, LT_DLNOTFOUND_FLAG); - - MUTEX_LOCK (); - handle->next = handles; - handles = handle; - MUTEX_UNLOCK (); -} - -#endif /* _AIX */ diff -uNr arts-1.3.2/libltdl/ltdl.h arts-1.3.2-new/libltdl/ltdl.h --- arts-1.3.2/libltdl/ltdl.h Thu Apr 5 23:56:42 2001 +++ arts-1.3.2-new/libltdl/ltdl.h Wed Dec 15 13:41:49 2004 @@ -34,6 +34,9 @@ /* --- 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. */ @@ -76,12 +79,14 @@ /* LT_CONC creates a new concatenated symbol for the compiler in a portable way. */ -#if defined(__STDC__) || defined(__cplusplus) +#if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER) # define LT_CONC(s,t) s##t #else # 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) @@ -106,6 +111,7 @@ # endif #endif + #ifdef __WINDOWS__ # ifndef __CYGWIN__ /* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory @@ -135,6 +141,10 @@ #endif +#if defined(_MSC_VER) /* Visual Studio */ +# define R_OK 4 +#endif + /* --- DYNAMIC MODULE LOADING API --- */ @@ -143,25 +153,31 @@ typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module. */ /* Initialisation and finalisation functions for libltdl. */ -extern int lt_dlinit LT_PARAMS((void)); -extern int lt_dlexit LT_PARAMS((void)); +LT_SCOPE int lt_dlinit LT_PARAMS((void)); +LT_SCOPE int lt_dlexit LT_PARAMS((void)); -/* Module search path manipultation. */ -extern int lt_dladdsearchdir LT_PARAMS((const char *search_dir)); -extern int lt_dlsetsearchpath LT_PARAMS((const char *search_path)); -extern const char *lt_dlgetsearchpath LT_PARAMS((void)); +/* Module search path manipulation. */ +LT_SCOPE int lt_dladdsearchdir LT_PARAMS((const char *search_dir)); +LT_SCOPE int lt_dlinsertsearchdir LT_PARAMS((const char *before, + const char *search_dir)); +LT_SCOPE int lt_dlsetsearchpath LT_PARAMS((const char *search_path)); +LT_SCOPE const char *lt_dlgetsearchpath LT_PARAMS((void)); +LT_SCOPE int lt_dlforeachfile LT_PARAMS(( + const char *search_path, + int (*func) (const char *filename, lt_ptr data), + lt_ptr data)); /* Portable libltdl versions of the system dlopen() API. */ -extern lt_dlhandle lt_dlopen LT_PARAMS((const char *filename)); -extern lt_dlhandle lt_dlopenext LT_PARAMS((const char *filename)); -extern lt_ptr lt_dlsym LT_PARAMS((lt_dlhandle handle, +LT_SCOPE lt_dlhandle lt_dlopen LT_PARAMS((const char *filename)); +LT_SCOPE lt_dlhandle lt_dlopenext LT_PARAMS((const char *filename)); +LT_SCOPE lt_ptr lt_dlsym LT_PARAMS((lt_dlhandle handle, const char *name)); -extern const char *lt_dlerror LT_PARAMS((void)); -extern int lt_dlclose LT_PARAMS((lt_dlhandle handle)); +LT_SCOPE const char *lt_dlerror LT_PARAMS((void)); +LT_SCOPE int lt_dlclose LT_PARAMS((lt_dlhandle handle)); /* Module residency management. */ -extern int lt_dlmakeresident LT_PARAMS((lt_dlhandle handle)); -extern int lt_dlisresident LT_PARAMS((lt_dlhandle handle)); +LT_SCOPE int lt_dlmakeresident LT_PARAMS((lt_dlhandle handle)); +LT_SCOPE int lt_dlisresident LT_PARAMS((lt_dlhandle handle)); @@ -171,10 +187,10 @@ typedef void lt_dlmutex_lock LT_PARAMS((void)); typedef void lt_dlmutex_unlock LT_PARAMS((void)); -typedef void lt_dlmutex_seterror LT_PARAMS((const char *error)); +typedef void lt_dlmutex_seterror LT_PARAMS((const char *errmsg)); typedef const char *lt_dlmutex_geterror LT_PARAMS((void)); -extern int lt_dlmutex_register LT_PARAMS((lt_dlmutex_lock *lock, +LT_SCOPE int lt_dlmutex_register LT_PARAMS((lt_dlmutex_lock *lock, lt_dlmutex_unlock *unlock, lt_dlmutex_seterror *seterror, lt_dlmutex_geterror *geterror)); @@ -185,8 +201,13 @@ /* --- 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)); @@ -202,8 +223,8 @@ lt_ptr address; } lt_dlsymlist; -extern int lt_dlpreload LT_PARAMS((const lt_dlsymlist *preloaded)); -extern int lt_dlpreload_default +LT_SCOPE int lt_dlpreload LT_PARAMS((const lt_dlsymlist *preloaded)); +LT_SCOPE int lt_dlpreload_default LT_PARAMS((const lt_dlsymlist *preloaded)); #define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \ @@ -225,20 +246,20 @@ number of times lt_dlclosed. */ } lt_dlinfo; -extern const lt_dlinfo *lt_dlgetinfo LT_PARAMS((lt_dlhandle handle)); -extern lt_dlhandle lt_dlhandle_next LT_PARAMS((lt_dlhandle place)); -extern int lt_dlforeach LT_PARAMS(( +LT_SCOPE const lt_dlinfo *lt_dlgetinfo LT_PARAMS((lt_dlhandle handle)); +LT_SCOPE lt_dlhandle lt_dlhandle_next LT_PARAMS((lt_dlhandle place)); +LT_SCOPE int lt_dlforeach LT_PARAMS(( int (*func) (lt_dlhandle handle, lt_ptr data), lt_ptr data)); /* Associating user data with loaded modules. */ typedef unsigned lt_dlcaller_id; -extern lt_dlcaller_id lt_dlcaller_register LT_PARAMS((void)); -extern lt_ptr lt_dlcaller_set_data LT_PARAMS((lt_dlcaller_id key, +LT_SCOPE lt_dlcaller_id lt_dlcaller_register LT_PARAMS((void)); +LT_SCOPE lt_ptr lt_dlcaller_set_data LT_PARAMS((lt_dlcaller_id key, lt_dlhandle handle, lt_ptr data)); -extern lt_ptr lt_dlcaller_get_data LT_PARAMS((lt_dlcaller_id key, +LT_SCOPE lt_ptr lt_dlcaller_get_data LT_PARAMS((lt_dlcaller_id key, lt_dlhandle handle)); @@ -269,15 +290,15 @@ lt_user_data dlloader_data; }; -extern lt_dlloader *lt_dlloader_next LT_PARAMS((lt_dlloader *place)); -extern lt_dlloader *lt_dlloader_find LT_PARAMS(( - const char *loader_name)); -extern const char *lt_dlloader_name LT_PARAMS((lt_dlloader *place)); -extern lt_user_data *lt_dlloader_data LT_PARAMS((lt_dlloader *place)); -extern int lt_dlloader_add LT_PARAMS((lt_dlloader *place, - const struct lt_user_dlloader *dlloader, +LT_SCOPE lt_dlloader *lt_dlloader_next LT_PARAMS((lt_dlloader *place)); +LT_SCOPE lt_dlloader *lt_dlloader_find LT_PARAMS(( const char *loader_name)); -extern int lt_dlloader_remove LT_PARAMS(( +LT_SCOPE const char *lt_dlloader_name LT_PARAMS((lt_dlloader *place)); +LT_SCOPE lt_user_data *lt_dlloader_data LT_PARAMS((lt_dlloader *place)); +LT_SCOPE int lt_dlloader_add LT_PARAMS((lt_dlloader *place, + const struct lt_user_dlloader *dlloader, + const char *loader_name)); +LT_SCOPE int lt_dlloader_remove LT_PARAMS(( const char *loader_name)); @@ -307,7 +328,8 @@ LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \ LT_ERROR(SHUTDOWN, "library already shutdown") \ LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \ - LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") + LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") \ + LT_ERROR(INVALID_POSITION, "invalid search path insert position") /* Enumerate the symbolic error names. */ enum { @@ -319,15 +341,12 @@ }; /* These functions are only useful from inside custom module loaders. */ -extern int lt_dladderror LT_PARAMS((const char *diagnostic)); -extern int lt_dlseterror LT_PARAMS((int errorcode)); +LT_SCOPE int lt_dladderror LT_PARAMS((const char *diagnostic)); +LT_SCOPE int lt_dlseterror LT_PARAMS((int errorcode)); -/* For KDE and for now, we want this source compatibility until I get rid - of the exportation of ltdl.h alltogether. (matz@kde.org) */ -#define LT_NON_POSIX_NAMESPACE /* --- SOURCE COMPATIBILITY WITH OLD LIBLTDL --- */ diff -uNr arts-1.3.2/mcop/tcpserver.cc arts-1.3.2-new/mcop/tcpserver.cc --- arts-1.3.2/mcop/tcpserver.cc Fri Nov 29 11:51:13 2002 +++ arts-1.3.2-new/mcop/tcpserver.cc Wed Dec 15 13:41:49 2004 @@ -129,7 +129,7 @@ return false; } - socklen_t sz = sizeof(struct sockaddr_in); + kde_socklen_t sz = sizeof(struct sockaddr_in); int r = getsockname (theSocket,(struct sockaddr *)&socket_addr, &sz); if(r == 0) { thePort = ntohs(socket_addr.sin_port); @@ -170,7 +170,7 @@ { int clientfd; struct sockaddr_in incoming; - socklen_t size_in = sizeof(struct sockaddr_in); + kde_socklen_t size_in = sizeof(struct sockaddr_in); clientfd = accept(theSocket, (struct sockaddr*) &incoming, &size_in ); if(clientfd > 0) diff -uNr arts-1.3.2/mcop/unixserver.cc arts-1.3.2-new/mcop/unixserver.cc --- arts-1.3.2/mcop/unixserver.cc Fri Mar 8 15:30:20 2002 +++ arts-1.3.2-new/mcop/unixserver.cc Wed Dec 15 13:41:49 2004 @@ -130,7 +130,7 @@ { int clientfd; struct sockaddr_un incoming; - socklen_t size_in = sizeof(struct sockaddr_un); + kde_socklen_t size_in = sizeof(struct sockaddr_un); clientfd = accept(theSocket, (struct sockaddr*) &incoming, &size_in ); if(clientfd > 0) diff -uNr arts-1.3.2/mcop_mt/Makefile.in arts-1.3.2-new/mcop_mt/Makefile.in --- arts-1.3.2/mcop_mt/Makefile.in Mon Nov 29 10:03:05 2004 +++ arts-1.3.2-new/mcop_mt/Makefile.in Wed Dec 15 13:41:49 2004 @@ -349,7 +349,7 @@ #>- libmcop_mt_la_LDFLAGS = -no-undefined -version-info 1:0 $(USE_THREADS) #>+ 1 -libmcop_mt_la_LDFLAGS = -no-undefined $(KDE_NO_UNDEFINED) -version-info 1:0 $(USE_THREADS) +libmcop_mt_la_LDFLAGS = -no-undefined $(KDE_NO_UNDEFINED) -version-info 1:0 $(all_libraries) $(USE_THREADS) #>- all: all-am #>+ 1 all: docs-am all-am diff -uNr arts-1.3.2/x11/Makefile.in arts-1.3.2-new/x11/Makefile.in --- arts-1.3.2/x11/Makefile.in Mon Nov 29 10:03:05 2004 +++ arts-1.3.2-new/x11/Makefile.in Wed Dec 15 13:41:49 2004 @@ -355,7 +355,7 @@ libx11globalcomm_la_LIBADD = $(top_builddir)/mcop/libmcop.la $(LIB_X11) #>- libx11globalcomm_la_LDFLAGS = -no-undefined -module -version-info 1:0 $(X_LDFLAGS) $(all_libraries) #>+ 1 -libx11globalcomm_la_LDFLAGS = -no-undefined $(KDE_NO_UNDEFINED) -module -version-info 1:0 $(X_LDFLAGS) $(all_libraries) +libx11globalcomm_la_LDFLAGS = -no-undefined $(KDE_NO_UNDEFINED) -module -version-info 1:0 $(all_libraries) $(X_LDFLAGS) DISTCLEANFILES = x11globalcomm.cc x11globalcomm.h \ x11globalcomm.mcoptype x11globalcomm.mcopclass