dir.c 2.3 KB
Newer Older
Vicent Marti committed
1
/*
Edward Thomson committed
2
 * Copyright (C) the libgit2 contributors. All rights reserved.
Vicent Marti committed
3 4 5 6
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */
7
#define GIT__WIN32_NO_WRAP_DIR
Vicent Marti committed
8
#include "posix.h"
9

10
git__DIR *git__opendir(const char *dir)
11
{
12
	git_win32_path filter_w;
13
	git__DIR *new = NULL;
14
	size_t dirlen, alloclen;
15

16
	if (!dir || !git_win32__findfirstfile_filter(filter_w, dir))
17 18
		return NULL;

19 20
	dirlen = strlen(dir);

21 22 23
	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, sizeof(*new), dirlen) ||
		GIT_ADD_SIZET_OVERFLOW(&alloclen, alloclen, 1) ||
		!(new = git__calloc(1, alloclen)))
24
		return NULL;
25

26
	memcpy(new->dir, dir, dirlen);
27

28 29
	new->h = FindFirstFileW(filter_w, &new->f);

30
	if (new->h == INVALID_HANDLE_VALUE) {
31
		giterr_set(GITERR_OS, "Could not open directory '%s'", dir);
32 33
		git__free(new);
		return NULL;
34 35
	}

36
	new->first = 1;
37 38 39
	return new;
}

40 41 42 43 44
int git__readdir_ext(
	git__DIR *d,
	struct git__dirent *entry,
	struct git__dirent **result,
	int *is_dir)
45
{
46 47
	if (!d || !entry || !result || d->h == INVALID_HANDLE_VALUE)
		return -1;
48

49 50
	*result = NULL;

51 52
	if (d->first)
		d->first = 0;
53
	else if (!FindNextFileW(d->h, &d->f)) {
54 55 56 57
		if (GetLastError() == ERROR_NO_MORE_FILES)
			return 0;
		giterr_set(GITERR_OS, "Could not read from directory '%s'", d->dir);
		return -1;
58 59
	}

60 61
	/* Convert the path to UTF-8 */
	if (git_win32_path_to_utf8(entry->d_name, d->f.cFileName) < 0)
62 63 64
		return -1;

	entry->d_ino = 0;
65

66
	*result = entry;
67

68 69 70
	if (is_dir != NULL)
		*is_dir = ((d->f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);

71 72
	return 0;
}
73

74 75 76
struct git__dirent *git__readdir(git__DIR *d)
{
	struct git__dirent *result;
77
	if (git__readdir_ext(d, &d->entry, &result, NULL) < 0)
78 79
		return NULL;
	return result;
80 81
}

82
void git__rewinddir(git__DIR *d)
83
{
84
	git_win32_path filter_w;
85

86 87 88 89 90
	if (!d)
		return;

	if (d->h != INVALID_HANDLE_VALUE) {
		FindClose(d->h);
91 92
		d->h = INVALID_HANDLE_VALUE;
		d->first = 0;
93
	}
94

95
	if (!git_win32__findfirstfile_filter(filter_w, d->dir))
96
		return;
97

98 99 100 101 102 103
	d->h = FindFirstFileW(filter_w, &d->f);

	if (d->h == INVALID_HANDLE_VALUE)
		giterr_set(GITERR_OS, "Could not open directory '%s'", d->dir);
	else
		d->first = 1;
104 105
}

106
int git__closedir(git__DIR *d)
107
{
108 109 110 111 112 113
	if (!d)
		return 0;

	if (d->h != INVALID_HANDLE_VALUE) {
		FindClose(d->h);
		d->h = INVALID_HANDLE_VALUE;
114
	}
115

116
	git__free(d);
117 118 119
	return 0;
}