diff --git a/src/dir.h b/src/dir.h new file mode 100644 index 000000000..62ee0b899 --- /dev/null +++ b/src/dir.h @@ -0,0 +1,32 @@ +#ifndef INCLUDE_dir_h__ +#define INCLUDE_dir_h__ + +#include "common.h" + +#ifndef GIT_WIN32 +# include +#endif + +#ifdef GIT_WIN32 + +struct dirent { + int d_ino; + char d_name[261]; +}; + +typedef struct { + HANDLE h; + WIN32_FIND_DATA f; + struct dirent entry; + char *dir; + int first; +} DIR; + +extern DIR *opendir(const char *); +extern struct dirent *readdir(DIR *); +extern void rewinddir(DIR *); +extern int closedir(DIR *); + +#endif + +#endif /* INCLUDE_dir_h__ */ diff --git a/src/fileops.h b/src/fileops.h index 39e01811c..039255881 100644 --- a/src/fileops.h +++ b/src/fileops.h @@ -11,10 +11,10 @@ #include "common.h" #include "map.h" +#include "dir.h" #include #include #include -#include #if !defined(O_BINARY) #define O_BINARY 0 diff --git a/src/win32/dir.c b/src/win32/dir.c new file mode 100644 index 000000000..00f43bfc8 --- /dev/null +++ b/src/win32/dir.c @@ -0,0 +1,97 @@ +#include "dir.h" + +static int init_filter(char *filter, size_t n, const char *dir) +{ + int len = strlen(dir); + + if (len+3 >= n) + return 0; + + strcpy(filter, dir); + if (len && dir[len-1] != '/') + strcat(filter, "/"); + strcat(filter, "*"); + + return 1; +} + +DIR *opendir(const char *dir) +{ + char filter[4096]; + DIR *new; + + if (!dir || !init_filter(filter, sizeof(filter), dir)) + return NULL; + + new = git__malloc(sizeof(*new)); + if (!new) + return NULL; + + new->dir = git__malloc(strlen(dir)+1); + if (!new->dir) { + free(new); + return NULL; + } + strcpy(new->dir, dir); + + new->h = FindFirstFile(filter, &new->f); + if (new->h == INVALID_HANDLE_VALUE) { + free(new->dir); + free(new); + return NULL; + } + new->first = 1; + + return new; +} + +struct dirent *readdir(DIR *d) +{ + if (!d || d->h == INVALID_HANDLE_VALUE) + return NULL; + + if (d->first) + d->first = 0; + else { + if (!FindNextFile(d->h, &d->f)) + return NULL; + } + + if (strlen(d->f.cFileName) >= sizeof(d->entry.d_name)) + return NULL; + + d->entry.d_ino = 0; + strcpy(d->entry.d_name, d->f.cFileName); + + return &d->entry; +} + +void rewinddir(DIR *d) +{ + char filter[4096]; + + if (d) { + if (d->h != INVALID_HANDLE_VALUE) + FindClose(d->h); + d->h = INVALID_HANDLE_VALUE; + d->first = 0; + if (init_filter(filter, sizeof(filter), d->dir)) { + d->h = FindFirstFile(filter, &d->f); + if (d->h != INVALID_HANDLE_VALUE) + d->first = 1; + } + } +} + +int closedir(DIR *d) +{ + if (d) { + if (d->h != INVALID_HANDLE_VALUE) + FindClose(d->h); + if (d->dir) + free(d->dir); + free(d); + } + return 0; +} +