/* ltdl.c -- system independent dlopen wrapper
- Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2004, 2005 Free Software Foundation, Inc.
Originally by Thomas Tanner <tanner@ffii.org>
This file is part of GNU Libtool.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA
*/
DIR *entry;
assert(path != (char *) NULL);
- (void) strncpy(file_specification,path,LT_FILENAME_MAX-1);
+ /* allow space for: path + '\\' '\\' '*' '.' '*' + '\0' */
+ (void) strncpy (file_specification, path, LT_FILENAME_MAX-6);
+ file_specification[LT_FILENAME_MAX-6] = LT_EOS_CHAR;
(void) strcat(file_specification,"\\");
entry = LT_DLMALLOC (DIR,sizeof(DIR));
if (entry != (DIR *) 0)
entry->firsttime = FALSE;
(void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
LT_FILENAME_MAX-1);
+ entry->file_info.d_name[LT_FILENAME_MAX - 1] = LT_EOS_CHAR;
entry->file_info.d_namlen = strlen(entry->file_info.d_name);
return(&entry->file_info);
}
assert (pargz);
assert (pargz_len);
- /* Make a copy of STR, but replacing each occurence of
+ /* Make a copy of STR, but replacing each occurrence of
DELIM with '\0'. */
argz_len = 1+ LT_STRLEN (str);
if (argz_len)
if (!searchname)
return 0;
-#if __CYGWIN__
{
- char wpath[MAX_PATH];
- cygwin_conv_to_full_win32_path(searchname, wpath);
- module = LoadLibrary(wpath);
- }
+ /* Silence dialog from LoadLibrary on some failures.
+ No way to get the error mode, but to set it,
+ so set it twice to preserve any previous flags. */
+ UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS);
+ SetErrorMode(errormode | SEM_FAILCRITICALERRORS);
+
+#if defined(__CYGWIN__)
+ {
+ char wpath[MAX_PATH];
+ cygwin_conv_to_full_win32_path (searchname, wpath);
+ module = LoadLibrary (wpath);
+ }
#else
- module = LoadLibrary (searchname);
+ module = LoadLibrary (searchname);
#endif
+
+ /* Restore the error mode. */
+ SetErrorMode(errormode);
+ }
+
LT_DLFREE (searchname);
/* libltdl expects this function to fail if it is unable
static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
const char *filename));
static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
- const char *filename));
+ const char *filename,
+ const char * useloader));
static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
static int lt_argz_insert LT_PARAMS((char **pargz,
size_t *pargz_len,
LT_DLMEM_REASSIGN (loader, next);
}
loaders = 0;
+
+ LT_DLFREE (user_search_path);
}
done:
}
static int
-tryall_dlopen (handle, filename)
+tryall_dlopen (handle, filename, useloader)
lt_dlhandle *handle;
const char *filename;
+ const char *useloader;
{
lt_dlhandle cur;
lt_dlloader *loader;
while (loader)
{
+ if (useloader && strcmp(loader->loader_name, useloader))
+ {
+ loader = loader->next;
+ continue;
+ }
lt_user_data data = loader->dlloader_data;
cur->module = loader->module_open (data, filename);
error += tryall_dlopen_module (handle,
(const char *) 0, prefix, filename);
}
- else if (tryall_dlopen (handle, filename) != 0)
+ else if (tryall_dlopen (handle, filename, NULL) != 0)
{
++error;
}
/* 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)
+ if (old_name && tryall_dlopen (handle, old_name, "dlpreload") == 0)
{
return 0;
}
/* maybe it was moved to another directory */
{
- if (tryall_dlopen_module (handle,
- (const char *) 0, dir, dlname) == 0)
+ if (dir && (tryall_dlopen_module (handle,
+ (const char *) 0, dir, dlname) == 0))
return 0;
}
}
/* Try to dlopen the file, but do not continue searching in any
case. */
- if (tryall_dlopen (handle, filename) != 0)
+ if (tryall_dlopen (handle, filename,NULL) != 0)
*handle = 0;
return 1;
}
}
- /* restore the old search path */
- LT_DLFREE (user_search_path);
- user_search_path = save_search_path;
-
- LT_DLMUTEX_UNLOCK ();
-
if (!depcount)
{
errors = 0;
cleanup:
LT_DLFREE (names);
+ /* restore the old search path */
+ if (user_search_path) {
+ LT_DLFREE (user_search_path);
+ user_search_path = save_search_path;
+ }
+ LT_DLMUTEX_UNLOCK ();
+
#endif
return errors;
LT_DLFREE (*dest);
+ if (!end)
+ return 1;
+
if (len > 3 && str[0] == '\'')
{
tmp = LT_EMALLOC (char, end - str);
/* lt_dlclose()ing yourself is very bad! Disallow it. */
LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
- if (tryall_dlopen (&newhandle, 0) != 0)
+ if (tryall_dlopen (&newhandle, 0, NULL) != 0)
{
LT_DLFREE (*phandle);
return 1;
++base_name;
}
else
- LT_DLMEM_REASSIGN (base_name, canonical);
+ base_name = canonical;
assert (base_name && *base_name);
}
#endif
}
- if (!file)
+ else
{
file = fopen (filename, LT_READTEXT_MODE);
}
#endif
)))
{
- if (tryall_dlopen (&newhandle, filename) != 0)
+ if (tryall_dlopen (&newhandle, filename, NULL) != 0)
{
newhandle = NULL;
}
strcpy (tmp, filename);
strcat (tmp, archive_ext);
errors = try_dlopen (&handle, tmp);
- if (errors) return 0;
+ if (handle && errors) {
+ LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
+ return 0; /* leaks tmp and handle */
+ }
+ if (handle && errors) {
+ LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
+ return 0; /* leaks tmp and 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
else
{
tmp[len] = LT_EOS_CHAR;
+ if (handle && errors) {
+ LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
+ return 0; /* leaks tmp and handle */
+ }
}
strcat(tmp, shlib_ext);
errors = try_dlopen (&handle, tmp);
- if (errors) return 0;
+ if (handle && errors) {
+ LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
+ return 0; /* leaks tmp and handle */
+ }
/* As before, if the file was found but loading failed, return now
with the current error message. */
{
error_t error;
- if ((error = argz_insert (pargz, pargz_len, before, entry)))
+ /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
+ pargz_len, NULL, entry) failed with EINVAL. */
+ if (before)
+ error = argz_insert (pargz, pargz_len, before, entry);
+ else
+ error = argz_append (pargz, pargz_len, entry, 1 + LT_STRLEN (entry));
+
+ if (error)
{
switch (error)
{