diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2014-10-13 16:52:44 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2014-10-13 16:52:44 -0400 |
commit | c6e26210520663b4de07102b8b3035dd7675ef08 (patch) | |
tree | 0a16e49570dcc200880e71a12dbc33cf74dc2b66 | |
parent | c0c8570c5104a3047564fd5a1cfe1cacb0ed935d (diff) | |
parent | 969b6a4710451b3e905757093dce4977cd596635 (diff) | |
download | libgit2-c6e26210520663b4de07102b8b3035dd7675ef08.tar.gz |
Merge pull request #2615 from ethomson/mount_points
Mount points
-rw-r--r-- | src/path.c | 42 | ||||
-rw-r--r-- | src/win32/posix_w32.c | 13 |
2 files changed, 38 insertions, 17 deletions
diff --git a/src/path.c b/src/path.c index 21b6e18d6..143c564e8 100644 --- a/src/path.c +++ b/src/path.c @@ -515,23 +515,33 @@ bool git_path_is_empty_dir(const char *path) WIN32_FIND_DATAW 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 (hFind != INVALID_HANDLE_VALUE) { - empty = true; - - do { - /* Allow the enumeration to return . and .. and still be considered - * 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 - * directory if there's nothing there. */ - if (!git_path_is_dot_or_dotdotW(findData.cFileName)) { - empty = false; - break; - } - } while (FindNextFileW(hFind, &findData)); - - FindClose(hFind); - } + empty = true; + + do { + /* Allow the enumeration to return . and .. and still be considered + * 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 + * directory if there's nothing there. */ + if (!git_path_is_dot_or_dotdotW(findData.cFileName)) { + empty = false; + break; + } + } while (FindNextFileW(hFind, &findData)); + + FindClose(hFind); } return empty; diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 0023f95ff..7b4555719 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -131,6 +131,11 @@ GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft) 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 failure, returns a negative value. */ static int readlink_w( @@ -177,7 +182,13 @@ static int readlink_w( 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. */ target_len = git_win32__canonicalize_path(target, target_len); |