Skip to content

Commit

Permalink
Fix emulated readdir() d_type to return DT_FILE or DT_DIR like Unix does
Browse files Browse the repository at this point in the history
We used to abuse dirent.d_type to store Windows attributes, but we can now just
add a new attribute to store these (win_attrs), so I have.
  • Loading branch information
qris committed May 19, 2017
1 parent 7858a80 commit 28a50df
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 11 deletions.
14 changes: 5 additions & 9 deletions lib/bbackupd/BackupClientDirectoryRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,13 +435,9 @@ bool BackupClientDirectoryRecord::SyncDirectoryEntry(
#ifdef WIN32
// Don't stat the file just yet, to ensure that users can exclude
// unreadable files to suppress warnings that they are not accessible.
//
// Our emulated readdir() abuses en->d_type, which would normally
// contain DT_REG, DT_DIR, etc, but we only use it here and prefer to
// have the full file attributes.

int type;
if (en->d_type & FILE_ATTRIBUTE_DIRECTORY)
if (en->d_type == DT_DIR)
{
type = S_IFDIR;
}
Expand Down Expand Up @@ -514,24 +510,24 @@ bool BackupClientDirectoryRecord::SyncDirectoryEntry(
return false;
}

#ifdef WIN32
#ifdef WIN32
// exclude reparse points, as Application Data points to the
// parent directory under Vista and later, and causes an
// infinite loop:
// http://social.msdn.microsoft.com/forums/en-US/windowscompatibility/thread/05d14368-25dd-41c8-bdba-5590bf762a68/
if (en->d_type & FILE_ATTRIBUTE_REPARSE_POINT)
if (en->win_attrs & FILE_ATTRIBUTE_REPARSE_POINT)
{
rNotifier.NotifyMountPointSkipped(this, realFileName);
return false;
}
#endif
#endif // WIN32
}
else // not a file or directory, what is it?
{
if (type == S_IFSOCK
#ifndef WIN32
|| type == S_IFIFO
#endif
#endif // !WIN32
)
{
// removed notification for these types
Expand Down
10 changes: 9 additions & 1 deletion lib/win32/emu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,15 @@ struct dirent *readdir(DIR *dp)
NULL, NULL);
//den->d_name = (char *)dp->info.name;
den->d_name = &tempbuff[0];
den->d_type = dp->info.dwFileAttributes;
den->win_attrs = dp->info.dwFileAttributes;
if(dp->info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
den->d_type = DT_DIR;
}
else
{
den->d_type = DT_REG;
}
}
else // FindNextFileW failed
{
Expand Down
14 changes: 13 additions & 1 deletion lib/win32/emu.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,22 @@ inline int strncasecmp(const char *s1, const char *s2, size_t count)
#error You must not include the MinGW dirent.h!
#endif

// File types for struct dirent.d_type. Not all are supported by our emulated readdir():
#define DT_UNKNOWN 0
#define DT_FIFO 1
#define DT_CHR 2
#define DT_DIR 4
#define DT_BLK 6
#define DT_REG 8
#define DT_LNK 10
#define DT_SOCK 12
#define DT_WHT 14

struct dirent
{
char *d_name;
DWORD d_type; // file attributes
int d_type; // emulated UNIX file attributes
DWORD win_attrs; // WIN32_FIND_DATA.dwFileAttributes
};

struct DIR
Expand Down

0 comments on commit 28a50df

Please sign in to comment.