summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_exec.c')
-rw-r--r--sys/kern/kern_exec.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 41ff7d8..670d5dd 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -65,6 +65,19 @@
MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments");
+static MALLOC_DEFINE(M_ATEXEC, "atexec", "atexec callback");
+
+/*
+ * callout list for things to do at exec time
+ */
+struct execlist {
+ execlist_fn function;
+ TAILQ_ENTRY(execlist) next;
+};
+
+TAILQ_HEAD(exec_list_head, execlist);
+static struct exec_list_head exec_list = TAILQ_HEAD_INITIALIZER(exec_list);
+
static register_t *exec_copyout_strings __P((struct image_params *));
/* XXX This should be vm_size_t. */
@@ -115,6 +128,7 @@ execve(td, uap)
struct vattr attr;
int (*img_first) __P((struct image_params *));
struct pargs *pa;
+ struct execlist *ep;
imgp = &image_params;
@@ -244,6 +258,9 @@ interpret:
goto interpret;
}
+ TAILQ_FOREACH(ep, &exec_list, next)
+ (*ep->function)(p);
+
/*
* Copy out strings (args and env) and initialize stack base
*/
@@ -926,3 +943,44 @@ exec_unregister(execsw_arg)
execsw = newexecsw;
return 0;
}
+
+int
+at_exec(function)
+ execlist_fn function;
+{
+ struct execlist *ep;
+
+#ifdef INVARIANTS
+ /* Be noisy if the programmer has lost track of things */
+ if (rm_at_exec(function))
+ printf("WARNING: exec callout entry (%p) already present\n",
+ function);
+#endif
+ ep = malloc(sizeof(*ep), M_ATEXEC, M_NOWAIT);
+ if (ep == NULL)
+ return (ENOMEM);
+ ep->function = function;
+ TAILQ_INSERT_TAIL(&exec_list, ep, next);
+ return (0);
+}
+
+/*
+ * Scan the exec callout list for the given item and remove it.
+ * Returns the number of items removed (0 or 1)
+ */
+int
+rm_at_exec(function)
+ execlist_fn function;
+{
+ struct execlist *ep;
+
+ TAILQ_FOREACH(ep, &exec_list, next) {
+ if (ep->function == function) {
+ TAILQ_REMOVE(&exec_list, ep, next);
+ free(ep, M_ATEXEC);
+ return(1);
+ }
+ }
+ return (0);
+}
+
OpenPOWER on IntegriCloud