Commit 19ac1ed7 by Vicent Marti

fileops: Fix stat() on directories for W32

The `stat` methods were having issues when called with a trailing slash
in Windows platforms.

We now use GetFileAttributes() where possible, which doesn't have this
restriction.
parent 5ad739e8
...@@ -93,31 +93,20 @@ int git_futils_creat_locked_withpath(const char *path, int mode) ...@@ -93,31 +93,20 @@ int git_futils_creat_locked_withpath(const char *path, int mode)
int git_futils_isdir(const char *path) int git_futils_isdir(const char *path)
{ {
struct stat st; #ifdef GIT_WIN32
int len, stat_error; DWORD attr = GetFileAttributes(path);
if (attr == INVALID_FILE_ATTRIBUTES)
assert(path);
len = strlen(path);
/* win32: stat path for folders cannot end in a slash */
if (path[len - 1] == '/') {
char *path_fixed = NULL;
path_fixed = git__strdup(path);
path_fixed[len - 1] = 0;
stat_error = p_stat(path_fixed, &st);
free(path_fixed);
} else {
stat_error = p_stat(path, &st);
}
if (stat_error < GIT_SUCCESS)
return GIT_ERROR; return GIT_ERROR;
if (!S_ISDIR(st.st_mode)) return (attr & FILE_ATTRIBUTE_DIRECTORY) ? GIT_SUCCESS : GIT_ERROR;
#else
struct stat st;
if (p_stat(path, &st) < GIT_SUCCESS)
return GIT_ERROR; return GIT_ERROR;
return GIT_SUCCESS; return S_ISDIR(st.st_mode) ? GIT_SUCCESS : GIT_ERROR;
#endif
} }
int git_futils_isfile(const char *path) int git_futils_isfile(const char *path)
......
...@@ -377,7 +377,7 @@ static int retrieve_device(dev_t *device_out, const char *path) ...@@ -377,7 +377,7 @@ static int retrieve_device(dev_t *device_out, const char *path)
assert(device_out); assert(device_out);
if (p_stat(path, &path_info)) if (p_lstat(path, &path_info))
return git__throw(GIT_EOSERR, "Failed to get file informations: %s", path); return git__throw(GIT_EOSERR, "Failed to get file informations: %s", path);
*device_out = path_info.st_dev; *device_out = path_info.st_dev;
......
...@@ -190,13 +190,22 @@ int p_hide_directory__w32(const char *path) ...@@ -190,13 +190,22 @@ int p_hide_directory__w32(const char *path)
return error; return error;
} }
int p_realpath(const char *orig_path, char *buffer) char *p_realpath(const char *orig_path, char *buffer)
{ {
int ret = GetFullPathName(orig_path, GIT_PATH_MAX, buffer, NULL); int ret, alloc = 0;
if (!ret || ret > GIT_PATH_MAX)
return GIT_EOSERR; if (buffer == NULL) {
buffer = (char *)git__malloc(GIT_PATH_MAX);
alloc = 1;
}
ret = GetFullPathName(orig_path, GIT_PATH_MAX, buffer, NULL);
if (!ret || ret > GIT_PATH_MAX) {
if (alloc) free(buffer);
return NULL;
}
git_path_mkposix(buffer); git_path_mkposix(buffer);
return GIT_SUCCESS; return buffer;
} }
...@@ -21,6 +21,6 @@ extern int p_unlink(const char *path); ...@@ -21,6 +21,6 @@ extern int p_unlink(const char *path);
extern int p_lstat(const char *file_name, struct stat *buf); extern int p_lstat(const char *file_name, struct stat *buf);
extern int p_readlink(const char *link, char *target, size_t target_len); extern int p_readlink(const char *link, char *target, size_t target_len);
extern int p_hide_directory__w32(const char *path); extern int p_hide_directory__w32(const char *path);
extern int p_realpath(const char *orig_path, char *buffer); extern char *p_realpath(const char *orig_path, char *buffer);
#endif #endif
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