提交 d39acdd2 编写于 作者: W wangjiahui 提交者: huanghuijin

Add dlns_get and add dlns_create2

Need one interface to get dlns, and can set default parent for new namespace. add dlns_create2 interface which caller can create namespace without inherit
from default namespace.

test: creat2 without flags
Signed-off-by: Nhuanghuijin <huanghuijin@huawei.com>
上级 00b747c7
......@@ -220,6 +220,55 @@ void dlopen_ns_0500(void)
dlclose(handle);
}
/**
* @tc.name : dlns_get_0100
* @tc.desc : Gets an existing namespace handle.
* @tc.level : Level 1
*/
void dlns_get_0100(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_get_0100");
dlns_create(&dlns, NULL);
dlns_get("dlns_get_0100", &dlns);
EXPECT_EQ("dlns_get_0100", strcmp(dlns.name, "dlns_get_0100"), 0);
}
/**
* @tc.name : dlns_get_0200
* @tc.desc : Gets the current namespace handle when name=NULL.
* @tc.level : Level 1
*/
void dlns_get_0200(void)
{
Dl_namespace dlns;
dlns_get(NULL, &dlns);
EXPECT_EQ("dlns_get_0200", strcmp(dlns.name, "default"), 0);
}
/**
* @tc.name : dlns_get_0300
* @tc.desc : Call dlns_get when dlns=NULL.
* @tc.level : Level 2
*/
void dlns_get_0300(void)
{
dlns_get(NULL, NULL);
EXPECT_EQ("dlns_get_0300", dlns_get(NULL, NULL), EINVAL);
}
/**
* @tc.name : dlns_get_0400
* @tc.desc : Gets a namespace handle that does not exist.
* @tc.level : Level 2
*/
void dlns_get_0400(void)
{
Dl_namespace dlns;
dlns_init(&dlns, "dlns_get_0400");
EXPECT_EQ("dlns_get_0400", dlns_get("dlns_get_0400", &dlns), ENOKEY);
}
TEST_FUN G_Fun_Array[] = {
dlopen_0100,
dlopen_0200,
......@@ -235,6 +284,10 @@ TEST_FUN G_Fun_Array[] = {
dlopen_ns_0300,
dlopen_ns_0400,
dlopen_ns_0500,
dlns_get_0100,
dlns_get_0200,
dlns_get_0300,
dlns_get_0400,
};
int main(void)
......
......@@ -20,6 +20,11 @@ extern "C" {
#define RTLD_DI_LINKMAP 2
/* create flags for dlns_create */
#define CREATE_INHERIT_DEFAULT 0x1
#define CREATE_INHERIT_CURRENT 0x2
int dlclose(void *);
char *dlerror(void);
void *dlopen(const char *, int);
......@@ -33,17 +38,28 @@ typedef struct {
/**
* @brief Initialize a namespace structure for operating namespaces through related functional interfaces.
* @param Dl_namespace * Carry the naming information of the namespace.
* @param Dl_namespace * namespace handle.
* @param char * namespace name.
* @return void.
* @retval none.
*/
void dlns_init(Dl_namespace *, const char *);
/**
* @brief Gets the current namespace handle, or verifies that the given name namespace exists.
* @param char * Namespace name.Gets the current caller namespace handle when name is null.
* @param Dl_namespace * namespace handle.
* @return return 0 on success,fail other values.
* @retval
* EINVAL(22) Invalid argument.
* ENOKEY(126) Required key not available.
*/
int dlns_get(const char *, Dl_namespace *);
/**
* @brief open dso in given namespace which has own lib search paths, when namespace is null, it's same to dlopen().
* avoid using "default" as namespace, which is the default namespace.
* @param Dl_namespace * Carry the naming information of the namespace.
* @param Dl_namespace * namespace handle.
* @param char * the name of the so file you want to open.
* @param int open file mode.
* -- RTLD_LAZY.
......@@ -61,7 +77,7 @@ void *dlopen_ns(Dl_namespace *, const char *, int);
* @brief create the namespace and set lib search paths of namespace,
* the paths should be splited by ':'. When namespace already exist,return error.
* avoid using "default" as namespace, which is the default namespace.
* @param Dl_namespace * namespace information.
* @param Dl_namespace * namespace handle.
* @param char * lib path library that can be specified.
* @return return 0 on success,fail other values.
* @retval
......@@ -71,6 +87,20 @@ void *dlopen_ns(Dl_namespace *, const char *, int);
*/
int dlns_create(Dl_namespace *, const char *);
/**
* @brief create the namespace and set lib search paths of namespace,
* like dlns_create, except can use flags to set parent ns.
* @param Dl_namespace * namespace handle.
* @param char * lib path library that can be specified.
* #param int flags for create namespace, CREATE_INHERIT_CURRENT or CREATE_INHERIT_DEFAULT.
* @return return 0 on success,fail other values.
* @retval
* EINVAL(22) Invalid argument.
* EEXIST(17) File exists.
* ENOMEM(12) Out of memory.
*/
int dlns_create2(Dl_namespace *, const char *, int);
/**
* @brief make one namespace inherit another, and so it can use shared libs by the inherited one.
* param1: namespace, param2: inherited namespace, param3: shared libs.
......
......@@ -15,4 +15,4 @@ There are two ways to use the linker namespace:
### Usage example
Test usages show some examples of using the linker namespace. The file <ld-musl-namespace.ini> in current directory is configures for test. The file <libc-test/src/functional/dlopen_ns.c> gives usages of how apis and configures work.
Test usages show some examples of using the linker namespace. The file <ld-musl-namespace-arm.ini> or <ld-musl-namespace-aarch64.ini> in config directory is configures for test. The file <libc-test/src/functionalext/dlns/> gives usages of how apis and configures work.
......@@ -2636,6 +2636,36 @@ void dlns_init(Dl_namespace *dlns, const char *name)
LD_LOGI("dlns_init dlns->name:%s .\n", dlns->name);
}
int dlns_get(const char *name, Dl_namespace *dlns)
{
if (!dlns) {
LD_LOGW("dlns_get dlns is null.\n");
return EINVAL;
}
int ret = 0;
ns_t *ns = NULL;
pthread_rwlock_rdlock(&lock);
if (!name) {
struct dso *caller;
const void *caller_addr = __builtin_return_address(0);
caller = (struct dso *)addr2dso((size_t)caller_addr);
ns = ((caller && caller->namespace) ? caller->namespace : get_default_ns());
(void)snprintf(dlns->name, sizeof dlns->name, ns->ns_name);
LD_LOGI("dlns_get name is null, current dlns dlns->name:%s.\n", dlns->name);
} else {
ns = find_ns_by_name(name);
if (ns) {
(void)snprintf(dlns->name, sizeof dlns->name, ns->ns_name);
LD_LOGI("dlns_get found ns, current dlns dlns->name:%s.\n", dlns->name);
} else {
LD_LOGI("dlns_get not found ns! name:%s.\n", name);
ret = ENOKEY;
}
}
pthread_rwlock_unlock(&lock);
return ret;
}
void *dlopen_ns(Dl_namespace *dlns, const char *file, int mode)
{
const void *caller_addr = __builtin_return_address(0);
......@@ -2643,7 +2673,7 @@ void *dlopen_ns(Dl_namespace *dlns, const char *file, int mode)
return dlopen_impl(file, mode, dlns->name, caller_addr, NULL);
}
int dlns_create(Dl_namespace *dlns, const char *lib_path)
int dlns_create2(Dl_namespace *dlns, const char *lib_path, int flags)
{
if (!dlns) {
LD_LOGW("dlns_create dlns is null.\n");
......@@ -2668,7 +2698,20 @@ int dlns_create(Dl_namespace *dlns, const char *lib_path)
ns_add_dso(ns, get_default_ns()->ns_dsos->dsos[0]); /* add main app to this namespace*/
nslist_add_ns(ns); /* add ns to list*/
ns_set_lib_paths(ns, lib_path);
ns_add_inherit(ns, get_default_ns(), NULL);
if ((flags & CREATE_INHERIT_DEFAULT) != 0) {
ns_add_inherit(ns, get_default_ns(), NULL);
}
if ((flags & CREATE_INHERIT_CURRENT) != 0) {
struct dso *caller;
const void *caller_addr = __builtin_return_address(0);
caller = (struct dso *)addr2dso((size_t)caller_addr);
if (caller && caller->namespace) {
ns_add_inherit(ns, caller->namespace, NULL);
}
}
LD_LOGI("dlns_create :"
"ns: %p ,"
"ns_name: %s ,"
......@@ -2680,6 +2723,11 @@ int dlns_create(Dl_namespace *dlns, const char *lib_path)
return 0;
}
int dlns_create(Dl_namespace *dlns, const char *lib_path)
{
return dlns_create2(dlns, lib_path, CREATE_INHERIT_DEFAULT);
}
int dlns_inherit(Dl_namespace *dlns, Dl_namespace *inherited, const char *shared_libs)
{
if (!dlns || !inherited) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册