diff --git a/runtime/src/module.c b/runtime/src/module.c index a57d9c2..0e896d5 100644 --- a/runtime/src/module.c +++ b/runtime/src/module.c @@ -217,17 +217,14 @@ err: } /** - * Parses a JSON file and allocates one or more new modules - * @param file_name The path of the JSON file - * @return RC 0 on Success. -1 on Error + * Allocates a buffer in memory containing the entire contents of the file provided + * @param file_name file to load into memory + * @param ret_ptr Pointer to set with address of buffer this function allocates. The caller must free this! + * @return size of the allocated buffer or -1 in case of error; */ -int -module_alloc_from_json(char *file_name) +static inline size_t +load_file_into_buffer(char *file_name, char **file_buffer) { - assert(file_name != NULL); - int return_code = -1; - jsmntok_t tokens[JSON_MAX_ELEMENT_SIZE * JSON_MAX_ELEMENT_COUNT]; - /* Use stat to get file attributes and make sure file is present and not empty */ struct stat stat_buffer; if (stat(file_name, &stat_buffer) < 0) { @@ -251,16 +248,16 @@ module_alloc_from_json(char *file_name) } /* Initialize a Buffer */ - char *file_buffer = calloc(1, stat_buffer.st_size); - if (file_buffer == NULL) { + *file_buffer = calloc(1, stat_buffer.st_size); + if (*file_buffer == NULL) { fprintf(stderr, "Attempt to allocate file buffer failed: %s\n", strerror(errno)); goto stat_buffer_alloc_err; } /* Read the file into the buffer and check that the buffer size equals the file size */ - int total_chars_read = fread(file_buffer, sizeof(char), stat_buffer.st_size, module_file); + ssize_t total_chars_read = fread(*file_buffer, sizeof(char), stat_buffer.st_size, module_file); #ifdef LOG_MODULE_LOADING - debuglog("size read: %d content: %s\n", total_chars_read, file_buffer); + debuglog("size read: %d content: %s\n", total_chars_read, *file_buffer); #endif if (total_chars_read != stat_buffer.st_size) { fprintf(stderr, "Attempt to read %s into buffer failed: %s\n", file_name, strerror(errno)); @@ -275,6 +272,39 @@ module_alloc_from_json(char *file_name) }; module_file = NULL; + return total_chars_read; + +fclose_err: + /* We will retry fclose when we fall through into stat_buffer_alloc_err */ +fread_err: + free(*file_buffer); +stat_buffer_alloc_err: + // Check to ensure we haven't already close this + if (module_file != NULL) { + if (fclose(module_file) == EOF) panic("Failed to close file\n"); + } +err: + return (ssize_t)-1; +} + +/** + * Parses a JSON file and allocates one or more new modules + * @param file_name The path of the JSON file + * @return RC 0 on Success. -1 on Error + */ +int +module_alloc_from_json(char *file_name) +{ + assert(file_name != NULL); + + int return_code = -1; + jsmntok_t tokens[JSON_MAX_ELEMENT_SIZE * JSON_MAX_ELEMENT_COUNT]; + + /* Load file_name into memory */ + char *file_buffer = NULL; + ssize_t total_chars_read = load_file_into_buffer(file_name, &file_buffer); + if (total_chars_read <= 0) goto module_alloc_err; + /* Initialize the Jasmine Parser and an array to hold the tokens */ jsmn_parser module_parser; jsmn_init(&module_parser); @@ -432,15 +462,8 @@ done: return return_code; module_alloc_err: json_parse_err: -fclose_err: - /* We will retry fclose when we fall through into stat_buffer_alloc_err */ -fread_err: +file_load_err: free(file_buffer); -stat_buffer_alloc_err: - // Check to ensure we haven't already close this - if (module_file != NULL) { - if (fclose(module_file) == EOF) panic("Failed to close file\n"); - } err: return_code = -1; goto done;