lib

morphux C utility library
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/lib

commit ed62831b740a07cc7255a64edb316479a2aea6d1
parent bd7c7c90461e10c71a7c49640db363096d547013
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Sun, 28 May 2017 15:08:34 +0200

Add(Files): Add a function to create files with directories (mkdir -p like)

Diffstat:
Minc/m_file.h | 14++++++++++++++
Msrc/m_file.c | 27+++++++++++++++++++++++++++
Mtests/test_files.c | 16++++++++++++++++
3 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/inc/m_file.h b/inc/m_file.h @@ -63,5 +63,19 @@ off_t mpm_get_file_size_from_fd(int fd); */ off_t mpm_get_file_size_from_fn(const char *fn); +/*! + * \brief Open a file, an create directory in order to access it + * + * \param[in] File path + * + * This function will create directories in order to achieve the desired path, + * then return a FILE * on the opened file. + * Example: + * > recursive_file_open("/tmp/something/somedir/somefile"); + * + * \note Due to its nature, this function is not very likely to fail + * \return A FILE * on success, NULL on failure + */ +FILE *recursive_file_open(char *fn); #endif /* M_FILE_H */ diff --git a/src/m_file.c b/src/m_file.c @@ -83,3 +83,30 @@ char *mpm_read_file_from_fn(const char *fn) { close(fd); return ret; } + +FILE *recursive_file_open(char *path) { + char *tmp = NULL, *fn = NULL; + + /* Sanitize path */ + fn = strdup(path); + if (fn == NULL) + return NULL; + + for (tmp = fn + 1; *tmp != '\0'; tmp++) + { + if (*tmp == '/') + { + *tmp = '\0'; + if (mkdir(fn, S_IRWXU) == -1 && errno != EEXIST) + { + *tmp = '/'; + goto open; + } + *tmp = '/'; + } + } + +open: + free(fn); + return fopen(path, "w+"); +} diff --git a/tests/test_files.c b/tests/test_files.c @@ -95,6 +95,21 @@ TEST(file_read_file_from_fn_3) { return TEST_SUCCESS; } +# define _DIR_TO_CREATE "/tmp/dir_1/dir_2/dir_3/file" +TEST(recursive_file_open) { + FILE *fd = NULL; + + TEST_ASSERT(recursive_file_open("/somepath_i_cant_create/file") == NULL, "Error did not raise"); + set_strdup_fail(0); + TEST_ASSERT(recursive_file_open("/somepath_i_cant_create/file") == NULL, "Error did not raise"); + + fd = recursive_file_open(_DIR_TO_CREATE); + TEST_ASSERT(fd != NULL, "Can't create the file"); + fclose(fd); + recursive_delete("/tmp/dir_1"); + return TEST_SUCCESS; +} + void register_files_tests(void) { reg_test("m_file", file_get_file_size_from_fd_1); @@ -111,4 +126,5 @@ void register_files_tests(void) { reg_test("m_file", file_read_file_from_fn_1); reg_test("m_file", file_read_file_from_fn_2); reg_test("m_file", file_read_file_from_fn_3); + reg_test("m_file", recursive_file_open); }