mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-22 17:13:26 +00:00

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.
120 lines
2.3 KiB
C
120 lines
2.3 KiB
C
/*
|
|
* 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;
|
|
}
|
|
|