diff options
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | procfs.c | 15 | ||||
-rw-r--r-- | procfs.h | 6 | ||||
-rw-r--r-- | procfs_dir.c | 27 | ||||
-rw-r--r-- | procfs_dir.h | 9 | ||||
-rw-r--r-- | proclist.c | 2 |
6 files changed, 51 insertions, 10 deletions
@@ -35,7 +35,7 @@ int main (int argc, char **argv) error (1, 0, "Must be started as a translator"); netfs_init (); - netfs_root_node = procfs_dir_make_node (entries, NULL); + netfs_root_node = procfs_dir_make_node (entries, NULL, NULL); netfs_startup (bootstrap, 0); for (;;) @@ -1,6 +1,7 @@ #include <stdlib.h> #include <string.h> #include <fcntl.h> +#include <mach.h> #include <hurd/netfs.h> #include <hurd/fshelp.h> #include "procfs.h" @@ -15,6 +16,18 @@ struct netnode size_t contents_len; }; +void +procfs_cleanup_contents_with_free (void *hook, void *cont, size_t len) +{ + free (cont); +} + +void +procfs_cleanup_contents_with_vm_deallocate (void *hook, void *cont, size_t len) +{ + vm_deallocate (mach_task_self (), (vm_address_t) cont, (vm_size_t) len); +} + struct node *procfs_make_node (const struct procfs_node_ops *ops, void *hook) { struct netnode *nn; @@ -85,7 +98,7 @@ error_t procfs_lookup (struct node *np, const char *name, struct node **npp) void procfs_cleanup (struct node *np) { if (np->nn->contents && np->nn->ops->cleanup_contents) - np->nn->ops->cleanup_contents (np->nn->contents); + np->nn->ops->cleanup_contents (np->nn->hook, np->nn->contents, np->nn->contents_len); if (np->nn->ops->cleanup) np->nn->ops->cleanup (np->nn->hook); @@ -18,7 +18,7 @@ struct procfs_node_ops you would expect; for directories, they are an argz vector of the names of the entries. */ error_t (*get_contents) (void *hook, void **contents, size_t *contents_len); - void (*cleanup_contents) (void *contents); + void (*cleanup_contents) (void *hook, void *contents, size_t contents_len); /* Lookup NAME in this directory, and store the result in *np. The returned node should be created by lookup() using procfs_make_node() @@ -29,6 +29,10 @@ struct procfs_node_ops void (*cleanup) (void *hook); }; +/* These helper functions can be used as procfs_node_ops.cleanup_contents. */ +void procfs_cleanup_contents_with_free (void *, void *, size_t); +void procfs_cleanup_contents_with_vm_deallocate (void *, void *, size_t); + /* Create a new node and return it. Returns NULL if it fails to allocate enough memory. In this case, ops->cleanup will be invoked. */ struct node *procfs_make_node (const struct procfs_node_ops *ops, void *hook); diff --git a/procfs_dir.c b/procfs_dir.c index 62a45b1b..b7fb28fa 100644 --- a/procfs_dir.c +++ b/procfs_dir.c @@ -7,6 +7,7 @@ struct procfs_dir_node { const struct procfs_dir_entry *entries; void *hook; + void (*cleanup) (void *hook); }; static error_t @@ -51,23 +52,41 @@ procfs_dir_lookup (void *hook, const char *name, struct node **np) return 0; } +static void +procfs_dir_cleanup (void *hook) +{ + struct procfs_dir_node *dn = hook; + + if (dn->cleanup) + dn->cleanup (dn->hook); + + free (dn); +} + struct node * -procfs_dir_make_node (const struct procfs_dir_entry *entries, void *dir_hook) +procfs_dir_make_node (const struct procfs_dir_entry *entries, + void *dir_hook, void (*cleanup) (void *dir_hook)) { static const struct procfs_node_ops ops = { .get_contents = procfs_dir_get_contents, .lookup = procfs_dir_lookup, - .cleanup_contents = free, - .cleanup = free, + .cleanup_contents = procfs_cleanup_contents_with_free, + .cleanup = procfs_dir_cleanup, }; struct procfs_dir_node *dn; dn = malloc (sizeof *dn); if (! dn) - return NULL; + { + if (cleanup) + cleanup (dir_hook); + + return NULL; + } dn->entries = entries; dn->hook = dir_hook; + dn->cleanup = cleanup; return procfs_make_node (&ops, dn); } diff --git a/procfs_dir.h b/procfs_dir.h index 1ba45ad0..4eb934e0 100644 --- a/procfs_dir.h +++ b/procfs_dir.h @@ -9,7 +9,12 @@ struct procfs_dir_entry }; /* A simple directory is built from a table of entries. The table is - terminated by a null NAME pointer. */ + terminated by a null NAME pointer. The DIR_HOOK is passed the + MAKE_NODE callback function of looked up procfs_dir_entries, and to + the provided CLEANUP function when the directory is destroyed. + Returns the new directory node. If not enough memory can be + allocated, CLEANUP is invoked immediately and NULL is returned. */ struct node * -procfs_dir_make_node (const struct procfs_dir_entry *entries, void *dir_hook); +procfs_dir_make_node (const struct procfs_dir_entry *entries, + void *dir_hook, void (*cleanup) (void *dir_hook)); @@ -59,7 +59,7 @@ proclist_make_node (process_t process) static const struct procfs_node_ops ops = { .get_contents = proclist_get_contents, .lookup = proclist_lookup, - .cleanup_contents = free, + .cleanup_contents = procfs_cleanup_contents_with_free, .cleanup = free, }; struct proclist_node *pl; |