Skip to content

Commit f4cbb8d

Browse files
kbleesdscho
authored andcommitted
mingw: 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 <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 2e56150 commit f4cbb8d

File tree

4 files changed

+18
-17
lines changed

4 files changed

+18
-17
lines changed

compat/mingw.c

+3-10
Original file line numberDiff line numberDiff line change
@@ -864,21 +864,14 @@ int mingw_lstat(const char *file_name, struct stat *buf)
864864
buf->st_gid = 0;
865865
buf->st_uid = 0;
866866
buf->st_nlink = 1;
867-
buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
867+
buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes,
868+
findbuf.dwReserved0);
868869
buf->st_size = fdata.nFileSizeLow |
869870
(((off_t)fdata.nFileSizeHigh)<<32);
870871
buf->st_dev = buf->st_rdev = 0; /* not used by Git */
871872
filetime_to_timespec(&(fdata.ftLastAccessTime), &(buf->st_atim));
872873
filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim));
873874
filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim));
874-
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
875-
if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
876-
(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
877-
buf->st_mode = S_IFLNK | S_IREAD;
878-
if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
879-
buf->st_mode |= S_IWRITE;
880-
}
881-
}
882875
return 0;
883876
}
884877
error:
@@ -923,7 +916,7 @@ static int get_file_info_by_handle(HANDLE hnd, struct stat *buf)
923916
buf->st_gid = 0;
924917
buf->st_uid = 0;
925918
buf->st_nlink = 1;
926-
buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
919+
buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes, 0);
927920
buf->st_size = fdata.nFileSizeLow |
928921
(((off_t)fdata.nFileSizeHigh)<<32);
929922
buf->st_dev = buf->st_rdev = 0; /* not used by Git */

compat/win32.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
#include <windows.h>
77
#endif
88

9-
static inline int file_attr_to_st_mode (DWORD attr)
9+
static inline int file_attr_to_st_mode (DWORD attr, DWORD tag)
1010
{
1111
int fMode = S_IREAD;
12-
if (attr & FILE_ATTRIBUTE_DIRECTORY)
12+
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) && tag == IO_REPARSE_TAG_SYMLINK)
13+
fMode |= S_IFLNK;
14+
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
1315
fMode |= S_IFDIR;
1416
else
1517
fMode |= S_IFREG;

compat/win32/dirent.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAW *fdata)
1818
xwcstoutf(ent->d_name, fdata->cFileName, MAX_PATH * 3);
1919

2020
/* Set file type, based on WIN32_FIND_DATA */
21-
if (fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
21+
if ((fdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
22+
&& fdata->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
23+
ent->d_type = DT_LNK;
24+
else if (fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
2225
ent->d_type = DT_DIR;
2326
else
2427
ent->d_type = DT_REG;

compat/win32/fscache.c

+7-4
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,13 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache,
200200
fdata->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
201201
fdata->EaSize : 0;
202202

203-
fse->st_mode = file_attr_to_st_mode(fdata->FileAttributes);
204-
fse->dirent.d_type = S_ISDIR(fse->st_mode) ? DT_DIR : DT_REG;
205-
fse->u.s.st_size = fdata->EndOfFile.LowPart |
206-
(((off_t)fdata->EndOfFile.HighPart) << 32);
203+
fse->st_mode = file_attr_to_st_mode(fdata->FileAttributes,
204+
fdata->EaSize);
205+
fse->dirent.d_type = S_ISREG(fse->st_mode) ? DT_REG :
206+
S_ISDIR(fse->st_mode) ? DT_DIR : DT_LNK;
207+
fse->u.s.st_size = S_ISLNK(fse->st_mode) ? MAX_LONG_PATH :
208+
fdata->EndOfFile.LowPart |
209+
(((off_t)fdata->EndOfFile.HighPart) << 32);
207210
filetime_to_timespec((FILETIME *)&(fdata->LastAccessTime),
208211
&(fse->u.s.st_atim));
209212
filetime_to_timespec((FILETIME *)&(fdata->LastWriteTime),

0 commit comments

Comments
 (0)