mirror of
https://github.com/git/git.git
synced 2026-01-17 22:26:32 +00:00
Win32: teach fscache and dirent about symlinks
Move S_IFLNK detection to file_attr_to_st_mode() and reuse it in fscache. Implement DT_LNK detection in dirent.c and the fscache readdir version. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
committed by
Johannes Schindelin
parent
513a68b217
commit
3cc396b84f
@@ -720,21 +720,14 @@ int mingw_lstat(const char *file_name, struct stat *buf)
|
||||
buf->st_gid = 0;
|
||||
buf->st_uid = 0;
|
||||
buf->st_nlink = 1;
|
||||
buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
|
||||
buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes,
|
||||
findbuf.dwReserved0);
|
||||
buf->st_size = fdata.nFileSizeLow |
|
||||
(((off_t)fdata.nFileSizeHigh)<<32);
|
||||
buf->st_dev = buf->st_rdev = 0; /* not used by Git */
|
||||
filetime_to_timespec(&(fdata.ftLastAccessTime), &(buf->st_atim));
|
||||
filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim));
|
||||
filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim));
|
||||
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
|
||||
(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
|
||||
buf->st_mode = S_IFLNK | S_IREAD;
|
||||
if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
buf->st_mode |= S_IWRITE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
error:
|
||||
@@ -779,7 +772,7 @@ static int get_file_info_by_handle(HANDLE hnd, struct stat *buf)
|
||||
buf->st_gid = 0;
|
||||
buf->st_uid = 0;
|
||||
buf->st_nlink = 1;
|
||||
buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
|
||||
buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes, 0);
|
||||
buf->st_size = fdata.nFileSizeLow |
|
||||
(((off_t)fdata.nFileSizeHigh)<<32);
|
||||
buf->st_dev = buf->st_rdev = 0; /* not used by Git */
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
static inline int file_attr_to_st_mode (DWORD attr)
|
||||
static inline int file_attr_to_st_mode (DWORD attr, DWORD tag)
|
||||
{
|
||||
int fMode = S_IREAD;
|
||||
if (attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) && tag == IO_REPARSE_TAG_SYMLINK)
|
||||
fMode |= S_IFLNK;
|
||||
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
fMode |= S_IFDIR;
|
||||
else
|
||||
fMode |= S_IFREG;
|
||||
|
||||
@@ -16,7 +16,10 @@ static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAW *fdata)
|
||||
xwcstoutf(ent->d_name, fdata->cFileName, MAX_PATH * 3);
|
||||
|
||||
/* Set file type, based on WIN32_FIND_DATA */
|
||||
if (fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
if ((fdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
&& fdata->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
|
||||
ent->d_type = DT_LNK;
|
||||
else if (fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
ent->d_type = DT_DIR;
|
||||
else
|
||||
ent->d_type = DT_REG;
|
||||
|
||||
@@ -149,7 +149,8 @@ static struct fsentry *fseentry_create_entry(struct fsentry *list,
|
||||
|
||||
fse = fsentry_alloc(list, buf, len);
|
||||
|
||||
fse->st_mode = file_attr_to_st_mode(fdata->dwFileAttributes);
|
||||
fse->st_mode = file_attr_to_st_mode(fdata->dwFileAttributes,
|
||||
fdata->dwReserved0);
|
||||
fse->st_size = (((off64_t) (fdata->nFileSizeHigh)) << 32)
|
||||
| fdata->nFileSizeLow;
|
||||
filetime_to_timespec(&(fdata->ftLastAccessTime), &(fse->st_atim));
|
||||
@@ -442,7 +443,8 @@ static struct dirent *fscache_readdir(DIR *base_dir)
|
||||
if (!next)
|
||||
return NULL;
|
||||
dir->pfsentry = next;
|
||||
dir->dirent.d_type = S_ISDIR(next->st_mode) ? DT_DIR : DT_REG;
|
||||
dir->dirent.d_type = S_ISREG(next->st_mode) ? DT_REG :
|
||||
S_ISDIR(next->st_mode) ? DT_DIR : DT_LNK;
|
||||
dir->dirent.d_name = (char*) next->name;
|
||||
return &(dir->dirent);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user