diff --git a/ChangeLog b/ChangeLog index 597a06f8..5b1c5782 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,13 +1,30 @@ +2001-08-13 Gary V. Vaughan + + * libltdl/ltdl.c (rpl_argz_stringify): New fallback implementation. + * ltdl.m4 (AC_LTDL_FUNC_ARGZ): Test for argz_stringify in libc. + * libltdl/ltdl.c (lt_argz_insertinorder): Renamed from + lt_argz_insert to make room for... + (lt_argz_insert): Wraps argz_insert with libltdl error handling. + (lt_dlpath_insertdir): Insert new path elements into an + argzized path. + (lt_dlinsertsearchdir): New function to insert new search + directories anywhere into user_search_path using the above. + (lt_dladdsearchdir): Rewritten to use lt_dlpath_insertdir. + * libltdl/ltdl.h (lt_dlinsertsearchdir): Prototype for export. + * doc/libtool.texi (Libltdl interface): Document it. + * NEWS: Updated, + 2001-08-07 Gary V. Vaughan - ltmain.in [irix*]: $with_gcc is either "yes" or "" (empty string) + From Albert Chin : + * ltmain.in [irix*]: $with_gcc is either "yes" or "" (empty string) with current autoconf, so we need to be robust to that when testing it, 2001-08-06 Gary V. Vaughan From Brad : - libtool.m4 (deplibs_check_method) [aix*]: Removed redundant setting + * libtool.m4 (deplibs_check_method) [aix*]: Removed redundant setting of this variable. 2001-08-05 Gary V. Vaughan diff --git a/NEWS b/NEWS index 01c0f46b..778d7947 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ NEWS - list of user-visible changes between releases of GNU Libtool New in 1.4d: 2001-??-??; CVS version 1.4c, Libtool team: * Help strings display correctly again. * Better error messages when library linking fails. +* Better search path management in libltdl with `lt_dlinsertsearchdir' call. * Support /lib/w32api in recent cygwin releases. * Support cross compilation to mingw. * Improved support for linking with gcc on aix4* and aix5*. diff --git a/doc/libtool.texi b/doc/libtool.texi index 0ac9c65f..3973564f 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -2735,8 +2735,9 @@ following search paths for the module (in the order as follows): @enumerate 1 @item user-defined search path: -This search path can be set by the program using the -functions @code{lt_dlsetsearchpath} and @code{lt_dladdsearchdir}. +This search path can be changed by the program using the +functions @code{lt_dlsetsearchpath}, @code{lt_dladdsearchdir} and +@code{lt_dlinsertsearchdir}. @item libltdl's search path: This search path is the value of the environment variable @@ -2827,8 +2828,15 @@ int main() @{ @end defmac @deftypefun int lt_dladdsearchdir (const char *@var{search_dir}) -Add the search directory @var{search_dir} to the user-defined library -search path. Return 0 on success. +Append the search directory @var{search_dir} to the current user-defined +library search path. Return 0 on success. +@end deftypefun + +@deftypefun int lt_dlinsertsearchdir (@w{const char *@var{before}}, @w{const char *@var{search_dir}}) +Insert the search directory @var{search_dir} into the user-defined library +search path, immediately before the element starting at address +@var{before}. If @var{before} is @samp{NULL}, then @var{search_dir} is +appending as if @code{lt_dladdsearchdir} had been called. Return 0 on success. @end deftypefun @deftypefun int lt_dlsetsearchpath (const char *@var{search_path}) diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index 501804ed..82881951 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -597,6 +597,33 @@ argz_next (argz, argz_len, entry) +#if ! HAVE_ARGZ_STRINGIFY +# define argz_stringify rpl_argz_stringify + +static void argz_stringify LT_PARAMS((char *argz, size_t argz_len, + int sep)); + +void +argz_stringify (argz, argz_len, sep) + char *argz; + size_t argz_len; + int sep; +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (sep) + { + while (--argz_len >= 0) + { + if (argz[argz_len] == LT_EOS_CHAR) + argz[argz_len] = sep; + } + } +} +#endif /* !HAVE_ARGZ_STRINGIFY */ + + + /* --- TYPE DEFINITIONS -- */ @@ -1604,12 +1631,12 @@ static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1, lt_ptr data2)); -static int canonicalize_path LT_PARAMS((const char *path, +static int canonicalize_path LT_PARAMS((const char *path, char **pcanonical)); -static int argzize_path LT_PARAMS((const char *path, +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, +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, @@ -1630,7 +1657,16 @@ static int trim LT_PARAMS((char **dest, 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_dlpath_insertdir LT_PARAMS((char **ppath, + char *before, + const char *dir)); static char *user_search_path= 0; static lt_dlloader *loaders = 0; @@ -2855,8 +2891,35 @@ lt_dlopenext (filename) return 0; } + int -lt_argz_insert (pargz, pargz_len, entry) +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))) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + return 1; + } + + return 0; +} + +int +lt_argz_insertinorder (pargz, pargz_len, entry) char **pargz; size_t *pargz_len; const char *entry; @@ -2875,26 +2938,8 @@ lt_argz_insert (pargz, pargz_len, entry) if (cmp < 0) break; if (cmp == 0) return 0; /* No duplicates! */ } - - { - error_t error; - if ((error = argz_insert (pargz, pargz_len, before, entry))) - { - switch (error) - { - case ENOMEM: - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - break; - default: - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); - break; - } - return 1; - } - } - - return 0; + return lt_argz_insert (pargz, pargz_len, before, entry); } int @@ -2955,7 +3000,7 @@ lt_argz_insertdir (pargz, pargz_len, dirnam, dp) buf[buf_len] = LT_EOS_CHAR; /* Try to insert (in order) into ARGZ/ARGZ_LEN. */ - if (lt_argz_insert (pargz, pargz_len, buf) != 0) + if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0) ++errors; LT_DLFREE (buf); @@ -3254,42 +3299,125 @@ lt_dlerror () return error ? error : LT_DLSTRERROR (UNKNOWN); } +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 lt_dladdsearchdir (search_dir) const char *search_dir; { int errors = 0; - if (!search_dir || !LT_STRLEN(search_dir)) + if (search_dir && *search_dir) { - return errors; - } - - LT_DLMUTEX_LOCK (); - if (!user_search_path) - { - user_search_path = lt_estrdup (search_dir); - if (!user_search_path) + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0) ++errors; + LT_DLMUTEX_UNLOCK (); } - else - { - size_t len = LT_STRLEN (user_search_path) + 1 + LT_STRLEN (search_dir); - char *new_search_path = LT_EMALLOC (char, 1+ len); - if (!new_search_path) + return errors; +} + +int +lt_dlinsertsearchdir (before, search_dir) + const char *before; + const char *search_dir; +{ + int errors = 0; + + if (before) + { + LT_DLMUTEX_LOCK (); + if ((before < user_search_path) + || (before >= LT_STRLEN (user_search_path))) + { + LT_DLMUTEX_UNLOCK (); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION)); + return 1; + } + LT_DLMUTEX_UNLOCK (); + } + + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, + (char *) before, search_dir) != 0) { ++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 (); } - LT_DLMUTEX_UNLOCK (); return errors; } @@ -3298,7 +3426,7 @@ int lt_dlsetsearchpath (search_path) const char *search_path; { - int errors = 0; + int errors = 0; LT_DLMUTEX_LOCK (); LT_DLFREE (user_search_path); @@ -3310,8 +3438,7 @@ lt_dlsetsearchpath (search_path) } LT_DLMUTEX_LOCK (); - user_search_path = lt_estrdup (search_path); - if (!user_search_path) + if (canonicalize_path (search_path, &user_search_path) != 0) ++errors; LT_DLMUTEX_UNLOCK (); diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h index 569b5ef0..2bbfa302 100644 --- a/libltdl/ltdl.h +++ b/libltdl/ltdl.h @@ -152,10 +152,12 @@ extern int lt_dlinit LT_PARAMS((void)); extern int lt_dlexit LT_PARAMS((void)); /* Module search path manipulation. */ -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)); -extern int lt_dlforeachfile LT_PARAMS(( +extern int lt_dladdsearchdir LT_PARAMS((const char *search_dir)); +extern int lt_dlinsertsearchdir LT_PARAMS((const char *before, + const char *search_dir)); +extern int lt_dlsetsearchpath LT_PARAMS((const char *search_path)); +extern const char *lt_dlgetsearchpath LT_PARAMS((void)); +extern int lt_dlforeachfile LT_PARAMS(( const char *search_path, int (*func) (const char *filename, lt_ptr data), lt_ptr data)); @@ -321,7 +323,8 @@ extern int lt_dlloader_remove LT_PARAMS(( 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 { diff --git a/ltdl.m4 b/ltdl.m4 index e0cbf8a1..b2966b13 100644 --- a/ltdl.m4 +++ b/ltdl.m4 @@ -369,5 +369,5 @@ AC_CHECK_TYPES([error_t], # include #endif]) -AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next]) +AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next argz_stringify]) ])# AC_LTDL_FUNC_ARGZ