Browse Source

Add rtld_global option for PLUGIN tag

Serj Kalichev 8 years ago
parent
commit
e6cb02f6b3
6 changed files with 39 additions and 7 deletions
  1. 4 0
      clish.xsd
  2. 2 0
      clish/plugin.h
  3. 20 1
      clish/plugin/plugin.c
  4. 7 6
      clish/plugin/plugin_dump.c
  5. 1 0
      clish/plugin/private.h
  6. 5 0
      clish/shell/shell_xml.c

+ 4 - 0
clish.xsd

@@ -530,6 +530,9 @@
 *******************************************************
 * <PLUGIN> is used to dynamically load plugins
 *
+* [rtld_global] - A boolean RTLD_GLOBAL flag for dlopen()
+*                 while plugin loading. Default is "false".
+*
 ********************************************************
 -->
     <xs:complexType name="plugin_t">
@@ -538,6 +541,7 @@
                 <xs:attribute name="name" type="xs:string" use="required"/>
                 <xs:attribute name="alias" type="xs:string" use="optional"/>
                 <xs:attribute name="file" type="xs:string" use="optional"/>
+                <xs:attribute name="rtld_global" type="bool_t" use="optional" default="false"/>
             </xs:extension>
         </xs:simpleContent>
     </xs:complexType>

+ 2 - 0
clish/plugin.h

@@ -123,6 +123,8 @@ void clish_plugin__set_builtin_flag(clish_plugin_t *instance, bool_t builtin_fla
 bool_t clish_plugin__get_builtin_flag(const clish_plugin_t *instance);
 void clish_plugin__set_conf(clish_plugin_t *instance, const char *conf);
 char *clish_plugin__get_conf(const clish_plugin_t *instance);
+void clish_plugin__set_rtld_global(clish_plugin_t *instance, bool_t rtld_global);
+bool_t clish_plugin__get_rtld_global(const clish_plugin_t *instance);
 
 #endif				/* _clish_plugin_h */
 /** @} clish_plugin */

+ 20 - 1
clish/plugin/plugin.c

@@ -164,6 +164,8 @@ clish_plugin_t *clish_plugin_new(const char *name)
 	/* Constructor and destructor */
 	this->init = NULL;
 	this->fini = NULL;
+	/* Flags */
+	this->rtld_global = BOOL_FALSE; /* The dlopen() use RTLD_LOCAL by default */
 
 	return this;
 }
@@ -334,6 +336,7 @@ static int clish_plugin_load_shared(clish_plugin_t *this)
 #ifdef HAVE_DLFCN_H
 	char *file = NULL; /* Plugin so file name */
 	char *init_name = NULL; /* Init function name */
+	int flag = RTLD_NOW;
 
 	if (this->file) {
 		file = lub_string_dup(this->file);
@@ -344,7 +347,11 @@ static int clish_plugin_load_shared(clish_plugin_t *this)
 	}
 
 	/* Open dynamic library */
-	this->dlhan = dlopen(file, RTLD_NOW | RTLD_LOCAL);
+	if (clish_plugin__get_rtld_global(this))
+		flag |= RTLD_GLOBAL;
+	else
+		flag |= RTLD_LOCAL;
+	this->dlhan = dlopen(file, flag);
 	lub_string_free(file);
 	if (!this->dlhan) {
 		fprintf(stderr, "Error: Can't open plugin \"%s\": %s\n",
@@ -464,3 +471,15 @@ char *clish_plugin__get_conf(const clish_plugin_t *this)
 }
 
 /*--------------------------------------------------------- */
+void clish_plugin__set_rtld_global(clish_plugin_t *this, bool_t rtld_global)
+{
+	this->rtld_global = rtld_global;
+}
+
+/*--------------------------------------------------------- */
+bool_t clish_plugin__get_rtld_global(const clish_plugin_t *this)
+{
+	return this->rtld_global;
+}
+
+/*--------------------------------------------------------- */

+ 7 - 6
clish/plugin/plugin_dump.c

@@ -52,12 +52,13 @@ void clish_plugin_dump(const clish_plugin_t *this)
 
 	lub_dump_printf("plugin(%p)\n", this);
 	lub_dump_indent();
-	lub_dump_printf("name  : %s\n", LUB_DUMP_STR(this->name));
-	lub_dump_printf("alias : %s\n", LUB_DUMP_STR(this->alias));
-	lub_dump_printf("conf  : %s\n", LUB_DUMP_STR(this->conf));
-	lub_dump_printf("dlhan : %p\n", this->dlhan);
-	lub_dump_printf("init  : %p\n", this->init);
-	lub_dump_printf("fini  : %p\n", this->fini);
+	lub_dump_printf("name        : %s\n", LUB_DUMP_STR(this->name));
+	lub_dump_printf("alias       : %s\n", LUB_DUMP_STR(this->alias));
+	lub_dump_printf("conf        : %s\n", LUB_DUMP_STR(this->conf));
+	lub_dump_printf("dlhan       : %p\n", this->dlhan);
+	lub_dump_printf("init        : %p\n", this->init);
+	lub_dump_printf("fini        : %p\n", this->fini);
+	lub_dump_printf("rtld_global : %s\n", LUB_DUMP_BOOL(this->rtld_global));
 	lub_dump_indent();
 	/* Iterate child elements */
 	for(iter = lub_list__get_head(this->syms);

+ 1 - 0
clish/plugin/private.h

@@ -28,4 +28,5 @@ struct clish_plugin_s {
 	void *dlhan; /* Handler of dlopen() */
 	clish_plugin_init_t *init; /* Init function (constructor) != NULL */
 	clish_plugin_fini_t *fini; /* Fini function (destructor) */
+	bool_t rtld_global; /* RTLD_GLOBAL flag for dlopen() */
 };

+ 5 - 0
clish/shell/shell_xml.c

@@ -1167,6 +1167,7 @@ static int process_plugin(clish_shell_t *shell, clish_xmlnode_t *element,
 	char *file = clish_xmlnode_fetch_attr(element, "file");
 	char *name = clish_xmlnode_fetch_attr(element, "name");
 	char *alias = clish_xmlnode_fetch_attr(element, "alias");
+	char *rtld_global = clish_xmlnode_fetch_attr(element, "rtld_global");
 	int res = -1;
 	char *text;
 
@@ -1191,6 +1192,9 @@ static int process_plugin(clish_shell_t *shell, clish_xmlnode_t *element,
 	if (file && *file)
 		clish_plugin__set_file(plugin, file);
 
+	if (rtld_global && lub_string_nocasecmp(rtld_global, "true") == 0)
+		clish_plugin__set_rtld_global(plugin, BOOL_TRUE);
+
 	/* Get PLUGIN body content */
 	text = clish_xmlnode_get_all_content(element);
 	if (text && *text)
@@ -1203,6 +1207,7 @@ error:
 	clish_xml_release(file);
 	clish_xml_release(name);
 	clish_xml_release(alias);
+	clish_xml_release(rtld_global);
 
 	parent = parent; /* Happy compiler */