Commit f0ebf82e1afe4736dc294c16431c15685294f0b6

Russell Belfer 2012-11-20T11:34:12

Merge pull request #1089 from edubart/fix_win32_lstat Fix win32 lstat

diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 7359e4e..0efcaf5 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -104,46 +104,30 @@ static int do_lstat(
 		return 0;
 	}
 
-	last_error = GetLastError();
+	errno = ENOENT;
 
-	/* ERROR_PATH_NOT_FOUND can mean either that a parent directory is
-	 * missing or that an expected directory is a regular file.  If we need
-	 * POSIX behavior, then ENOTDIR must only be set for the second case
-	 * (i.e. entry that is not a dir), and the first case should be ENOENT.
+	/* We need POSIX behavior, then ENOTDIR must set when any of the folders in the
+	 * file path is a regular file,otherwise ENOENT must be set.
 	 */
-
-	if (last_error == ERROR_PATH_NOT_FOUND && posix_enotdir) {
+	if (posix_enotdir) {
 		/* scan up path until we find an existing item */
 		while (1) {
 			/* remove last directory component */
 			for (--flen; flen > 0 && !WIN32_IS_WSEP(fbuf[flen]); --flen);
 
-			if (flen <= 0) {
-				last_error = ERROR_FILE_NOT_FOUND;
+			if (flen <= 0)
 				break;
-			}
 
 			fbuf[flen] = L'\0';
 
 			if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) {
-				if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-					last_error = ERROR_FILE_NOT_FOUND;
-				else
-					last_error = ERROR_PATH_NOT_FOUND;
+				if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+					errno = ENOTDIR;
 				break;
 			}
-
-			last_error = GetLastError();
-			if (last_error == ERROR_FILE_NOT_FOUND)
-				break;
 		}
 	}
 
-	if (last_error == ERROR_FILE_NOT_FOUND)
-		errno = ENOENT;
-	else if (last_error == ERROR_PATH_NOT_FOUND)
-		errno = ENOTDIR;
-
 	return -1;
 }
 
diff --git a/tests-clar/core/stat.c b/tests-clar/core/stat.c
index cbfc66c..2e4abfb 100644
--- a/tests-clar/core/stat.c
+++ b/tests-clar/core/stat.c
@@ -15,13 +15,6 @@ void test_core_stat__cleanup(void)
 	git_futils_rmdir_r("root", NULL, GIT_RMDIR_REMOVE_FILES);
 }
 
-#ifdef GIT_WIN32
-#define cl_assert_last_error(val) \
-	do { werr = GetLastError(); cl_assert_equal_i((val), (int)werr); } while (0)
-#else
-#define cl_assert_last_error(val)
-#endif
-
 #define cl_assert_error(val) \
 	do { err = errno; cl_assert_equal_i((val), err); } while (0)
 
@@ -29,66 +22,45 @@ void test_core_stat__0(void)
 {
 	struct stat st;
 	int err;
-#ifdef GIT_WIN32
-	DWORD werr;
-#endif
 
 	cl_assert_equal_i(0, p_lstat("root", &st));
 	cl_assert(S_ISDIR(st.st_mode));
-	cl_assert_last_error(0);
 	cl_assert_error(0);
 
 	cl_assert_equal_i(0, p_lstat("root/", &st));
 	cl_assert(S_ISDIR(st.st_mode));
-	cl_assert_last_error(0);
 	cl_assert_error(0);
 
 	cl_assert_equal_i(0, p_lstat("root/file", &st));
 	cl_assert(S_ISREG(st.st_mode));
-	cl_assert_last_error(0);
 	cl_assert_error(0);
 
 	cl_assert_equal_i(0, p_lstat("root/d1", &st));
 	cl_assert(S_ISDIR(st.st_mode));
-	cl_assert_last_error(0);
 	cl_assert_error(0);
 
 	cl_assert_equal_i(0, p_lstat("root/d1/", &st));
 	cl_assert(S_ISDIR(st.st_mode));
-	cl_assert_last_error(0);
 	cl_assert_error(0);
 
 	cl_assert_equal_i(0, p_lstat("root/d1/file", &st));
 	cl_assert(S_ISREG(st.st_mode));
-	cl_assert_last_error(0);
 	cl_assert_error(0);
 
 	cl_assert(p_lstat("root/missing", &st) < 0);
-	cl_assert_last_error(ERROR_FILE_NOT_FOUND);
 	cl_assert_error(ENOENT);
 
 	cl_assert(p_lstat("root/missing/but/could/be/created", &st) < 0);
-	cl_assert_last_error(ERROR_PATH_NOT_FOUND);
-#ifdef GIT_WIN32
-	cl_assert_error(ENOTDIR);
-#else
 	cl_assert_error(ENOENT);
-#endif
 
 	cl_assert(p_lstat_posixly("root/missing/but/could/be/created", &st) < 0);
 	cl_assert_error(ENOENT);
 
 	cl_assert(p_lstat("root/d1/missing", &st) < 0);
-	cl_assert_last_error(ERROR_FILE_NOT_FOUND);
 	cl_assert_error(ENOENT);
 
 	cl_assert(p_lstat("root/d1/missing/deeper/path", &st) < 0);
-	cl_assert_last_error(ERROR_PATH_NOT_FOUND);
-#ifdef GIT_WIN32
-	cl_assert_error(ENOTDIR);
-#else
 	cl_assert_error(ENOENT);
-#endif
 
 	cl_assert(p_lstat_posixly("root/d1/missing/deeper/path", &st) < 0);
 	cl_assert_error(ENOENT);
@@ -97,13 +69,21 @@ void test_core_stat__0(void)
 	cl_assert_error(ENOTDIR);
 
 	cl_assert(p_lstat("root/file/invalid", &st) < 0);
+#ifdef GIT_WIN32
+	cl_assert_error(ENOENT);
+#else
 	cl_assert_error(ENOTDIR);
+#endif
 
 	cl_assert(p_lstat_posixly("root/file/invalid", &st) < 0);
 	cl_assert_error(ENOTDIR);
 
 	cl_assert(p_lstat("root/file/invalid/deeper_path", &st) < 0);
+#ifdef GIT_WIN32
+	cl_assert_error(ENOENT);
+#else
 	cl_assert_error(ENOTDIR);
+#endif
 
 	cl_assert(p_lstat_posixly("root/file/invalid/deeper_path", &st) < 0);
 	cl_assert_error(ENOTDIR);