Mercurial > molko
changeset 255:d987a5fc4a3e
core: add sys_mkdir function
This function creates a directory recursively, will be needed for save.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 03 Dec 2020 14:56:07 +0100 |
parents | 6367b976112d |
children | 9dcb9354dc74 |
files | doc/docs/dev/api/core/sys.md libmlk-core/core/sys.c libmlk-core/core/sys.h |
diffstat | 3 files changed, 66 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/docs/dev/api/core/sys.md Thu Dec 03 13:49:54 2020 +0100 +++ b/doc/docs/dev/api/core/sys.md Thu Dec 03 14:56:07 2020 +0100 @@ -51,6 +51,16 @@ sys_dir(enum sys_dir kind) ``` +### sys\_mkdir + +Create the directory `path` recursively. Returns false on errors other than +already existing. + +```c +bool +sys_mkdir(const char *path) +``` + ### sys\_finish This function is automatically called from [core_finish](core.md#core_finish)
--- a/libmlk-core/core/sys.c Thu Dec 03 13:49:54 2020 +0100 +++ b/libmlk-core/core/sys.c Thu Dec 03 14:56:07 2020 +0100 @@ -25,6 +25,11 @@ #if defined(_WIN32) # include <shlwapi.h> +# include <windows.h> +#else +# include <sys/stat.h> +# include <errno.h> +# include <string.h> #endif #include <SDL.h> @@ -192,6 +197,21 @@ return NULL; } +static bool +mkpath(const char *path) +{ +#ifdef _WIN32 + /* TODO: add error using the convenient FormatMessage function. */ + if (!CreateDirectoryA(path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) + return errorf("unable to create directory: %s", path); +#else + if (mkdir(path, 0755) < 0 && errno != EEXIST) + return errorf("%s", strerror(errno)); +#endif + + return true; +} + const char * sys_dir(enum sys_dir kind) { @@ -205,6 +225,39 @@ } } +bool +sys_mkdir(const char *directory) +{ + char path[PATH_MAX], *p; + + /* Copy the directory to normalize and iterate over '/'. */ + snprintf(path, sizeof (path), "%s", directory); + normalize(path); + +#if defined(_WIN32) + /* Remove drive letter that we don't need. */ + if ((p = strchr(path, ':'))) + ++p; + else + p = path; +#else + p = path; +#endif + + for (p = p + 1; *p; ++p) { + if (*p == '/') { + *p = 0; + + if (!mkpath(path)) + return false; + + *p = '/'; + } + } + + return mkpath(path); +} + void sys_finish(void) {