diff --git a/src/outfile/CMakeLists.txt b/src/outfile/CMakeLists.txt index 79a8ae1..c129221 100644 --- a/src/outfile/CMakeLists.txt +++ b/src/outfile/CMakeLists.txt @@ -22,7 +22,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) # configure file groups set(EPANET_OUT_SOURCES src/epanet_output.c ../util/errormanager.c - ../util/filemanager.c) + ../util/filemanager.c + ../util/cstr_helper.c) # the binary output file API diff --git a/src/util/cstr_helper.c b/src/util/cstr_helper.c new file mode 100644 index 0000000..9266551 --- /dev/null +++ b/src/util/cstr_helper.c @@ -0,0 +1,22 @@ + +#include +#include + + +int copy_cstr(const char *source, char **destination, size_t *size) +// Determines length, allocates memory, and returns a null terminated copy +// Be Aware: caller is responsible for freeing memory +{ + size_t len; + + len = strlen(source); + *destination = (char *) calloc(len + 1, sizeof(char)); + + if (*destination == NULL) + return -1; + else { + strncpy(*destination, source, len); + *size = len + 1; + } + return 0; +} diff --git a/src/util/cstr_helper.h b/src/util/cstr_helper.h new file mode 100644 index 0000000..1b435c1 --- /dev/null +++ b/src/util/cstr_helper.h @@ -0,0 +1,9 @@ + +#ifndef CSTR_HELPER_H_ +#define CSTR_HELPER_H_ + + +int copy_cstr(const char *source, char **destination, size_t *size); + + +#endif /* CSTR_HELPER_H_ */ diff --git a/src/util/filemanager.c b/src/util/filemanager.c index a5f5c43..98d775c 100644 --- a/src/util/filemanager.c +++ b/src/util/filemanager.c @@ -22,41 +22,50 @@ #endif #include -#include #include "filemanager.h" typedef struct file_s { - char filename[FILE_MAXNAME + 1]; + char *filename; + size_t size; FILE *file; } file_handle_t; // local (private) functions int _fopen(FILE **f, const char *name, const char *mode); -int _get_temp_filename(char *tempname); +int _get_temp_filename(char **tempname, size_t *size); file_handle_t *create_file_manager() { file_handle_t *file_handle; - file_handle = (file_handle_t*)calloc(1, sizeof(file_handle_t)); + file_handle = (file_handle_t *)calloc(1, sizeof(file_handle_t)); + + file_handle->filename = NULL; + file_handle->size = 0; + file_handle->file = NULL; return file_handle; } void delete_file_manager(file_handle_t *file_handle) { - free(file_handle); + + if (file_handle->file != NULL) + close_file(file_handle); + + free(file_handle->filename); + free(file_handle); } -void get_filename(file_handle_t *file_handle, char **filename) +void get_filename(file_handle_t *file_handle, char **filename, size_t *size) +// +// BE AWARE: The memory allocated here must be freed by the caller +// { - char *temp = (char*) malloc((FILE_MAXNAME)*sizeof(char)); - - strncpy(temp, file_handle->filename, FILE_MAXNAME); - *filename = temp; + copy_cstr(file_handle->filename, filename, size); } @@ -64,9 +73,9 @@ int open_file(file_handle_t *file_handle, const char *filename, const char *file int error = 0; if (filename == NULL) - _get_temp_filename(file_handle->filename); + _get_temp_filename(&(file_handle->filename), &(file_handle->size)); else - strncpy(file_handle->filename, filename, FILE_MAXNAME); + copy_cstr(filename, &(file_handle->filename), &(file_handle->size)); if (file_mode == NULL) error = -1; @@ -146,12 +155,14 @@ int remove_file(file_handle_t *file_handle) { } -int _fopen(FILE **f, const char *name, const char *mode) { +int _fopen(FILE **f, const char *name, const char *mode) // // Purpose: Substitute for fopen_s on platforms where it doesn't exist // Note: fopen_s is part of C++11 standard // +{ int ret = 0; + #ifdef _WIN32 ret = (int)fopen_s(f, name, mode); #else @@ -162,8 +173,10 @@ int _fopen(FILE **f, const char *name, const char *mode) { return ret; } -int _get_temp_filename(char *tempname) { +int _get_temp_filename(char **tempname, size_t *size) +{ int error = 0; + #ifdef _WIN32 char *name = NULL; @@ -173,10 +186,8 @@ int _get_temp_filename(char *tempname) { error = -1; return error; } - else if (strlen(name) < FILE_MAXNAME) - strncpy(tempname, name, FILE_MAXNAME); else - tempname = NULL; + copy_cstr(name, tempname, size); // --- free the pointer returned by _tempnam if (name) @@ -185,8 +196,8 @@ int _get_temp_filename(char *tempname) { // --- for non-Windows systems: #else // --- use system function mkstemp() to create a temporary file name - strncpy(tempname, "enXXXXXX", 8); - error = mkstemp(tempname); + copy_cstr("enXXXXXX", tempname, size) + error = mkstemp(*tempname); #endif return error; } diff --git a/src/util/filemanager.h b/src/util/filemanager.h index 1e313b8..f0b00d2 100644 --- a/src/util/filemanager.h +++ b/src/util/filemanager.h @@ -18,6 +18,8 @@ #include #include +#include "cstr_helper.h" + // F_OFF Must be a 8 byte / 64 bit integer for large file support #ifdef _WIN32 // Windows (32-bit and 64-bit) @@ -42,7 +44,7 @@ file_handle_t *create_file_manager(); void delete_file_manager(file_handle_t *file_handle); -void get_filename(file_handle_t *file_handle, char **filename); +void get_filename(file_handle_t *file_handle, char **filename, size_t *size); int open_file(file_handle_t *file_handle, const char *filename, const char *file_mode); diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt index e126ceb..0bd4a43 100644 --- a/tests/util/CMakeLists.txt +++ b/tests/util/CMakeLists.txt @@ -7,11 +7,14 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -add_executable(test_errormanager ./test_errormanager.cpp ../../src/util/errormanager.c) +add_executable(test_errormanager ./test_errormanager.cpp + ../../src/util/errormanager.c) target_include_directories(test_errormanager PUBLIC ../../src/) target_link_libraries(test_errormanager ${Boost_LIBRARIES}) -add_executable(test_filemanager ./test_filemanager.cpp ../../src/util/filemanager.c) +add_executable(test_filemanager ./test_filemanager.cpp + ../../src/util/filemanager.c + ../../src/util/cstr_helper.c) target_include_directories(test_filemanager PUBLIC ../../src/) target_link_libraries(test_filemanager ${Boost_LIBRARIES}) diff --git a/tests/util/test_filemanager.cpp b/tests/util/test_filemanager.cpp index 79fcec7..310c620 100644 --- a/tests/util/test_filemanager.cpp +++ b/tests/util/test_filemanager.cpp @@ -80,10 +80,11 @@ struct Fixture{ BOOST_FIXTURE_TEST_CASE(test_temp_file, Fixture) { char *filename; + size_t size; printf_file(file_handle, "%s", "This is a test."); - get_filename(file_handle, &filename); + get_filename(file_handle, &filename, &size); //BOOST_CHECK(check_string(filename, "./test_file.txt")); BOOST_CHECK(boost::filesystem::exists(filename) == true);