diff options
author | Jeremie Koenig <jk@jk.fr.eu.org> | 2010-08-23 11:54:10 +0000 |
---|---|---|
committer | Jeremie Koenig <jk@jk.fr.eu.org> | 2010-08-30 14:31:31 +0200 |
commit | 4646c4a3ef6171a0ddec4fcfe0c6aa34b50501cd (patch) | |
tree | 6b84772adf6f4c45c852dfc051b94995864caa86 /dircat.c | |
parent | 6e202c432e2f16dfa83a7dc21b759c03623fa394 (diff) |
Improve the interface for dircat_make_node
* dircat.c, dircat.h (dircat_make_node): Use an explicit
array size for DIRS, fail with ENOMEM is any of them is NULL, and
release the reference on the non-NULL nodes on any error.
* main.c (root_make_node): Use the new interface.
Diffstat (limited to 'dircat.c')
-rw-r--r-- | dircat.c | 37 |
1 files changed, 23 insertions, 14 deletions
@@ -4,7 +4,8 @@ struct dircat_node { - struct node **dirs; + int num_dirs; + struct node *dirs[0]; }; static error_t @@ -17,7 +18,7 @@ dircat_get_contents (void *hook, char **contents, ssize_t *contents_len) pos = 0; *contents = malloc (sz = 512); - for (i=0; dcn->dirs[i]; i++) + for (i=0; i < dcn->num_dirs; i++) { char *subcon; ssize_t sublen; @@ -49,19 +50,20 @@ dircat_lookup (void *hook, const char *name, struct node **np) int i; err = ENOENT; - for (i=0; err && dcn->dirs[i]; i++) + for (i=0; err && i < dcn->num_dirs; i++) err = procfs_lookup (dcn->dirs[i], name, np); return err; } static void -dircat_release_dirs (struct node **dirs) +dircat_release_dirs (struct node *const *dirs, int num_dirs) { int i; - for (i=0; dirs[i]; i++) - netfs_nrele (dirs[i]); + for (i=0; i < num_dirs; i++) + if (dirs[i]) + netfs_nrele (dirs[i]); } static void @@ -69,12 +71,12 @@ dircat_cleanup (void *hook) { struct dircat_node *dcn = hook; - dircat_release_dirs (dcn->dirs); + dircat_release_dirs (dcn->dirs, dcn->num_dirs); free (dcn); } struct node * -dircat_make_node (struct node **dirs) +dircat_make_node (struct node *const *dirs, int num_dirs) { static struct procfs_node_ops ops = { .get_contents = dircat_get_contents, @@ -85,15 +87,22 @@ dircat_make_node (struct node **dirs) .enable_refresh_hack_and_break_readdir = 1, }; struct dircat_node *dcn; + int i; + + for (i=0; i < num_dirs; i++) + if (! dirs[i]) + goto fail; - dcn = malloc (sizeof *dcn); + dcn = malloc (sizeof *dcn + num_dirs * sizeof dcn->dirs[0]); if (! dcn) - { - dircat_release_dirs (dirs); - return NULL; - } + goto fail; - dcn->dirs = dirs; + dcn->num_dirs = num_dirs; + memcpy (dcn->dirs, dirs, num_dirs * sizeof dcn->dirs[0]); return procfs_make_node (&ops, dcn); + +fail: + dircat_release_dirs (dirs, num_dirs); + return NULL; } |