summaryrefslogtreecommitdiff
path: root/nuttx/binfmt/binfmt_exec.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-17 14:43:55 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-17 14:43:55 +0000
commitd8d9cc8a96cdc2219af7bec8142e7633779fd685 (patch)
treed9cf39f88361f174a2350d354ffb5584d43e2fc4 /nuttx/binfmt/binfmt_exec.c
parent4f0e8b1249c1550bac83f9db61c67094bc6afc2d (diff)
downloadpx4-nuttx-d8d9cc8a96cdc2219af7bec8142e7633779fd685.tar.gz
px4-nuttx-d8d9cc8a96cdc2219af7bec8142e7633779fd685.tar.bz2
px4-nuttx-d8d9cc8a96cdc2219af7bec8142e7633779fd685.zip
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
Diffstat (limited to 'nuttx/binfmt/binfmt_exec.c')
-rw-r--r--nuttx/binfmt/binfmt_exec.c69
1 files changed, 67 insertions, 2 deletions
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 */