Commit c6e26210 by Edward Thomson

Merge pull request #2615 from ethomson/mount_points

Mount points
parents c0c8570c 969b6a47
...@@ -515,23 +515,33 @@ bool git_path_is_empty_dir(const char *path) ...@@ -515,23 +515,33 @@ bool git_path_is_empty_dir(const char *path)
WIN32_FIND_DATAW findData; WIN32_FIND_DATAW findData;
HANDLE hFind = FindFirstFileW(filter_w, &findData); HANDLE hFind = FindFirstFileW(filter_w, &findData);
/* FindFirstFile will fail if there are no children to the given
* path, which can happen if the given path is a file (and obviously
* has no children) or if the given path is an empty mount point.
* (Most directories have at least directory entries '.' and '..',
* but ridiculously another volume mounted in another drive letter's
* path space do not, and thus have nothing to enumerate.) If
* FindFirstFile fails, check if this is a directory-like thing
* (a mount point).
*/
if (hFind == INVALID_HANDLE_VALUE)
return git_path_isdir(path);
/* If the find handle was created successfully, then it's a directory */ /* If the find handle was created successfully, then it's a directory */
if (hFind != INVALID_HANDLE_VALUE) { empty = true;
empty = true;
do {
do { /* Allow the enumeration to return . and .. and still be considered
/* Allow the enumeration to return . and .. and still be considered * empty. In the special case of drive roots (i.e. C:\) where . and
* empty. In the special case of drive roots (i.e. C:\) where . and * .. do not occur, we can still consider the path to be an empty
* .. do not occur, we can still consider the path to be an empty * directory if there's nothing there. */
* directory if there's nothing there. */ if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
if (!git_path_is_dot_or_dotdotW(findData.cFileName)) { empty = false;
empty = false; break;
break; }
} } while (FindNextFileW(hFind, &findData));
} while (FindNextFileW(hFind, &findData));
FindClose(hFind);
FindClose(hFind);
}
} }
return empty; return empty;
......
...@@ -131,6 +131,11 @@ GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft) ...@@ -131,6 +131,11 @@ GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft)
return (time_t)winTime; return (time_t)winTime;
} }
static bool path_is_volume(wchar_t *target, size_t target_len)
{
return (target_len && wcsncmp(target, L"\\??\\Volume{", 11) == 0);
}
/* On success, returns the length, in characters, of the path stored in dest. /* On success, returns the length, in characters, of the path stored in dest.
* On failure, returns a negative value. */ * On failure, returns a negative value. */
static int readlink_w( static int readlink_w(
...@@ -177,7 +182,13 @@ static int readlink_w( ...@@ -177,7 +182,13 @@ static int readlink_w(
goto on_error; goto on_error;
} }
if (target_len) { if (path_is_volume(target, target_len)) {
/* This path is a reparse point that represents another volume mounted
* at this location, it is not a symbolic link our input was canonical.
*/
errno = EINVAL;
error = -1;
} else if (target_len) {
/* The path may need to have a prefix removed. */ /* The path may need to have a prefix removed. */
target_len = git_win32__canonicalize_path(target, target_len); target_len = git_win32__canonicalize_path(target, target_len);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment