From ac75e3648e6a9c3a8cf45d5fa491abd3a3ab3613 Mon Sep 17 00:00:00 2001
From: Jeremie Koenig <jk@jk.fr.eu.org>
Date: Tue, 17 Aug 2010 16:48:55 +0000
Subject: Fix the failure semantics of procfs_make_node

* procfs.c (procfs_make_node): Invoke the cleanup callback on
  failure, so that callers don't have to.
* procfs.h: Document the change.
* procfs_dir.c (procfs_dir_make_node), procfs_file.c
  (procfs_file_make_node), proclist.c (proclist_make_node):
  Update to reflect the change.
---
 procfs.c      | 14 +++++++++-----
 procfs.h      |  2 ++
 procfs_dir.c  |  7 +------
 procfs_file.c |  7 +------
 proclist.c    |  7 +------
 5 files changed, 14 insertions(+), 23 deletions(-)

diff --git a/procfs.c b/procfs.c
index 304befba..0c57686b 100644
--- a/procfs.c
+++ b/procfs.c
@@ -22,7 +22,7 @@ struct node *procfs_make_node (const struct procfs_node_ops *ops, void *hook)
  
   nn = malloc (sizeof *nn);
   if (! nn)
-    return NULL;
+    goto fail;
 
   memset (nn, 0, sizeof *nn);
   nn->ops = ops;
@@ -30,10 +30,7 @@ struct node *procfs_make_node (const struct procfs_node_ops *ops, void *hook)
 
   np = netfs_make_node (nn);
   if (! np)
-    {
-      free (nn);
-      return NULL;
-    }
+    goto fail;
 
   np->nn = nn;
   memset (&np->nn_stat, 0, sizeof np->nn_stat);
@@ -45,6 +42,13 @@ struct node *procfs_make_node (const struct procfs_node_ops *ops, void *hook)
     np->nn_stat.st_mode = S_IFREG | 0444;
 
   return np;
+
+fail:
+  if (ops->cleanup)
+    ops->cleanup (hook);
+
+  free (nn);
+  return NULL;
 }
 
 error_t procfs_get_contents (struct node *np, void **data, size_t *data_len)
diff --git a/procfs.h b/procfs.h
index 0557b6d1..21b0f93d 100644
--- a/procfs.h
+++ b/procfs.h
@@ -29,6 +29,8 @@ struct procfs_node_ops
   void (*cleanup) (void *hook);
 };
 
+/* 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 4d4faa28..62a45b1b 100644
--- a/procfs_dir.c
+++ b/procfs_dir.c
@@ -61,7 +61,6 @@ procfs_dir_make_node (const struct procfs_dir_entry *entries, void *dir_hook)
     .cleanup = free,
   };
   struct procfs_dir_node *dn;
-  struct node *np;
 
   dn = malloc (sizeof *dn);
   if (! dn)
@@ -70,10 +69,6 @@ procfs_dir_make_node (const struct procfs_dir_entry *entries, void *dir_hook)
   dn->entries = entries;
   dn->hook = dir_hook;
 
-  np = procfs_make_node (&ops, dn);
-  if (! np)
-    free (dn);
-
-  return np;
+  return procfs_make_node (&ops, dn);
 }
 
diff --git a/procfs_file.c b/procfs_file.c
index 62419ee5..cb0488e9 100644
--- a/procfs_file.c
+++ b/procfs_file.c
@@ -40,7 +40,6 @@ procfs_file_make_node (void *contents, ssize_t len, void (*cleanup)(void *))
     .cleanup = procfs_file_cleanup,
   };
   struct procfs_file *f;
-  struct node *np;
 
   f = malloc (sizeof *f);
   if (! f)
@@ -50,10 +49,6 @@ procfs_file_make_node (void *contents, ssize_t len, void (*cleanup)(void *))
   f->len = (len >= 0) ? len : strlen (f->contents);
   f->cleanup = cleanup;
 
-  np = procfs_make_node (&ops, f);
-  if (! np)
-    free (f);
-
-  return np;
+  return procfs_make_node (&ops, f);
 }
 
diff --git a/proclist.c b/proclist.c
index 4dd6ab31..16cef9d6 100644
--- a/proclist.c
+++ b/proclist.c
@@ -63,7 +63,6 @@ proclist_make_node (process_t process)
     .cleanup = free,
   };
   struct proclist_node *pl;
-  struct node *np;
 
   pl = malloc (sizeof *pl);
   if (! pl)
@@ -72,10 +71,6 @@ proclist_make_node (process_t process)
   memset (pl, 0, sizeof *pl);
   pl->process = process;
 
-  np = procfs_make_node (&ops, pl);
-  if (! np)
-    free (pl);
-
-  return np;
+  return procfs_make_node (&ops, pl);
 }
 
-- 
cgit v1.2.3