fileops: Make git_futils_mkdir_r() able to cope with Windows network paths Partially fix libgit2/libgit2sharp#153
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
diff --git a/src/fileops.c b/src/fileops.c
index ee9d421..d6960ca 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -241,28 +241,36 @@ void git_futils_mmap_free(git_map *out)
int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode)
{
- int root_path_offset;
git_buf make_path = GIT_BUF_INIT;
- size_t start;
+ size_t start = 0;
char *pp, *sp;
bool failed = false;
if (base != NULL) {
+ /*
+ * when a base is being provided, it is supposed to already exist.
+ * Therefore, no attempt is being made to recursively create this leading path
+ * segment. It's just skipped. */
start = strlen(base);
if (git_buf_joinpath(&make_path, base, path) < 0)
return -1;
} else {
- start = 0;
+ int root_path_offset;
+
if (git_buf_puts(&make_path, path) < 0)
return -1;
+
+ root_path_offset = git_path_root(make_path.ptr);
+ if (root_path_offset > 0) {
+ /*
+ * On Windows, will skip the drive name (eg. C: or D:)
+ * or the leading part of a network path (eg. //computer_name ) */
+ start = root_path_offset;
+ }
}
pp = make_path.ptr + start;
- root_path_offset = git_path_root(make_path.ptr);
- if (root_path_offset > 0)
- pp += root_path_offset; /* On Windows, will skip the drive name (eg. C: or D:) */
-
while (!failed && (sp = strchr(pp, '/')) != NULL) {
if (sp != pp && git_path_isdir(make_path.ptr) == false) {
*sp = 0;
diff --git a/src/fileops.h b/src/fileops.h
index be619d6..b0c5779 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -49,6 +49,9 @@ extern int git_futils_creat_locked_withpath(const char *path, const mode_t dirmo
/**
* Create a path recursively
+ *
+ * If a base parameter is being passed, it's expected to be valued with a path pointing to an already
+ * exisiting directory.
*/
extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode);