[augeas-devel] augeas: master - Handle allocation failures from define_native_intl

David Lutterkort lutter at fedoraproject.org
Thu Oct 1 00:23:15 UTC 2009


Gitweb:        http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=de5176539277cb7513cddf2ada51c9683555f29f
Commit:        de5176539277cb7513cddf2ada51c9683555f29f
Parent:        e5e7ee7ab6c88cb3e2a6ae4409f4ae4c1d5f4bd7
Author:        David Lutterkort <lutter at redhat.com>
AuthorDate:    Sun Feb 1 21:30:50 2009 -0800
Committer:     David Lutterkort <lutter at redhat.com>
CommitterDate: Wed Sep 30 12:10:55 2009 -0700

Handle allocation failures from define_native_intl

---
 src/builtin.c |   50 ++++++++++++++++++++++++++++++--------------------
 src/syntax.c  |   39 ++++++++++++++++++++++++++++++---------
 src/syntax.h  |    7 ++++---
 3 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/src/builtin.c b/src/builtin.c
index e066aba..c9698b0 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -429,39 +429,49 @@ static struct value *sys_read_file(struct info *info, struct value *n) {
 
 struct module *builtin_init(void) {
     struct module *modl = module_create("Builtin");
-    define_native(modl, "gensym", 1, gensym, T_STRING, T_STRING);
+    int r;
+
+#define DEFINE_NATIVE(modl, name, nargs, impl, types ...)               \
+    r = define_native(modl, name, nargs, impl, ##types);                \
+    if (r < 0) goto error;
+
+    DEFINE_NATIVE(modl, "gensym", 1, gensym, T_STRING, T_STRING);
+
     /* Primitive lenses */
-    define_native(modl, "del",     2, lns_del, T_REGEXP, T_STRING, T_LENS);
-    define_native(modl, "store",   1, lns_store, T_REGEXP, T_LENS);
-    define_native(modl, "key",     1, lns_key, T_REGEXP, T_LENS);
-    define_native(modl, "label",   1, lns_label, T_STRING, T_LENS);
-    define_native(modl, "seq",     1, lns_seq, T_STRING, T_LENS);
-    define_native(modl, "counter", 1, lns_counter, T_STRING, T_LENS);
+    DEFINE_NATIVE(modl, "del",     2, lns_del, T_REGEXP, T_STRING, T_LENS);
+    DEFINE_NATIVE(modl, "store",   1, lns_store, T_REGEXP, T_LENS);
+    DEFINE_NATIVE(modl, "key",     1, lns_key, T_REGEXP, T_LENS);
+    DEFINE_NATIVE(modl, "label",   1, lns_label, T_STRING, T_LENS);
+    DEFINE_NATIVE(modl, "seq",     1, lns_seq, T_STRING, T_LENS);
+    DEFINE_NATIVE(modl, "counter", 1, lns_counter, T_STRING, T_LENS);
     /* Applying lenses (mostly for tests) */
-    define_native(modl, "get",     2, lens_get, T_LENS, T_STRING, T_TREE);
-    define_native(modl, "put",     3, lens_put, T_LENS, T_TREE, T_STRING,
-                                               T_STRING);
+    DEFINE_NATIVE(modl, "get",     2, lens_get, T_LENS, T_STRING, T_TREE);
+    DEFINE_NATIVE(modl, "put",     3, lens_put, T_LENS, T_TREE, T_STRING,
+                  T_STRING);
     /* Tree manipulation used by the PUT tests */
-    define_native(modl, "set", 3, tree_set_glue, T_STRING, T_STRING, T_TREE,
+    DEFINE_NATIVE(modl, "set", 3, tree_set_glue, T_STRING, T_STRING, T_TREE,
                                                  T_TREE);
-    define_native(modl, "clear", 2, tree_clear_glue, T_STRING, T_TREE,
+    DEFINE_NATIVE(modl, "clear", 2, tree_clear_glue, T_STRING, T_TREE,
                                                  T_TREE);
-    define_native(modl, "rm", 2, tree_rm_glue, T_STRING, T_TREE, T_TREE);
-    define_native(modl, "insa", 3, tree_insa_glue, T_STRING, T_STRING, T_TREE,
+    DEFINE_NATIVE(modl, "rm", 2, tree_rm_glue, T_STRING, T_TREE, T_TREE);
+    DEFINE_NATIVE(modl, "insa", 3, tree_insa_glue, T_STRING, T_STRING, T_TREE,
                                                    T_TREE);
-    define_native(modl, "insb", 3, tree_insb_glue, T_STRING, T_STRING, T_TREE,
+    DEFINE_NATIVE(modl, "insb", 3, tree_insb_glue, T_STRING, T_STRING, T_TREE,
                                                    T_TREE);
     /* Transforms and filters */
-    define_native(modl, "incl", 1, xform_incl, T_STRING, T_FILTER);
-    define_native(modl, "excl", 1, xform_excl, T_STRING, T_FILTER);
-    define_native(modl, "transform", 2, xform_transform, T_LENS, T_FILTER,
+    DEFINE_NATIVE(modl, "incl", 1, xform_incl, T_STRING, T_FILTER);
+    DEFINE_NATIVE(modl, "excl", 1, xform_excl, T_STRING, T_FILTER);
+    DEFINE_NATIVE(modl, "transform", 2, xform_transform, T_LENS, T_FILTER,
                                                          T_TRANSFORM);
     /* System functions */
     struct module *sys = module_create("Sys");
     modl->next = sys;
-    define_native(sys, "getenv", 1, sys_getenv, T_STRING, T_STRING);
-    define_native(sys, "read_file", 1, sys_read_file, T_STRING, T_STRING);
+    DEFINE_NATIVE(sys, "getenv", 1, sys_getenv, T_STRING, T_STRING);
+    DEFINE_NATIVE(sys, "read_file", 1, sys_read_file, T_STRING, T_STRING);
     return modl;
+ error:
+    unref(modl, module);
+    return NULL;
 }
 
 /*
diff --git a/src/syntax.c b/src/syntax.c
index 3f06c05..a429c75 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -245,7 +245,8 @@ void free_value(struct value *v) {
         unref(v->transform, transform);
         break;
     case V_NATIVE:
-        unref(v->native->type, type);
+        if (v->native)
+            unref(v->native->type, type);
         free(v->native);
         break;
     case V_CLOS:
@@ -1709,17 +1710,18 @@ static struct info *make_native_info(const char *fname, int line) {
     return info;
 }
 
-void define_native_intl(const char *file, int line,
-                        struct module *module, const char *name,
-                        int argc, void *impl, ...) {
+int define_native_intl(const char *file, int line,
+                       struct module *module, const char *name,
+                       int argc, void *impl, ...) {
     assert(argc > 0);  /* We have no unit type */
     assert(argc <= 5);
     va_list ap;
     enum type_tag tag;
-    struct term *params = NULL, *body;
+    struct term *params = NULL, *body = NULL, *func = NULL;
     struct type *type;
-    struct value *v;
+    struct value *v = NULL;
     struct info *info = make_native_info(file, line);
+    struct ctx ctx;
 
     va_start(ap, impl);
     for (int i=0; i < argc; i++) {
@@ -1737,22 +1739,31 @@ void define_native_intl(const char *file, int line,
     type = make_base_type(tag);
 
     make_ref(v);
+    if (v == NULL)
+        goto error;
     v->tag = V_NATIVE;
     v->info = info;
 
-    CALLOC(v->native, 1);
+    if (ALLOC(v->native) < 0)
+        goto error;
     v->native->argc = argc;
     v->native->type = type;
     v->native->impl = impl;
 
     make_ref(body);
+    if (body == NULL)
+        goto error;
     body->info = ref(info);
     body->type = ref(type);
     body->tag = A_VALUE;
     body->value = v;
+    v = NULL;
+
+    func = build_func(params, body);
+    if (func == NULL)
+        goto error;
+    body = NULL;
 
-    struct term *func = build_func(params, body);
-    struct ctx ctx;
     ctx.aug = NULL;
     ctx.local = ref(module->bindings);
     ctx.name = module->name;
@@ -1762,12 +1773,22 @@ void define_native_intl(const char *file, int line,
         abort();
     }
     v = make_closure(func, ctx.local);
+    if (v == NULL) {
+        unref(module->bindings, binding);
+        goto error;
+    }
     bind(&ctx.local, name, func->type, v);
     unref(v, value);
     unref(func, term);
     unref(module->bindings, binding);
 
     module->bindings = ctx.local;
+    return 0;
+ error:
+    unref(v, value);
+    unref(body, term);
+    unref(func, term);
+    return -1;
 }
 
 
diff --git a/src/syntax.h b/src/syntax.h
index f0c21a2..4d805ae 100644
--- a/src/syntax.h
+++ b/src/syntax.h
@@ -255,9 +255,10 @@ struct module *module_create(const char *name);
 #define define_native(module, name, argc, impl, types ...)       \
     define_native_intl(__FILE__, __LINE__, module, name, argc, impl, ## types)
 
-void define_native_intl(const char *fname, int line,
-                        struct module *module, const char *name,
-                        int argc, void *impl, ...);
+ATTRIBUTE_RETURN_CHECK
+int define_native_intl(const char *fname, int line,
+                       struct module *module, const char *name,
+                       int argc, void *impl, ...);
 
 struct module *builtin_init(void);
 




More information about the augeas-devel mailing list