Commit daf98cb2edaa2d8b45c3e88d2d2f4c5db7925b2f

Jameson Miller 2013-06-04T14:49:39

Allow creation of directories under the volume root in Win32 We ran into an issue where cloning a repository to a folder directly underneath the root of a volume (e.g. 'd:\libgit2') would fail with an access denied error. This was traced down to a call to make a directory that is the root (e.g. 'd:') could return an error indicated access denied instead of an error indicating the path already exists. This change now handles the access denied error on Win32 and checks for the existence of the folder.

diff --git a/src/fileops.c b/src/fileops.c
index a3e4321..a4f56e0 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -277,7 +277,7 @@ int git_futils_mkdir(
 	mode_t mode,
 	uint32_t flags)
 {
-	int error = -1;
+	int error = -1, tmp_errno;
 	git_buf make_path = GIT_BUF_INIT;
 	ssize_t root = 0;
 	char lastch, *tail;
@@ -345,18 +345,26 @@ int git_futils_mkdir(
 
 				already_exists = 1;
 				break;
+#ifdef GIT_WIN32
+			case EACCES:
+#endif
 			case ENOSYS:
-				/* Solaris can generate this error if you try to mkdir
-				 * a path which is already a mount point. In that case,
-				 * the path does already exist; but it's not implied by
+				/* The following errors can be generated if:
+				 * EACCES - Win32 can generate this error if you try to mkdir
+				 *          a path which is the root of a volume.
+				 * ENOSYS - Solaris can generate a ENOSYS error if you try to mkdir
+				 *          a path which is already a mount point.
+				 * In these cases, the path does already exist; but it's not implied by
 				 * the definition of the error, so let's recheck */
+				tmp_errno = errno;
+
 				if (git_path_isdir(make_path.ptr)) {
 					already_exists = 1;
 					break;
 				}
 
 				/* Fall through */
-				errno = ENOSYS;
+				errno = tmp_errno;
 			default:
 				giterr_set(GITERR_OS, "Failed to make directory '%s'",
 					make_path.ptr);