1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

Implement ltdl-like directory search for modules

Search LTDL_LIBRARY_PATH and LD_LIBRARY_PATH before
the system extensions path.

* dynl.c (sysdep_dynl_link_search): new procedure
  (sysdep_dynl_link): search library paths
This commit is contained in:
Mike Gran 2020-03-24 14:55:21 -07:00
parent f6373cf69f
commit bcce103393

View file

@ -66,6 +66,60 @@ static scm_i_pthread_mutex_t ltdl_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
/* LT_PATH_SEP-separated extension library search path, searched last */ /* LT_PATH_SEP-separated extension library search path, searched last */
static char *system_extensions_path; static char *system_extensions_path;
static void *
sysdep_dynl_link_search (const char *fname, const char *subr, char *library_path)
{
GModule *handle = NULL;
if (library_path == NULL || strlen(library_path) == 0)
return NULL;
char *fname_attempt
= scm_gc_malloc_pointerless (strlen (library_path)
+ strlen (fname) + 2,
"dynl fname_attempt");
char *path; /* remaining path to search */
char *end; /* end of current path component */
char *s;
/* Iterate over the components of SYSTEM_EXTENSIONS_PATH */
for (path = library_path;
*path != '\0';
path = (*end == '\0') ? end : (end + 1))
{
/* Find end of path component */
end = strchr (path, LT_PATHSEP_CHAR);
if (end == NULL)
end = strchr (path, '\0');
/* Skip empty path components */
if (path == end)
continue;
/* Construct FNAME_ATTEMPT, starting with path component */
s = fname_attempt;
memcpy (s, path, end - path);
s += end - path;
/* Append directory separator, but avoid duplicates */
if (s[-1] != '/'
#ifdef LT_DIRSEP_CHAR
&& s[-1] != LT_DIRSEP_CHAR
#endif
)
*s++ = '/';
/* Finally, append FNAME (including null terminator) */
strcpy (s, fname);
/* Try to load it, and terminate the search if successful */
handle = g_module_open (fname_attempt, 0);
if (handle != NULL)
break;
}
return handle;
}
static void * static void *
sysdep_dynl_link (const char *fname, const char *subr) sysdep_dynl_link (const char *fname, const char *subr)
{ {
@ -73,8 +127,8 @@ sysdep_dynl_link (const char *fname, const char *subr)
/* Try the literal filename first or, if NULL, the program itself */ /* Try the literal filename first or, if NULL, the program itself */
handle = g_module_open (fname, 0); handle = g_module_open (fname, 0);
if (handle == NULL if (handle == NULL && fname != NULL
#ifdef LT_DIRSEP_CHAR #ifdef LT_DIRSEP_CHAR
&& strchr (fname, LT_DIRSEP_CHAR) == NULL && strchr (fname, LT_DIRSEP_CHAR) == NULL
#endif #endif
@ -82,49 +136,18 @@ sysdep_dynl_link (const char *fname, const char *subr)
{ {
/* FNAME contains no directory separators and was not in the /* FNAME contains no directory separators and was not in the
usual library search paths, so now we search for it in usual library search paths, so now we search for it in
SYSTEM_EXTENSIONS_PATH. */ LTDL_LIBRARY_PATH, LD_LIBRARY_PATH, and SYSTEM_EXTENSIONS_PATH. */
char *fname_attempt handle = sysdep_dynl_link_search (fname, subr, getenv("LTDL_LIBRARY_PATH"));
= scm_gc_malloc_pointerless (strlen (system_extensions_path) if (!handle)
+ strlen (fname) + 2, handle = sysdep_dynl_link_search (fname, subr, getenv("LD_LIBRARY_PATH"));
"dynl fname_attempt"); if (!handle)
char *path; /* remaining path to search */ handle = sysdep_dynl_link_search (fname, subr, system_extensions_path);
char *end; /* end of current path component */ if (!handle)
char *s;
/* Iterate over the components of SYSTEM_EXTENSIONS_PATH */
for (path = system_extensions_path;
*path != '\0';
path = (*end == '\0') ? end : (end + 1))
{ {
/* Find end of path component */ SCM fn;
end = strchr (path, LT_PATHSEP_CHAR);
if (end == NULL)
end = strchr (path, '\0');
/* Skip empty path components */
if (path == end)
continue;
/* Construct FNAME_ATTEMPT, starting with path component */ fn = fname != NULL ? scm_from_locale_string (fname) : SCM_BOOL_F;
s = fname_attempt; scm_misc_error (subr, "module ~S not found in search paths", scm_list_1 (fn));
memcpy (s, path, end - path);
s += end - path;
/* Append directory separator, but avoid duplicates */
if (s[-1] != '/'
#ifdef LT_DIRSEP_CHAR
&& s[-1] != LT_DIRSEP_CHAR
#endif
)
*s++ = '/';
/* Finally, append FNAME (including null terminator) */
strcpy (s, fname);
/* Try to load it, and terminate the search if successful */
handle = g_module_open (fname_attempt, 0);
if (handle != NULL)
break;
} }
} }
@ -135,7 +158,7 @@ sysdep_dynl_link (const char *fname, const char *subr)
fn = fname != NULL ? scm_from_locale_string (fname) : SCM_BOOL_F; fn = fname != NULL ? scm_from_locale_string (fname) : SCM_BOOL_F;
msg = scm_from_locale_string (g_module_error ()); msg = scm_from_locale_string (g_module_error ());
scm_misc_error (subr, "file: ~S, message: ~S", scm_list_2 (fn, msg)); scm_misc_error (subr, "module ~S not found, message: ~S", scm_list_2 (fn, msg));
} }
return (void *) handle; return (void *) handle;
@ -149,7 +172,7 @@ sysdep_dynl_unlink (void *handle, const char *subr)
scm_misc_error (subr, (char *) g_module_error (), SCM_EOL); scm_misc_error (subr, (char *) g_module_error (), SCM_EOL);
} }
} }
static void * static void *
sysdep_dynl_value (const char *symb, void *handle, const char *subr) sysdep_dynl_value (const char *symb, void *handle, const char *subr)
{ {
@ -257,7 +280,7 @@ SCM_DEFINE (scm_dynamic_link, "dynamic-link", 0, 1, 0,
#undef FUNC_NAME #undef FUNC_NAME
SCM_DEFINE (scm_dynamic_object_p, "dynamic-object?", 1, 0, 0, SCM_DEFINE (scm_dynamic_object_p, "dynamic-object?", 1, 0, 0,
(SCM obj), (SCM obj),
"Return @code{#t} if @var{obj} is a dynamic object handle,\n" "Return @code{#t} if @var{obj} is a dynamic object handle,\n"
"or @code{#f} otherwise.") "or @code{#f} otherwise.")
@ -268,7 +291,7 @@ SCM_DEFINE (scm_dynamic_object_p, "dynamic-object?", 1, 0, 0,
#undef FUNC_NAME #undef FUNC_NAME
SCM_DEFINE (scm_dynamic_unlink, "dynamic-unlink", 1, 0, 0, SCM_DEFINE (scm_dynamic_unlink, "dynamic-unlink", 1, 0, 0,
(SCM dobj), (SCM dobj),
"Unlink a dynamic object from the application, if possible. The\n" "Unlink a dynamic object from the application, if possible. The\n"
"object must have been linked by @code{dynamic-link}, with \n" "object must have been linked by @code{dynamic-link}, with \n"
@ -330,7 +353,7 @@ SCM_DEFINE (scm_dynamic_pointer, "dynamic-pointer", 2, 0, 0,
#undef FUNC_NAME #undef FUNC_NAME
SCM_DEFINE (scm_dynamic_func, "dynamic-func", 2, 0, 0, SCM_DEFINE (scm_dynamic_func, "dynamic-func", 2, 0, 0,
(SCM name, SCM dobj), (SCM name, SCM dobj),
"Return a ``handle'' for the function @var{name} in the\n" "Return a ``handle'' for the function @var{name} in the\n"
"shared object referred to by @var{dobj}. The handle\n" "shared object referred to by @var{dobj}. The handle\n"
@ -347,7 +370,7 @@ SCM_DEFINE (scm_dynamic_func, "dynamic-func", 2, 0, 0,
#undef FUNC_NAME #undef FUNC_NAME
SCM_DEFINE (scm_dynamic_call, "dynamic-call", 2, 0, 0, SCM_DEFINE (scm_dynamic_call, "dynamic-call", 2, 0, 0,
(SCM func, SCM dobj), (SCM func, SCM dobj),
"Call a C function in a dynamic object. Two styles of\n" "Call a C function in a dynamic object. Two styles of\n"
"invocation are supported:\n\n" "invocation are supported:\n\n"