diff options
Diffstat (limited to 'src/fileops.c')
-rw-r--r-- | src/fileops.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/src/fileops.c b/src/fileops.c index 5d7e92978..68f45c25a 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -1,5 +1,6 @@ #include "common.h" #include "fileops.h" +#include <ctype.h> int gitfo_open(const char *path, int flags) { @@ -311,6 +312,19 @@ int gitfo_dirent( return GIT_SUCCESS; } +#ifdef GIT_WIN32 + +static int is_windows_rooted_path(const char *path) +{ + /* Does the root of the path look like a windows drive ? */ + if (isalpha(path[0]) && (path[1] == ':')) + return GIT_SUCCESS; + + return GIT_ERROR; +} + +#endif + int gitfo_mkdir_recurs(const char *path, int mode) { int error; @@ -320,23 +334,35 @@ int gitfo_mkdir_recurs(const char *path, int mode) if (path_copy == NULL) return GIT_ENOMEM; - error = GIT_SUCCESS; - pp = path_copy; + error = GIT_SUCCESS; + pp = path_copy; - while (error == 0 && (sp = strchr(pp, '/')) != 0) { - if (sp != pp && gitfo_isdir(path_copy) < GIT_SUCCESS) { - *sp = 0; - error = gitfo_mkdir(path_copy, mode); - *sp = '/'; - } +#ifdef GIT_WIN32 - pp = sp + 1; - } + if (!is_windows_rooted_path(pp)) + pp += 2; /* Skip the drive name (eg. C: or D:) */ + +#endif + + while (error == GIT_SUCCESS && (sp = strchr(pp, '/')) != 0) { + if (sp != pp && gitfo_isdir(path_copy) < GIT_SUCCESS) { + *sp = 0; + error = gitfo_mkdir(path_copy, mode); + + /* Do not choke while trying to recreate an existing directory */ + if (errno == EEXIST) + error = GIT_SUCCESS; + + *sp = '/'; + } + + pp = sp + 1; + } - if (*(pp - 1) != '/' && error == GIT_SUCCESS) - error = gitfo_mkdir(path, mode); + if (*(pp - 1) != '/' && error == GIT_SUCCESS) + error = gitfo_mkdir(path, mode); - free(path_copy); - return error; + free(path_copy); + return error; } |