Hash :
f1453c59
Author :
Date :
2015-02-12T12:19:37
Make our overflow check look more like gcc/clang's Make our overflow checking look more like gcc and clang's, so that we can substitute it out with the compiler instrinsics on platforms that support it. This means dropping the ability to pass `NULL` as an out parameter. As a result, the macros also get updated to reflect this as well.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#define GIT__WIN32_NO_WRAP_DIR
#include "posix.h"
git__DIR *git__opendir(const char *dir)
{
git_win32_path filter_w;
git__DIR *new = NULL;
size_t dirlen, alloclen;
if (!dir || !git_win32__findfirstfile_filter(filter_w, dir))
return NULL;
dirlen = strlen(dir);
if (GIT_ADD_SIZET_OVERFLOW(&alloclen, sizeof(*new), dirlen) ||
GIT_ADD_SIZET_OVERFLOW(&alloclen, alloclen, 1) ||
!(new = git__calloc(1, alloclen)))
return NULL;
memcpy(new->dir, dir, dirlen);
new->h = FindFirstFileW(filter_w, &new->f);
if (new->h == INVALID_HANDLE_VALUE) {
giterr_set(GITERR_OS, "Could not open directory '%s'", dir);
git__free(new);
return NULL;
}
new->first = 1;
return new;
}
int git__readdir_ext(
git__DIR *d,
struct git__dirent *entry,
struct git__dirent **result,
int *is_dir)
{
if (!d || !entry || !result || d->h == INVALID_HANDLE_VALUE)
return -1;
*result = NULL;
if (d->first)
d->first = 0;
else if (!FindNextFileW(d->h, &d->f)) {
if (GetLastError() == ERROR_NO_MORE_FILES)
return 0;
giterr_set(GITERR_OS, "Could not read from directory '%s'", d->dir);
return -1;
}
/* Convert the path to UTF-8 */
if (git_win32_path_to_utf8(entry->d_name, d->f.cFileName) < 0)
return -1;
entry->d_ino = 0;
*result = entry;
if (is_dir != NULL)
*is_dir = ((d->f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
return 0;
}
struct git__dirent *git__readdir(git__DIR *d)
{
struct git__dirent *result;
if (git__readdir_ext(d, &d->entry, &result, NULL) < 0)
return NULL;
return result;
}
void git__rewinddir(git__DIR *d)
{
git_win32_path filter_w;
if (!d)
return;
if (d->h != INVALID_HANDLE_VALUE) {
FindClose(d->h);
d->h = INVALID_HANDLE_VALUE;
d->first = 0;
}
if (!git_win32__findfirstfile_filter(filter_w, d->dir))
return;
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;
}
int git__closedir(git__DIR *d)
{
if (!d)
return 0;
if (d->h != INVALID_HANDLE_VALUE) {
FindClose(d->h);
d->h = INVALID_HANDLE_VALUE;
}
git__free(d);
return 0;
}