mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 23:03:27 +08:00
libs/libc/dllfcn, sched/init: Add LD_LIBRARY_PATH environment variable support.
This commit is contained in:
@@ -17,4 +17,16 @@ config LIBC_DLLFCN
|
|||||||
|
|
||||||
A work in progress, hence, marked EXPERIMENTAL
|
A work in progress, hence, marked EXPERIMENTAL
|
||||||
|
|
||||||
|
if LIBC_DLLFCN
|
||||||
|
|
||||||
|
config LDPATH_INITIAL
|
||||||
|
string "Initial LD_LIBRARY_PATH Value"
|
||||||
|
default ""
|
||||||
|
depends on LIB_ENVPATH
|
||||||
|
---help---
|
||||||
|
The initial value of the LD_LIBRARY_PATH variable. This is the
|
||||||
|
colon-separated list of absolute paths. E.g., "/lib:/usr/lib:/system/lib"
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
# endmenu # Shared Library Support
|
# endmenu # Shared Library Support
|
||||||
|
|||||||
+102
-52
@@ -46,6 +46,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/envpath.h>
|
||||||
#include <nuttx/module.h>
|
#include <nuttx/module.h>
|
||||||
#include <nuttx/lib/modlib.h>
|
#include <nuttx/lib/modlib.h>
|
||||||
|
|
||||||
@@ -161,6 +162,14 @@ static void dldump_initializer(mod_initializer_t initializer,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_PROTECTED
|
#ifdef CONFIG_BUILD_PROTECTED
|
||||||
|
/* The PROTECTED build is equivalent to the FLAT build EXCEPT that there
|
||||||
|
* must be two copies of the module logic: One residing in kernel
|
||||||
|
* space and using the kernel symbol table and one residing in user space
|
||||||
|
* using the user space symbol table.
|
||||||
|
*
|
||||||
|
* dlinsert() is essentially a clone of insmod().
|
||||||
|
*/
|
||||||
|
|
||||||
static inline FAR void *dlinsert(FAR const char *filename)
|
static inline FAR void *dlinsert(FAR const char *filename)
|
||||||
{
|
{
|
||||||
struct mod_loadinfo_s loadinfo;
|
struct mod_loadinfo_s loadinfo;
|
||||||
@@ -257,6 +266,50 @@ errout_with_lock:
|
|||||||
set_errno(-ret);
|
set_errno(-ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#elif defined(CONFIG_BUILD_FLAT)
|
||||||
|
/* In the FLAT build, a shared library is essentially the same as a kernel
|
||||||
|
* module.
|
||||||
|
*
|
||||||
|
* REVIST: Missing functionality:
|
||||||
|
* - No automatic binding of symbols
|
||||||
|
* - No dependencies
|
||||||
|
* - mode is ignored.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline FAR void *dlinsert(FAR const char *filename)
|
||||||
|
{
|
||||||
|
FAR void *handle;
|
||||||
|
FAR char *name;
|
||||||
|
|
||||||
|
DEBUGASSERT(filename != NULL);
|
||||||
|
|
||||||
|
name = strdup(filename);
|
||||||
|
if (name == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then install the file using the basename of the file as the module name. */
|
||||||
|
|
||||||
|
handle = insmod(filename, basename(name));
|
||||||
|
free(name);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
#else /* if defined(CONFIG_BUILD_KERNEL) */
|
||||||
|
/* The KERNEL build is considerably more complex: In order to be shared,
|
||||||
|
* the .text portion of the module must be (1) build for PIC/PID operation
|
||||||
|
* and (2) must like in a shared memory region accessible from all
|
||||||
|
* processes. The .data/.bss portion of the module must be allocated in
|
||||||
|
* the user space of each process, but must lie at the same virtual address
|
||||||
|
* so that it can be referenced from the one copy of the text in the shared
|
||||||
|
* memory region.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline FAR void *dlinsert(FAR const char *filename)
|
||||||
|
{
|
||||||
|
#warning Missing logic
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -365,61 +418,58 @@ errout_with_lock:
|
|||||||
|
|
||||||
FAR void *dlopen(FAR const char *file, int mode)
|
FAR void *dlopen(FAR const char *file, int mode)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_BUILD_FLAT)
|
FAR void *handle = NULL;
|
||||||
FAR void *handle;
|
|
||||||
FAR char *name;
|
|
||||||
|
|
||||||
DEBUGASSERT(file != NULL);
|
#ifdef CONFIG_LIB_ENVPATH
|
||||||
|
if (file[0] != '/')
|
||||||
/* In the FLAT build, a shared library is essentially the same as a kernel
|
|
||||||
* module.
|
|
||||||
*
|
|
||||||
* REVIST: Missing functionality:
|
|
||||||
* - No automatic binding of symbols
|
|
||||||
* - No dependencies
|
|
||||||
* - mode is ignored.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Use the basename of the file as the module name.
|
|
||||||
* REVISIT: This places an non-standard restriction. We cannot install
|
|
||||||
* two modules of the same name event though they lie in different
|
|
||||||
* directories.
|
|
||||||
*/
|
|
||||||
|
|
||||||
name = strdup(file);
|
|
||||||
if (name == NULL)
|
|
||||||
{
|
{
|
||||||
return NULL;
|
FAR const char *relpath;
|
||||||
|
FAR char *fullpath;
|
||||||
|
ENVPATH_HANDLE env;
|
||||||
|
|
||||||
|
/* Set aside the relative path */
|
||||||
|
|
||||||
|
relpath = file;
|
||||||
|
|
||||||
|
/* Initialize to traverse the LD_LIBRARY_PATH variable */
|
||||||
|
|
||||||
|
env = envpath_init("LD_LIBRARY_PATH");
|
||||||
|
if (env)
|
||||||
|
{
|
||||||
|
/* Get the next absolute file path */
|
||||||
|
|
||||||
|
while ((fullpath = envpath_next(env, relpath)) != NULL)
|
||||||
|
{
|
||||||
|
/* Try to load the file at this path */
|
||||||
|
|
||||||
|
handle = dlinsert(fullpath);
|
||||||
|
|
||||||
|
/* Free the allocated fullpath */
|
||||||
|
|
||||||
|
lib_free(fullpath);
|
||||||
|
|
||||||
|
/* Break out of the loop with handle != NULL on success */
|
||||||
|
|
||||||
|
if (handle != NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the traversal handle */
|
||||||
|
|
||||||
|
envpath_release(env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* We already have the one and only absolute path to the file to
|
||||||
|
* be loaded.
|
||||||
|
*/
|
||||||
|
|
||||||
|
handle = dlinsert(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then install the file using the basename of the file as the module name. */
|
|
||||||
|
|
||||||
handle = insmod(file, basename(name));
|
|
||||||
free(name);
|
|
||||||
return handle;
|
return handle;
|
||||||
|
|
||||||
#elif defined(CONFIG_BUILD_PROTECTED)
|
|
||||||
/* The PROTECTED build is equivalent to the FLAT build EXCEPT that there
|
|
||||||
* must be two copies of the module logic: One residing in kernel
|
|
||||||
* space and using the kernel symbol table and one residing in user space
|
|
||||||
* using the user space symbol table.
|
|
||||||
*
|
|
||||||
* dlinsert() is essentially a clone of insmod().
|
|
||||||
*/
|
|
||||||
|
|
||||||
return dlinsert(file);
|
|
||||||
|
|
||||||
#else /* if defined(CONFIG_BUILD_KERNEL) */
|
|
||||||
/* The KERNEL build is considerably more complex: In order to be shared,
|
|
||||||
* the .text portion of the module must be (1) build for PIC/PID operation
|
|
||||||
* and (2) must like in a shared memory region accessible from all
|
|
||||||
* processes. The .data/.bss portion of the module must be allocated in
|
|
||||||
* the user space of each process, but must lie at the same virtual address
|
|
||||||
* so that it can be referenced from the one copy of the text in the shared
|
|
||||||
* memory region.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#warning Missing logic
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -436,6 +436,10 @@ int os_bringup(void)
|
|||||||
(void)setenv("PATH", CONFIG_PATH_INITIAL, 1);
|
(void)setenv("PATH", CONFIG_PATH_INITIAL, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_LDPATH_INITIAL)
|
||||||
|
(void)setenv("LD_LIBRARY_PATH", CONFIG_LDPATH_INITIAL, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Start the page fill worker kernel thread that will resolve page faults.
|
/* Start the page fill worker kernel thread that will resolve page faults.
|
||||||
* This should always be the first thread started because it may have to
|
* This should always be the first thread started because it may have to
|
||||||
* resolve page faults in other threads
|
* resolve page faults in other threads
|
||||||
@@ -458,7 +462,7 @@ int os_bringup(void)
|
|||||||
|
|
||||||
/* We an save a few bytes by discarding the IDLE thread's environment. */
|
/* We an save a few bytes by discarding the IDLE thread's environment. */
|
||||||
|
|
||||||
#if !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_PATH_INITIAL)
|
#if !defined(CONFIG_DISABLE_ENVIRON) && (defined(CONFIG_PATH_INITIAL) || defined(CONFIG_LDPATH_INITIAL))
|
||||||
(void)clearenv();
|
(void)clearenv();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user