dir.c 2.2 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;
15

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

19 20 21
	dirlen = strlen(dir);

	new = git__calloc(sizeof(*new) + dirlen + 1, 1);
22 23
	if (!new)
		return NULL;
24
	memcpy(new->dir, dir, dirlen);
25

26 27
	new->h = FindFirstFileW(filter_w, &new->f);

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

34
	new->first = 1;
35 36 37
	return new;
}

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

47 48
	*result = NULL;

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

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

	entry->d_ino = 0;
63

64
	*result = entry;
65

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

69 70
	return 0;
}
71

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

80
void git__rewinddir(git__DIR *d)
81
{
82
	git_win32_path filter_w;
83

84 85 86 87 88
	if (!d)
		return;

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

93
	if (!git_win32__findfirstfile_filter(filter_w, d->dir))
94
		return;
95

96 97 98 99 100 101
	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;
102 103
}

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

	if (d->h != INVALID_HANDLE_VALUE) {
		FindClose(d->h);
		d->h = INVALID_HANDLE_VALUE;
112
	}
113

114
	git__free(d);
115 116 117
	return 0;
}