From 97010c97d26556fd752c86fb2f610ac708415bdb Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Mon, 28 Sep 2009 09:36:00 -0400 Subject: [PATCH] Add config_from_fd() to ini_config --- common/ini/ini_config.c | 124 +++++++++++++++++++++++++++++++++++++++++-- common/ini/ini_config.h | 17 ++++++ common/ini/ini_config_ut.c | 71 +++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 6 deletions(-) diff --git a/common/ini/ini_config.c b/common/ini/ini_config.c index ffc5960..49a07b2 100644 --- a/common/ini/ini_config.c +++ b/common/ini/ini_config.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "config.h" /* For error text */ #include @@ -153,7 +154,8 @@ int read_line(FILE *file, /***************************************************************************/ /* Function to read single ini file and pupulate * the provided collection with subcollcetions from the file */ -static int ini_to_collection(const char *filename, +static int ini_to_collection(int fd, + const char *filename, struct collection_item *ini_config, int error_level, struct collection_item **error_list, @@ -177,7 +179,7 @@ static int ini_to_collection(const char *filename, TRACE_FLOW_STRING("ini_to_collection", "Entry"); /* Open file for reading */ - file = fopen(filename, "r"); + file = fdopen(fd, "r"); if (file == NULL) { error = errno; TRACE_ERROR_NUMBER("Failed to open file - but this is OK", error); @@ -423,6 +425,14 @@ void free_ini_config_lines(struct collection_item *lines) TRACE_FLOW_STRING("free_ini_config_lines", "Exit"); } +static int config_with_lines(const char *application, + int fd, + const char *config_file, + struct collection_item **ini_config, + int error_level, + struct collection_item **error_list, + struct collection_item **lines); + /* Read configuration information from a file */ int config_from_file(const char *application, const char *config_file, @@ -443,6 +453,26 @@ int config_from_file(const char *application, return error; } +/* Read configuration information from a file descriptor */ +int config_from_fd(const char *application, + int fd, + struct collection_item **ini_config, + int error_level, + struct collection_item **error_list) +{ + int error; + + TRACE_FLOW_STRING("config_from_fd", "Entry"); + error = config_from_fd_with_lines(application, + fd, + ini_config, + error_level, + error_list, + NULL); + TRACE_FLOW_NUMBER("config_from_fd. Returns", error); + return error; +} + /* Function to read the ini file and have a collection * of which item appers on which line */ @@ -453,6 +483,71 @@ int config_from_file_with_lines(const char *application, struct collection_item **error_list, struct collection_item **lines) { + int fd = -1; + int error = 0; + + TRACE_FLOW_STRING("config_from_fd", "Entry"); + + fd = open(config_file, O_RDONLY); + if(fd < 0) { + error = errno; + TRACE_FLOW_NUMBER("config_from_file_with_lines. Returns", error); + return error; + } + error = config_with_lines(application, fd, config_file, + ini_config, error_level, + error_list, lines); + TRACE_FLOW_NUMBER("config_from_file_with_lines. Returns", error); + return error; +} + +/* Function to read the ini file and have a collection + * of which item appers on which line + */ +int config_from_fd_with_lines(const char *application, + int fd, + struct collection_item **ini_config, + int error_level, + struct collection_item **error_list, + struct collection_item **lines) +{ + char *filename; + int size; + int error; + + TRACE_FLOW_STRING("config_from_fd_with_lines", "Entry"); + + filename = malloc(sizeof(char) * 13); + if(!filename) { + TRACE_FLOW_NUMBER("config_from_fd_with_lines. Returns", ENOMEM); + return ENOMEM; + } + + size = snprintf(filename, 13, "dummy_%d", fd); + if ((size < 0) || size >= 13) + { + free(filename); + TRACE_FLOW_NUMBER("config_from_fd_with_lines. Returns", EIO); + return EIO; + } + + error = config_with_lines(application, fd, filename, + ini_config, error_level, + error_list, lines); + TRACE_FLOW_NUMBER("config_from_fd_with_lines. Returns", error); + + free(filename); + return error; +} + +static int config_with_lines(const char *application, + int fd, + const char *config_file, + struct collection_item **ini_config, + int error_level, + struct collection_item **error_list, + struct collection_item **lines) +{ int error; int created = 0; int created_lines = 0; @@ -511,7 +606,7 @@ int config_from_file_with_lines(const char *application, } /* Do the actual work */ - error = ini_to_collection(config_file, *ini_config, + error = ini_to_collection(fd, config_file, *ini_config, error_level, error_list, lines); /* In case of error when we created collection - delete it */ if (error && created) { @@ -537,6 +632,7 @@ int config_for_app(const char *application, int error_level, struct collection_item **error_set) { + int fd = -1; int error = EOK; char *file_name; struct collection_item *error_list_common = NULL; @@ -605,8 +701,18 @@ int config_for_app(const char *application, /* Read master file */ if (config_file != NULL) { TRACE_INFO_STRING("Reading master file:", config_file); - error = ini_to_collection(config_file, *ini_config, - error_level, pass_common, NULL); + fd = open(config_file, O_RDONLY); + if (fd < 0) { + error = errno; + if(created) { + col_destroy_collection(*ini_config); + *ini_config = NULL; + } + } + else { + error = ini_to_collection(fd, config_file, *ini_config, + error_level, pass_common, NULL); + } tried++; /* ENOENT and EOK are Ok */ if (error) { @@ -665,7 +771,13 @@ int config_for_app(const char *application, TRACE_INFO_STRING("Opening file:", file_name); /* Read master file */ - error = ini_to_collection(file_name, *ini_config, + fd = open(file_name, O_RDONLY); + if (fd < 0) { + error = errno; + TRACE_ERROR_NUMBER("Failed to read specific application file", error); + return error; + } + error = ini_to_collection(fd, file_name, *ini_config, error_level, pass_specific, NULL); tried++; free(file_name); diff --git a/common/ini/ini_config.h b/common/ini/ini_config.h index 1fee48a..7e64214 100644 --- a/common/ini/ini_config.h +++ b/common/ini/ini_config.h @@ -103,6 +103,13 @@ int config_from_file(const char *application, /* Name of the appli int error_level, /* Error level - break for errors, warnings or best effort (don't break) */ struct collection_item **error_list); /* List of errors for a file */ +/* Read configuration information from a file descriptor */ +int config_from_fd(const char *application, /* Name of the application - will be used as name of the collection */ + int fd, /* Previously opened file descriptor for the config file */ + struct collection_item **ini_config, /* If *ini_config is NULL a new ini object will be allocated*/ + int error_level, /* Error level - break for errors, warnings or best effort (don't break) */ + struct collection_item **error_list); /* List of errors for a file */ + /* Read configuration information from a file with extra collection of line numbers */ int config_from_file_with_lines( @@ -114,6 +121,16 @@ int config_from_file_with_lines( struct collection_item **error_list, /* List of errors for a file */ struct collection_item **lines); /* Collection of pairs where key is the key and value is line number */ +/* Read configuration information from a file descriptor with extra collection of line numbers */ +int config_from_fd_with_lines( + const char *application, /* Name of the application - will be used as name of the collection */ + int fd, /* Previously opened file descriptor for the config file */ + struct collection_item **ini_config, /* If *ini_config is NULL a new ini object will be allocated, */ + /* otherwise the one that is pointed to will be updated. */ + int error_level, /* Error level - break for errors, warnings or best effort (don't break) */ + struct collection_item **error_list, /* List of errors for a file */ + struct collection_item **lines); /* Collection of pairs where key is the key and value is line number */ + /* Read default config file and then overwrite it with a specific one from the directory */ int config_for_app(const char *application, /* Name of the application that will be used to get config for */ diff --git a/common/ini/ini_config_ut.c b/common/ini/ini_config_ut.c index 6fbade6..025ecf1 100644 --- a/common/ini/ini_config_ut.c +++ b/common/ini/ini_config_ut.c @@ -23,6 +23,7 @@ #include #include #include +#include #define TRACE_HOME #include "ini_config.h" #include "collection.h" @@ -133,6 +134,75 @@ int single_file(void) return 0; } +int single_fd(void) +{ + int error; + struct collection_item *ini_config = NULL; + struct collection_item *error_set = NULL; + struct collection_item *lines = NULL; + + int fd = open("./ini.conf", O_RDONLY); + if (fd < 0) { + error = errno; + printf("Attempt to read configuration returned error: %d\n", error); + return error; + } + + error = config_from_fd("test", fd, &ini_config, INI_STOP_ON_NONE, &error_set); + if (error) { + printf("Attempt to read configuration returned error: %d\n",error); + return error; + } + + col_debug_collection(ini_config, COL_TRAVERSE_DEFAULT); + col_print_collection(ini_config); + col_print_collection(error_set); + + printf("\n\n----------------------\n"); + /* Output parsing errors (if any) */ + print_file_parsing_errors(stdout, error_set); + printf("----------------------\n\n\n"); + + + free_ini_config(ini_config); + free_ini_config_errors(error_set); + close(fd); + + ini_config = NULL; + error_set = NULL; + + printf("TEST WITH LINES\n"); + + fd = open("./ini.conf", O_RDONLY); + if (fd < 0) { + error = errno; + printf("Attempt to read configuration returned error: %d\n", error); + return error; + } + error = config_from_fd_with_lines("test", fd, &ini_config, + INI_STOP_ON_NONE, + &error_set, &lines); + if (error) { + printf("Attempt to read configuration returned error: %d\n",error); + return error; + } + + col_debug_collection(ini_config, COL_TRAVERSE_DEFAULT); + col_debug_collection(lines, COL_TRAVERSE_DEFAULT); + + printf("\n\n----------------------\n"); + /* Output parsing errors (if any) */ + print_file_parsing_errors(stdout, error_set); + printf("----------------------\n\n\n"); + + + free_ini_config(ini_config); + free_ini_config_errors(error_set); + free_ini_config_lines(lines); + + return 0; +} + int negative_test(void) { int error; @@ -828,6 +898,7 @@ int main(int argc, char *argv[]) if ((error = basic_test()) || (error = single_file()) || + (error = single_fd()) || (error = real_test(NULL)) || /* This should result in merged configuration */ (error = real_test("./ini.conf")) || -- 1.6.2.5