diff options
author | Max Kellermann <max@duempel.org> | 2009-09-24 21:40:07 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-09-24 21:40:07 +0200 |
commit | 06d5d4b03ec446b9eb7a7351c32ef2fdca29d3c8 (patch) | |
tree | ff7a44852afe108b5d7a89de1a9e8a44f7f969fe /src/conf.c | |
parent | f3739a73af02a0152e842f2451358aa7aa962c1e (diff) | |
download | mpd-06d5d4b03ec446b9eb7a7351c32ef2fdca29d3c8.tar.gz mpd-06d5d4b03ec446b9eb7a7351c32ef2fdca29d3c8.tar.xz mpd-06d5d4b03ec446b9eb7a7351c32ef2fdca29d3c8.zip |
conf: handle fatal errors with GError
Don't call g_error(), which will abort the process and dump core.
This patch does not affect all the config_get_X() functions. These
need some more refactoring.
Diffstat (limited to 'src/conf.c')
-rw-r--r-- | src/conf.c | 147 |
1 files changed, 104 insertions, 43 deletions
diff --git a/src/conf.c b/src/conf.c index fe4b39fc3..d78f44760 100644 --- a/src/conf.c +++ b/src/conf.c @@ -221,17 +221,20 @@ void config_global_check(void) } } -void +bool config_add_block_param(struct config_param * param, const char *name, - const char *value, int line) + const char *value, int line, GError **error_r) { struct block_param *bp; bp = config_get_block_param(param, name); - if (bp != NULL) - g_error("\"%s\" first defined on line %i, and " - "redefined on line %i\n", name, - bp->line, line); + if (bp != NULL) { + g_set_error(error_r, config_quark(), 0, + "\"%s\" first defined on line %i, and " + "redefined on line %i\n", name, + bp->line, line); + return false; + } param->num_block_params++; @@ -245,21 +248,28 @@ config_add_block_param(struct config_param * param, const char *name, bp->value = g_strdup(value); bp->line = line; bp->used = false; + + return true; } static struct config_param * -config_read_block(FILE *fp, int *count, char *string) +config_read_block(FILE *fp, int *count, char *string, GError **error_r) { struct config_param *ret = config_new_param(NULL, *count); + GError *error = NULL; + bool success; while (true) { char *line; const char *name, *value; - GError *error = NULL; line = fgets(string, MAX_STRING_SIZE, fp); - if (line == NULL) - g_error("Expected '}' before end-of-file"); + if (line == NULL) { + config_param_free(ret); + g_set_error(error_r, config_quark(), 0, + "Expected '}' before end-of-file"); + return NULL; + } (*count)++; line = g_strchug(line); @@ -271,9 +281,13 @@ config_read_block(FILE *fp, int *count, char *string) (and from this "while" loop) */ line = g_strchug(line + 1); - if (*line != 0 && *line != CONF_COMMENT) - g_error("line %i: Unknown tokens after '}'", - *count); + if (*line != 0 && *line != CONF_COMMENT) { + config_param_free(ret); + g_set_error(error_r, config_quark(), 0, + "line %i: Unknown tokens after '}'", + *count); + return false; + } return ret; } @@ -283,25 +297,44 @@ config_read_block(FILE *fp, int *count, char *string) name = tokenizer_next_word(&line, &error); if (name == NULL) { assert(*line != 0); - g_error("line %i: %s", *count, error->message); + config_param_free(ret); + g_propagate_prefixed_error(error_r, error, + "line %i: ", *count); + return NULL; } value = tokenizer_next_string(&line, &error); if (value == NULL) { + config_param_free(ret); if (*line == 0) - g_error("line %i: Value missing", *count); + g_set_error(error_r, config_quark(), 0, + "line %i: Value missing", *count); else - g_error("line %i: %s", *count, error->message); + g_propagate_prefixed_error(error_r, error, + "line %i: ", + *count); + return NULL; } - if (*line != 0 && *line != CONF_COMMENT) - g_error("line %i: Unknown tokens after value", *count); + if (*line != 0 && *line != CONF_COMMENT) { + config_param_free(ret); + g_set_error(error_r, config_quark(), 0, + "line %i: Unknown tokens after value", + *count); + return NULL; + } - config_add_block_param(ret, name, value, *count); + success = config_add_block_param(ret, name, value, *count, + error_r); + if (!success) { + config_param_free(ret); + return false; + } } } -void config_read_file(const char *file) +bool +config_read_file(const char *file, GError **error_r) { FILE *fp; char string[MAX_STRING_SIZE + 1]; @@ -312,8 +345,10 @@ void config_read_file(const char *file) g_debug("loading file %s", file); if (!(fp = fopen(file, "r"))) { - g_error("problems opening file %s for reading: %s\n", - file, strerror(errno)); + g_set_error(error_r, config_quark(), errno, + "Failed to open %s: %s", + file, strerror(errno)); + return false; } while (fgets(string, MAX_STRING_SIZE, fp)) { @@ -333,22 +368,29 @@ void config_read_file(const char *file) name = tokenizer_next_word(&line, &error); if (name == NULL) { assert(*line != 0); - g_error("line %i: %s", count, error->message); + g_propagate_prefixed_error(error_r, error, + "line %i: ", count); + return false; } /* get the definition of that option, and check the "repeatable" flag */ entry = config_entry_get(name); - if (entry == NULL) - g_error("unrecognized parameter in config file at " - "line %i: %s\n", count, name); + if (entry == NULL) { + g_set_error(error_r, config_quark(), 0, + "unrecognized parameter in config file at " + "line %i: %s\n", count, name); + return false; + } if (entry->params != NULL && !entry->repeatable) { param = entry->params->data; - g_error("config parameter \"%s\" is first defined on " - "line %i and redefined on line %i\n", - name, param->line, count); + g_set_error(error_r, config_quark(), 0, + "config parameter \"%s\" is first defined " + "on line %i and redefined on line %i\n", + name, param->line, count); + return false; } /* now parse the block or the value */ @@ -356,31 +398,48 @@ void config_read_file(const char *file) if (entry->block) { /* it's a block, call config_read_block() */ - if (*line != '{') - g_error("line %i: '{' expected", count); + if (*line != '{') { + g_set_error(error_r, config_quark(), 0, + "line %i: '{' expected", count); + return false; + } line = g_strchug(line + 1); - if (*line != 0 && *line != CONF_COMMENT) - g_error("line %i: Unknown tokens after '{'", - count); + if (*line != 0 && *line != CONF_COMMENT) { + g_set_error(error_r, config_quark(), 0, + "line %i: Unknown tokens after '{'", + count); + return false; + } - param = config_read_block(fp, &count, string); + param = config_read_block(fp, &count, string, error_r); + if (param == NULL) + return false; } else { /* a string value */ value = tokenizer_next_string(&line, &error); if (value == NULL) { if (*line == 0) - g_error("line %i: Value missing", - count); - else - g_error("line %i: %s", count, - error->message); + g_set_error(error_r, config_quark(), 0, + "line %i: Value missing", + count); + else { + g_set_error(error_r, config_quark(), 0, + "line %i: %s", count, + error->message); + g_error_free(error); + } + + return false; } - if (*line != 0 && *line != CONF_COMMENT) - g_error("line %i: Unknown tokens after value", - count); + if (*line != 0 && *line != CONF_COMMENT) { + g_set_error(error_r, config_quark(), 0, + "line %i: Unknown tokens after value", + count); + return false; + } param = config_new_param(value, count); } @@ -388,6 +447,8 @@ void config_read_file(const char *file) entry->params = g_slist_append(entry->params, param); } fclose(fp); + + return true; } struct config_param * |