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 <blees@dcon.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
Karsten Blees
2013-09-08 14:18:40 +02:00
committed by Johannes Schindelin
parent baa8b8a6fa
commit 2396e2d3a2
2 changed files with 3 additions and 5 deletions

View File

@@ -2,10 +2,9 @@
typedef struct dirent_DIR {
struct DIR base_dir; /* extend base struct DIR */
struct dirent dd_dir; /* includes d_type */
HANDLE dd_handle; /* FindFirstFile handle */
int dd_stat; /* 0-based index */
char dd_name[MAX_PATH * 3]; /* file name (* 3 for UTF-8 conversion) */
struct dirent dd_dir; /* includes d_type */
} dirent_DIR;
DIR *(*opendir)(const char *dirname) = dirent_opendir;
@@ -95,10 +94,9 @@ DIR *dirent_opendir(const char *name)
}
/* initialize DIR structure and copy first dir entry */
dir = xmalloc(sizeof(dirent_DIR));
dir = xmalloc(sizeof(dirent_DIR) + MAX_LONG_PATH);
dir->base_dir.preaddir = (struct dirent *(*)(DIR *dir)) dirent_readdir;
dir->base_dir.pclosedir = (int (*)(DIR *dir)) dirent_closedir;
dir->dd_dir.d_name = dir->dd_name;
dir->dd_handle = h;
dir->dd_stat = 0;
finddata2dirent(&dir->dd_dir, &fdata);

View File

@@ -8,7 +8,7 @@
struct dirent {
unsigned char d_type; /* file type to prevent lstat after readdir */
char *d_name; /* file name */
char d_name[FLEX_ARRAY]; /* file name */
};
/*