From fe0f4bf35b9378854a8a709d6067800495d3e845 Mon Sep 17 00:00:00 2001 From: Robert Spalek Date: Sun, 23 Apr 2006 14:14:21 +0200 Subject: [PATCH] conf2: bugfixes in journaling - commented usage of cf_malloc() vs. xmalloc() in init-hooks - commented buggy DYN_ALLOC(double) macro - don't bzero() static sections - use bopen_safe() --- lib/conf2-test.c | 15 +++++++++++---- lib/conf2.c | 40 +++++++++++++++++++++++++++++----------- lib/conf2.h | 6 ++++-- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/lib/conf2-test.c b/lib/conf2-test.c index 99b9b0a8..670190c3 100644 --- a/lib/conf2-test.c +++ b/lib/conf2-test.c @@ -24,9 +24,15 @@ struct sub_sect_1 { double *list; }; +static struct sub_sect_1 sec1 = { {}, "Charlie", "WBAFC", { 0, -1}, DYN_ALLOC(double, 3, 1e4, -1e-4, 8) }; + static byte * init_sec_1(struct sub_sect_1 *s) { + if (s == &sec1) { // this is a static variable; skip clearing + DYN_LEN(sec1.list) = 3; // XXX: fix for the bug in DYN_ALLOC() + return NULL; + } s->name = "unknown"; s->level = "default"; s->confidence[0] = 5; @@ -65,7 +71,6 @@ static byte *str1 = "no worries"; static byte **str2 = DYN_ALLOC(byte *, 2, "Alice", "Bob"); static u64 u1 = 0xCafeBeefDeadC00ll; static double d1 = -1.1; -static struct sub_sect_1 sec1 = { {}, "Charlie", "WBAFC", { 0, -1} }; static struct clist secs; static time_t t1, t2; static u32 ip; @@ -75,8 +80,8 @@ init_top(void *ptr UNUSED) { for (uns i=0; i<5; i++) { - struct sub_sect_1 *s = cf_malloc(sizeof(struct sub_sect_1)); - cf_init_section("slaves", &cf_sec_1, s); + struct sub_sect_1 *s = xmalloc(sizeof(struct sub_sect_1)); // XXX: cannot by cf_malloc(), because it's deleted when cf_reload()'ed + cf_init_section("slaves", &cf_sec_1, s, 1); s->confidence[1] = i; clist_add_tail(&secs, &s->n); } @@ -99,7 +104,7 @@ time_parser(uns number, byte **pars, time_t *ptr) } static struct cf_section cf_top = { - CF_COMMIT(init_top), + CF_INIT(init_top), CF_COMMIT(commit_top), CF_ITEMS { CF_UNS("nr1", &nr1), @@ -156,6 +161,8 @@ main(int argc, char *argv[]) if (optind < argc) usage(); + //cf_reload("non-existent file"); + struct fastbuf *out = bfdopen(1, 1<<14); cf_dump_sections(out); bclose(out); diff --git a/lib/conf2.c b/lib/conf2.c index 43529e38..6b470ef5 100644 --- a/lib/conf2.c +++ b/lib/conf2.c @@ -14,6 +14,7 @@ #include "lib/clists.h" #include "lib/fastbuf.h" #include "lib/chartype.h" +#include "lib/lfs.h" #include #include @@ -209,13 +210,15 @@ cf_declare_section(byte *name, struct cf_section *sec, uns allow_unknown) } void -cf_init_section(byte *name, struct cf_section *sec, void *ptr) +cf_init_section(byte *name, struct cf_section *sec, void *ptr, uns do_bzero) { - if (sec->size) + if (do_bzero) { + ASSERT(sec->size); bzero(ptr, sec->size); + } for (uns i=0; sec->cfg[i].cls; i++) if (sec->cfg[i].cls == CC_SECTION) - cf_init_section(sec->cfg[i].name, sec->cfg[i].u.sec, ptr + (addr_int_t) sec->cfg[i].ptr); + cf_init_section(sec->cfg[i].name, sec->cfg[i].u.sec, ptr + (addr_int_t) sec->cfg[i].ptr, 0); else if (sec->cfg[i].cls == CC_LIST) clist_init(sec->cfg[i].ptr); if (sec->init) { @@ -233,7 +236,7 @@ global_init(void) return; sections.flags |= SEC_FLAG_UNKNOWN; sections.size = 0; // size of allocated array used to be stored here - cf_init_section("top-level", §ions, NULL); + cf_init_section("top-level", §ions, NULL, 0); } static int @@ -648,7 +651,7 @@ interpret_add_list(struct cf_item *item, int number, byte **pars, int *processed while (number > 0) { void *node = cf_malloc(sec->size); - cf_init_section(item->name, sec, node); + cf_init_section(item->name, sec, node, 1); add_to_list(ptr, node, op); int taken; /* If the node contains any dynamic attribute at the end, we suppress @@ -800,7 +803,7 @@ opening_brace(struct cf_item *item, void *ptr, enum operation op) else if (item->cls == CC_LIST) { stack[level].base_ptr = cf_malloc(item->u.sec->size); - cf_init_section(item->name, item->u.sec, stack[level].base_ptr); + cf_init_section(item->name, item->u.sec, stack[level].base_ptr, 1); stack[level].list = ptr; stack[level].item = item; stack[level].op |= (op & OP_MASK) < OP_REMOVE ? OP_2ND : OP_1ST; @@ -831,7 +834,7 @@ closing_brace(struct item_stack *st, enum operation op, int number, byte **pars) if (pure_op == OP_EDIT) st->base_ptr = st->list; else if (pure_op == OP_AFTER || pure_op == OP_BEFORE) - cf_init_section(st->item->name, st->sec, st->base_ptr); + cf_init_section(st->item->name, st->sec, st->base_ptr, 1); else ASSERT(0); if (op & OP_OPEN) { // stay at the same recursion level @@ -1127,6 +1130,17 @@ split_command(void) /* Parsing multiple files */ +static struct fastbuf * +bopen_safe(byte *name) +{ + int fd = sh_open(name, O_RDONLY); + if (fd < 0) { + log(L_ERROR, "Cannot open %s", name); + return NULL; + } + return bopen(name, O_RDONLY, 1<<14); +} + static byte * parse_fastbuf(byte *name_fb, struct fastbuf *fb, uns depth) { @@ -1156,7 +1170,11 @@ parse_fastbuf(byte *name_fb, struct fastbuf *fb, uns depth) msg = "Too many nested files"; goto error; } - struct fastbuf *new_fb = bopen(pars[0], O_RDONLY, 1<<14); + struct fastbuf *new_fb = bopen_safe(pars[0]); + if (!new_fb) { + msg = "Cannot open file"; + goto error; + } uns ll = line_num; msg = parse_fastbuf(pars[0], new_fb, depth+1); bclose(new_fb); @@ -1206,7 +1224,9 @@ static int load_file(byte *file) { init_stack(); - struct fastbuf *fb = bopen(file, O_RDONLY, 1<<14); + struct fastbuf *fb = bopen_safe(file); + if (!fb) + return 1; byte *msg = parse_fastbuf(file, fb, 0); bclose(fb); int err = !!msg || done_stack(); @@ -1264,8 +1284,6 @@ cf_get_opt(int argc, char * const argv[], const char *short_opts, const struct o /* Debug dumping */ -#include "fastbuf.h" - static void spaces(struct fastbuf *fb, uns nr) { diff --git a/lib/conf2.h b/lib/conf2.h index 0455ec1a..528a6b84 100644 --- a/lib/conf2.h +++ b/lib/conf2.h @@ -39,7 +39,8 @@ typedef byte *cf_hook(void *ptr); * dynamically allocated nodes of link lists or for filling global variables * that are run-time dependent). The commit-hook should perform sanity * checks and postprocess the parsed values. Commit-hooks must call - * cf_journal_block() too. */ + * cf_journal_block() too. Caveat! init-hooks for static sections must not + * use cf_malloc() but normal xmalloc(). */ struct cf_section; struct cf_item { @@ -99,6 +100,7 @@ struct clist; // length of a dynamic array #define DYN_ALLOC(type,len,val...) (type[]) { (type)len, ##val } + 1 // creates a static instance of a dynamic array + // FIXME: overcast doesn't work for the double type /* Memory allocation */ struct mempool; @@ -114,7 +116,7 @@ void cf_journal_block(void *ptr, uns len); /* Declaration */ void cf_declare_section(byte *name, struct cf_section *sec, uns allow_unknown); -void cf_init_section(byte *name, struct cf_section *sec, void *ptr); +void cf_init_section(byte *name, struct cf_section *sec, void *ptr, uns do_bzero); /* Safe reloading and loading of configuration files */ extern byte *cf_def_file; -- 2.39.2