mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
Add logic to automatically unload module on exit; Several patches from Mike Smith
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5528 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -52,6 +52,10 @@ ifeq ($(CONFIG_BINFMT_EXEPATH),y)
|
||||
BINFMT_CSRCS += binfmt_exepath.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
|
||||
BINFMT_CSRCS += binfmt_schedunload.c
|
||||
endif
|
||||
|
||||
# Symbol table source files
|
||||
|
||||
BINFMT_CSRCS += symtab_findbyname.c symtab_findbyvalue.c
|
||||
|
||||
+67
-2
@@ -74,7 +74,9 @@
|
||||
*
|
||||
* Description:
|
||||
* This is a convenience function that wraps load_ and exec_module into
|
||||
* one call.
|
||||
* one call. If CONFIG_SCHED_ONEXIT is also defined, this function will
|
||||
* automatically call schedule_unload() to unload the module when task
|
||||
* exits.
|
||||
*
|
||||
* Input Parameter:
|
||||
* filename - Fulll path to the binary to be loaded
|
||||
@@ -84,7 +86,7 @@
|
||||
*
|
||||
* Returned Value:
|
||||
* This is an end-user function, so it follows the normal convention:
|
||||
* Returns the PID of the exec'ed module. On failure, it.returns
|
||||
* It returns the PID of the exec'ed module. On failure, it returns
|
||||
* -1 (ERROR) and sets errno appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
@@ -92,6 +94,66 @@
|
||||
int exec(FAR const char *filename, FAR const char **argv,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_ONEXIT
|
||||
FAR struct binary_s *bin;
|
||||
int errorcode;
|
||||
int ret;
|
||||
|
||||
/* Allocate the load information */
|
||||
|
||||
bin = (FAR struct binary_s *)kzalloc(sizeof(struct binary_s));
|
||||
if (!bin)
|
||||
{
|
||||
set_errno(ENOMEM);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Load the module into memory */
|
||||
|
||||
bin->filename = filename;
|
||||
bin->exports = exports;
|
||||
bin->nexports = nexports;
|
||||
|
||||
ret = load_module(bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: Failed to load program '%s'\n", filename);
|
||||
kfree(bin);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Disable pre-emption so that the executed module does
|
||||
* not return until we get a chance to connect the on_exit
|
||||
* handler.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Then start the module */
|
||||
|
||||
ret = exec_module(bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: Failed to execute program '%s'\n", filename);
|
||||
sched_unlock();
|
||||
unload_module(bin);
|
||||
kfree(bin);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Set up to unload the module (and free the binary_s structure)
|
||||
* when the task exists.
|
||||
*/
|
||||
|
||||
ret = schedul_unload(ret, bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: Failed to schedul unload '%s'\n", filename);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return ret;
|
||||
#else
|
||||
struct binary_s bin;
|
||||
int ret;
|
||||
|
||||
@@ -119,7 +181,10 @@ int exec(FAR const char *filename, FAR const char **argv,
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* TODO: How does the module get unloaded in this case? */
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BINFMT_DISABLE */
|
||||
|
||||
+5
-3
@@ -89,6 +89,7 @@ static struct binfmt_s g_builtin_binfmt =
|
||||
static int builtin_loadbinary(struct binary_s *binp)
|
||||
{
|
||||
FAR const char *filename;
|
||||
FAR const struct builtin_s *b;
|
||||
int fd;
|
||||
int index;
|
||||
int ret;
|
||||
@@ -134,9 +135,10 @@ static int builtin_loadbinary(struct binary_s *binp)
|
||||
* the priority. That is a bug and needs to be fixed.
|
||||
*/
|
||||
|
||||
binp->entrypt = g_builtins[index].main;
|
||||
binp->stacksize = g_builtins[index].stacksize;
|
||||
binp->priority = g_builtins[index].priority;
|
||||
b = builtin_for_index(index);
|
||||
binp->entrypt = b->main;
|
||||
binp->stacksize = b->stacksize;
|
||||
binp->priority = b->priority;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,10 +83,14 @@
|
||||
|
||||
FAR const char *builtin_getname(int index)
|
||||
{
|
||||
if (index < 0 || index >= number_builtins())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
struct builtin_s *b;
|
||||
|
||||
return g_builtins[index].name;
|
||||
b = builtin_for_index(index);
|
||||
|
||||
if (b != NULL)
|
||||
{
|
||||
return b->name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -80,18 +80,19 @@
|
||||
* Name: builtin_isavail
|
||||
*
|
||||
* Description:
|
||||
* Return the index into the table of applications for the applicaiton with
|
||||
* Return the index into the table of applications for the application with
|
||||
* the name 'appname'.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int builtin_isavail(FAR const char *appname)
|
||||
{
|
||||
FAR const char *n;
|
||||
int i;
|
||||
|
||||
for (i = 0; g_builtins[i].name; i++)
|
||||
for (i = 0; n = builtin_getname(i); i++)
|
||||
{
|
||||
if (!strncmp(g_builtins[i].name, appname, NAME_MAX))
|
||||
if (!strncmp(n, appname, NAME_MAX))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user