Skip to content

Commit 2396e2d

Browse files
kbleesdscho
authored andcommitted
squash! Win32: Make the dirent implementation pluggable
mingw: make the dirent implementation pluggable Emulating the POSIX `dirent` API on Windows via `FindFirstFile()`/`FindNextFile()` is pretty staightforward, however, most of the information provided in the `WIN32_FIND_DATA` structure is thrown away in the process. A more sophisticated implementation may cache this data, e.g. for later reuse in calls to `lstat()`. Make the `dirent` implementation pluggable so that it can be switched at runtime, e.g. based on a config option. Define a base DIR structure with pointers to `readdir()`/`closedir()` that match the `opendir()` implementation (similar to vtable pointers in Object-Oriented Programming). Define `readdir()`/`closedir()` so that they call the function pointers in the `DIR` structure. This allows to choose the `opendir()` implementation on a call-by-call basis. Make the fixed-size `dirent.d_name` buffer a flex array, as `d_name` may be implementation specific (e.g. a caching implementation may allocate a `struct dirent` with _just_ the size needed to hold the `d_name` in question). Signed-off-by: Karsten Blees <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent baa8b8a commit 2396e2d

File tree

2 files changed

+3
-5
lines changed

2 files changed

+3
-5
lines changed

compat/win32/dirent.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
typedef struct dirent_DIR {
44
struct DIR base_dir; /* extend base struct DIR */
5-
struct dirent dd_dir; /* includes d_type */
65
HANDLE dd_handle; /* FindFirstFile handle */
76
int dd_stat; /* 0-based index */
8-
char dd_name[MAX_PATH * 3]; /* file name (* 3 for UTF-8 conversion) */
7+
struct dirent dd_dir; /* includes d_type */
98
} dirent_DIR;
109

1110
DIR *(*opendir)(const char *dirname) = dirent_opendir;
@@ -95,10 +94,9 @@ DIR *dirent_opendir(const char *name)
9594
}
9695

9796
/* initialize DIR structure and copy first dir entry */
98-
dir = xmalloc(sizeof(dirent_DIR));
97+
dir = xmalloc(sizeof(dirent_DIR) + MAX_LONG_PATH);
9998
dir->base_dir.preaddir = (struct dirent *(*)(DIR *dir)) dirent_readdir;
10099
dir->base_dir.pclosedir = (int (*)(DIR *dir)) dirent_closedir;
101-
dir->dd_dir.d_name = dir->dd_name;
102100
dir->dd_handle = h;
103101
dir->dd_stat = 0;
104102
finddata2dirent(&dir->dd_dir, &fdata);

compat/win32/dirent.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
struct dirent {
1010
unsigned char d_type; /* file type to prevent lstat after readdir */
11-
char *d_name; /* file name */
11+
char d_name[FLEX_ARRAY]; /* file name */
1212
};
1313

1414
/*

0 commit comments

Comments
 (0)