Commit 0234c186bacb5144ca13f69f0dc9bfcc8ec7a075

Ramsay Jones 2009-03-20T19:52:50

win32: Add <dirent.h> directory reading routines Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>

diff --git a/src/dir.h b/src/dir.h
new file mode 100644
index 0000000..62ee0b8
--- /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 <dirent.h>
+#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 39e0181..0392558 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -11,10 +11,10 @@
 
 #include "common.h"
 #include "map.h"
+#include "dir.h"
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <time.h>
-#include <dirent.h>
 
 #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 0000000..00f43bf
--- /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;
+}
+