From d8d9cc8a96cdc2219af7bec8142e7633779fd685 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 17 Jan 2013 14:43:55 +0000 Subject: 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 --- nuttx/binfmt/binfmt_exec.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) (limited to 'nuttx/binfmt/binfmt_exec.c') diff --git a/nuttx/binfmt/binfmt_exec.c b/nuttx/binfmt/binfmt_exec.c index d878c8cc5..1cead4384 100644 --- a/nuttx/binfmt/binfmt_exec.c +++ b/nuttx/binfmt/binfmt_exec.c @@ -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 */ -- cgit v1.2.3