mirror of
https://git.proxmox.com/git/libgit2
synced 2025-12-26 15:59:05 +00:00
Continue error conversion
This converts blob.c, fileops.c, and all of the win32 files. Also, various minor cleanups throughout the code. Plus, in testing the win32 build, I cleaned up a bunch (although not all) of the warnings with the 64-bit build.
This commit is contained in:
parent
ab43ad2fd8
commit
deafee7bd7
110
src/blob.c
110
src/blob.c
@ -42,7 +42,7 @@ int git_blob__parse(git_blob *blob, git_odb_object *odb_obj)
|
||||
assert(blob);
|
||||
git_cached_obj_incref((git_cached_obj *)odb_obj);
|
||||
blob->odb_object = odb_obj;
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len)
|
||||
@ -51,58 +51,50 @@ int git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *b
|
||||
git_odb *odb;
|
||||
git_odb_stream *stream;
|
||||
|
||||
error = git_repository_odb__weakptr(&odb, repo);
|
||||
if (error < GIT_SUCCESS)
|
||||
if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
|
||||
(error = git_odb_open_wstream(&stream, odb, len, GIT_OBJ_BLOB)) < 0)
|
||||
return error;
|
||||
|
||||
if ((error = git_odb_open_wstream(&stream, odb, len, GIT_OBJ_BLOB)) < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create blob");
|
||||
if ((error = stream->write(stream, buffer, len)) == 0)
|
||||
error = stream->finalize_write(oid, stream);
|
||||
|
||||
if ((error = stream->write(stream, buffer, len)) < GIT_SUCCESS) {
|
||||
stream->free(stream);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = stream->finalize_write(oid, stream);
|
||||
stream->free(stream);
|
||||
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create blob");
|
||||
|
||||
return GIT_SUCCESS;
|
||||
return error;
|
||||
}
|
||||
|
||||
static int write_file_stream(git_oid *oid, git_odb *odb, const char *path, git_off_t file_size)
|
||||
static int write_file_stream(
|
||||
git_oid *oid, git_odb *odb, const char *path, git_off_t file_size)
|
||||
{
|
||||
int fd, error;
|
||||
char buffer[4096];
|
||||
git_odb_stream *stream = NULL;
|
||||
|
||||
if ((error = git_odb_open_wstream(&stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < GIT_SUCCESS)
|
||||
if ((error = git_odb_open_wstream(
|
||||
&stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < 0)
|
||||
return error;
|
||||
|
||||
if ((fd = p_open(path, O_RDONLY)) < 0) {
|
||||
error = git__throw(GIT_ENOTFOUND, "Failed to create blob. Could not open '%s'", path);
|
||||
goto cleanup;
|
||||
if ((fd = git_futils_open_ro(path)) < 0) {
|
||||
stream->free(stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (file_size > 0) {
|
||||
while (!error && file_size > 0) {
|
||||
ssize_t read_len = p_read(fd, buffer, sizeof(buffer));
|
||||
|
||||
if (read_len < 0) {
|
||||
error = git__throw(GIT_EOSERR, "Failed to create blob. Can't read full file");
|
||||
p_close(fd);
|
||||
goto cleanup;
|
||||
giterr_set(
|
||||
GITERR_OS, "Failed to create blob. Can't read whole file");
|
||||
error = -1;
|
||||
}
|
||||
|
||||
stream->write(stream, buffer, read_len);
|
||||
file_size -= read_len;
|
||||
else if (!(error = stream->write(stream, buffer, read_len)))
|
||||
file_size -= read_len;
|
||||
}
|
||||
|
||||
p_close(fd);
|
||||
error = stream->finalize_write(oid, stream);
|
||||
|
||||
cleanup:
|
||||
if (!error)
|
||||
error = stream->finalize_write(oid, stream);
|
||||
|
||||
stream->free(stream);
|
||||
return error;
|
||||
}
|
||||
@ -117,8 +109,7 @@ static int write_file_filtered(
|
||||
git_buf source = GIT_BUF_INIT;
|
||||
git_buf dest = GIT_BUF_INIT;
|
||||
|
||||
error = git_futils_readbuffer(&source, full_path);
|
||||
if (error < GIT_SUCCESS)
|
||||
if ((error = git_futils_readbuffer(&source, full_path)) < 0)
|
||||
return error;
|
||||
|
||||
error = git_filters_apply(&dest, &source, filters);
|
||||
@ -127,30 +118,29 @@ static int write_file_filtered(
|
||||
* and we don't want to ODB write to choke */
|
||||
git_buf_free(&source);
|
||||
|
||||
if (error == GIT_SUCCESS) {
|
||||
/* Write the file to disk if it was properly filtered */
|
||||
/* Write the file to disk if it was properly filtered */
|
||||
if (!error)
|
||||
error = git_odb_write(oid, odb, dest.ptr, dest.size, GIT_OBJ_BLOB);
|
||||
}
|
||||
|
||||
git_buf_free(&dest);
|
||||
return GIT_SUCCESS;
|
||||
return error;
|
||||
}
|
||||
|
||||
static int write_symlink(git_oid *oid, git_odb *odb, const char *path, size_t link_size)
|
||||
static int write_symlink(
|
||||
git_oid *oid, git_odb *odb, const char *path, size_t link_size)
|
||||
{
|
||||
char *link_data;
|
||||
ssize_t read_len;
|
||||
int error;
|
||||
|
||||
link_data = git__malloc(link_size);
|
||||
if (!link_data)
|
||||
return GIT_ENOMEM;
|
||||
GITERR_CHECK_ALLOC(link_data);
|
||||
|
||||
read_len = p_readlink(path, link_data, link_size);
|
||||
|
||||
if (read_len != (ssize_t)link_size) {
|
||||
giterr_set(GITERR_OS, "Failed to create blob. Can't read symlink '%s'", path);
|
||||
free(link_data);
|
||||
return git__throw(GIT_EOSERR, "Failed to create blob. Can't read symlink");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = git_odb_write(oid, odb, (void *)link_data, link_size, GIT_OBJ_BLOB);
|
||||
@ -168,25 +158,18 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
|
||||
git_odb *odb = NULL;
|
||||
|
||||
workdir = git_repository_workdir(repo);
|
||||
if (workdir == NULL)
|
||||
return git__throw(GIT_ENOTFOUND, "Failed to create blob. (No working directory found)");
|
||||
assert(workdir); /* error to call this on bare repo */
|
||||
|
||||
error = git_buf_joinpath(&full_path, workdir, path);
|
||||
if (error < GIT_SUCCESS)
|
||||
if ((error = git_buf_joinpath(&full_path, workdir, path)) < 0 ||
|
||||
(error = git_path_lstat(full_path.ptr, &st)) < 0 ||
|
||||
(error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||
{
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
|
||||
error = p_lstat(full_path.ptr, &st);
|
||||
if (error < 0) {
|
||||
error = git__throw(GIT_EOSERR, "Failed to stat blob. %s", strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
size = st.st_size;
|
||||
|
||||
error = git_repository_odb__weakptr(&odb, repo);
|
||||
if (error < GIT_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
error = write_symlink(oid, odb, full_path.ptr, (size_t)size);
|
||||
} else {
|
||||
@ -194,12 +177,12 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
|
||||
int filter_count;
|
||||
|
||||
/* Load the filters for writing this file to the ODB */
|
||||
filter_count = git_filters_load(&write_filters, repo, path, GIT_FILTER_TO_ODB);
|
||||
filter_count = git_filters_load(
|
||||
&write_filters, repo, path, GIT_FILTER_TO_ODB);
|
||||
|
||||
if (filter_count < 0) {
|
||||
/* Negative value means there was a critical error */
|
||||
error = filter_count;
|
||||
goto cleanup;
|
||||
} else if (filter_count == 0) {
|
||||
/* No filters need to be applied to the document: we can stream
|
||||
* directly from disk */
|
||||
@ -212,19 +195,20 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
|
||||
git_filters_free(&write_filters);
|
||||
|
||||
/*
|
||||
* TODO: eventually support streaming filtered files, for files which are bigger
|
||||
* than a given threshold. This is not a priority because applying a filter in
|
||||
* streaming mode changes the final size of the blob, and without knowing its
|
||||
* final size, the blob cannot be written in stream mode to the ODB.
|
||||
* TODO: eventually support streaming filtered files, for files
|
||||
* which are bigger than a given threshold. This is not a priority
|
||||
* because applying a filter in streaming mode changes the final
|
||||
* size of the blob, and without knowing its final size, the blob
|
||||
* cannot be written in stream mode to the ODB.
|
||||
*
|
||||
* The plan is to do streaming writes to a tempfile on disk and then opening
|
||||
* streaming that file to the ODB, using `write_file_stream`.
|
||||
* The plan is to do streaming writes to a tempfile on disk and then
|
||||
* opening streaming that file to the ODB, using
|
||||
* `write_file_stream`.
|
||||
*
|
||||
* CAREFULLY DESIGNED APIS YO
|
||||
*/
|
||||
}
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -215,8 +215,8 @@ void git_buf_truncate(git_buf *buf, size_t len)
|
||||
|
||||
void git_buf_rtruncate_at_char(git_buf *buf, char separator)
|
||||
{
|
||||
int idx = git_buf_rfind_next(buf, separator);
|
||||
git_buf_truncate(buf, idx < 0 ? 0 : idx);
|
||||
ssize_t idx = git_buf_rfind_next(buf, separator);
|
||||
git_buf_truncate(buf, idx < 0 ? 0 : (size_t)idx);
|
||||
}
|
||||
|
||||
void git_buf_swap(git_buf *buf_a, git_buf *buf_b)
|
||||
|
||||
@ -102,9 +102,9 @@ void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf);
|
||||
|
||||
#define git_buf_PUTS(buf, str) git_buf_put(buf, str, sizeof(str) - 1)
|
||||
|
||||
GIT_INLINE(int) git_buf_rfind_next(git_buf *buf, char ch)
|
||||
GIT_INLINE(ssize_t) git_buf_rfind_next(git_buf *buf, char ch)
|
||||
{
|
||||
int idx = buf->size - 1;
|
||||
ssize_t idx = (ssize_t)buf->size - 1;
|
||||
while (idx >= 0 && buf->ptr[idx] == ch) idx--;
|
||||
while (idx >= 0 && buf->ptr[idx] != ch) idx--;
|
||||
return idx;
|
||||
|
||||
@ -79,11 +79,25 @@ int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, con
|
||||
return git_futils_creat_locked(path, mode);
|
||||
}
|
||||
|
||||
int git_futils_open_ro(const char *path)
|
||||
{
|
||||
int fd = p_open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
fd = GIT_ENOTFOUND;
|
||||
giterr_set(GITERR_OS, "Failed to open '%s'", path);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
git_off_t git_futils_filesize(git_file fd)
|
||||
{
|
||||
struct stat sb;
|
||||
if (p_fstat(fd, &sb))
|
||||
return GIT_ERROR;
|
||||
|
||||
if (p_fstat(fd, &sb)) {
|
||||
giterr_set(GITERR_OS, "Failed to stat file descriptor");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sb.st_size;
|
||||
}
|
||||
@ -176,10 +190,15 @@ int git_futils_readbuffer(git_buf *buf, const char *path)
|
||||
|
||||
int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmode)
|
||||
{
|
||||
if (git_futils_mkpath2file(to, dirmode) < GIT_SUCCESS)
|
||||
return GIT_EOSERR; /* The callee already takes care of setting the correct error message. */
|
||||
if (git_futils_mkpath2file(to, dirmode) < 0)
|
||||
return -1;
|
||||
|
||||
return p_rename(from, to); /* The callee already takes care of setting the correct error message. */
|
||||
if (p_rename(from, to) < 0) {
|
||||
giterr_set(GITERR_OS, "Failed to rename '%s' to '%s'", from, to);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_futils_mmap_ro(git_map *out, git_file fd, git_off_t begin, size_t len)
|
||||
@ -192,8 +211,10 @@ int git_futils_mmap_ro_file(git_map *out, const char *path)
|
||||
git_file fd = p_open(path, O_RDONLY /* | O_NOATIME */);
|
||||
git_off_t len = git_futils_filesize(fd);
|
||||
int result;
|
||||
if (!git__is_sizet(len))
|
||||
return git__throw(GIT_ERROR, "File `%s` too large to mmap", path);
|
||||
if (!git__is_sizet(len)) {
|
||||
giterr_set(GITERR_OS, "File `%s` too large to mmap", path);
|
||||
return -1;
|
||||
}
|
||||
result = git_futils_mmap_ro(out, fd, 0, (size_t)len);
|
||||
p_close(fd);
|
||||
return result;
|
||||
@ -260,20 +281,31 @@ int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode)
|
||||
|
||||
static int _rmdir_recurs_foreach(void *opaque, git_buf *path)
|
||||
{
|
||||
int error = GIT_SUCCESS;
|
||||
int force = *(int *)opaque;
|
||||
|
||||
if (git_path_isdir(path->ptr) == true) {
|
||||
error = git_path_direach(path, _rmdir_recurs_foreach, opaque);
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to remove directory `%s`", path->ptr);
|
||||
return p_rmdir(path->ptr);
|
||||
if (git_path_direach(path, _rmdir_recurs_foreach, opaque) < 0)
|
||||
return -1;
|
||||
|
||||
} else if (force) {
|
||||
return p_unlink(path->ptr);
|
||||
if (p_rmdir(path->ptr) < 0) {
|
||||
giterr_set(GITERR_OS, "Could not remove directory '%s'", path->ptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git__rethrow(error, "Failed to remove directory. `%s` is not empty", path->ptr);
|
||||
if (force) {
|
||||
if (p_unlink(path->ptr) < 0) {
|
||||
giterr_set(GITERR_OS, "Could not remove directory. File '%s' cannot be removed", path->ptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
giterr_set(GITERR_OS, "Could not remove directory. File '%s' still present", path->ptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_futils_rmdir_r(const char *path, int force)
|
||||
@ -282,7 +314,7 @@ int git_futils_rmdir_r(const char *path, int force)
|
||||
git_buf p = GIT_BUF_INIT;
|
||||
|
||||
error = git_buf_sets(&p, path);
|
||||
if (error == GIT_SUCCESS)
|
||||
if (!error)
|
||||
error = _rmdir_recurs_foreach(&force, &p);
|
||||
git_buf_free(&p);
|
||||
return error;
|
||||
@ -328,9 +360,8 @@ static const win32_path *win32_system_root(void)
|
||||
const wchar_t *root_tmpl = L"%PROGRAMFILES%\\Git\\etc\\";
|
||||
|
||||
s_root.len = ExpandEnvironmentStringsW(root_tmpl, NULL, 0);
|
||||
|
||||
if (s_root.len <= 0) {
|
||||
git__throw(GIT_EOSERR, "Failed to expand environment strings");
|
||||
giterr_set(GITERR_OS, "Failed to expand environment strings");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -339,7 +370,7 @@ static const win32_path *win32_system_root(void)
|
||||
return NULL;
|
||||
|
||||
if (ExpandEnvironmentStringsW(root_tmpl, s_root.path, s_root.len) != s_root.len) {
|
||||
git__throw(GIT_EOSERR, "Failed to expand environment strings");
|
||||
giterr_set(GITERR_OS, "Failed to expand environment strings");
|
||||
git__free(s_root.path);
|
||||
s_root.path = NULL;
|
||||
return NULL;
|
||||
@ -351,7 +382,7 @@ static const win32_path *win32_system_root(void)
|
||||
|
||||
static int win32_find_system_file(git_buf *path, const char *filename)
|
||||
{
|
||||
int error = GIT_SUCCESS;
|
||||
int error = 0;
|
||||
const win32_path *root = win32_system_root();
|
||||
size_t len;
|
||||
wchar_t *file_utf16 = NULL, *scan;
|
||||
@ -362,8 +393,7 @@ static int win32_find_system_file(git_buf *path, const char *filename)
|
||||
|
||||
/* allocate space for wchar_t path to file */
|
||||
file_utf16 = git__calloc(root->len + len + 2, sizeof(wchar_t));
|
||||
if (!file_utf16)
|
||||
return GIT_ENOMEM;
|
||||
GITERR_CHECK_ALLOC(file_utf16);
|
||||
|
||||
/* append root + '\\' + filename as wchar_t */
|
||||
memcpy(file_utf16, root->path, root->len * sizeof(wchar_t));
|
||||
@ -373,7 +403,7 @@ static int win32_find_system_file(git_buf *path, const char *filename)
|
||||
|
||||
if (gitwin_append_utf16(file_utf16 + root->len - 1, filename, len + 1) !=
|
||||
(int)len + 1) {
|
||||
error = git__throw(GIT_EOSERR, "Failed to build file path");
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -389,9 +419,8 @@ static int win32_find_system_file(git_buf *path, const char *filename)
|
||||
|
||||
/* convert to utf8 */
|
||||
if ((file_utf8 = gitwin_from_utf16(file_utf16)) == NULL)
|
||||
error = GIT_ENOMEM;
|
||||
|
||||
if (file_utf8) {
|
||||
error = -1;
|
||||
else {
|
||||
git_path_mkposix(file_utf8);
|
||||
git_buf_attach(path, file_utf8, 0);
|
||||
}
|
||||
@ -409,7 +438,7 @@ int git_futils_find_system_file(git_buf *path, const char *filename)
|
||||
return -1;
|
||||
|
||||
if (git_path_exists(path->ptr) == true)
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
|
||||
git_buf_clear(path);
|
||||
|
||||
|
||||
@ -77,18 +77,9 @@ extern int git_futils_mktmp(git_buf *path_out, const char *filename);
|
||||
extern int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmode);
|
||||
|
||||
/**
|
||||
* Open a file readonly and set error if needed
|
||||
* Open a file readonly and set error if needed.
|
||||
*/
|
||||
GIT_INLINE(int) git_futils_open_ro(const char *path)
|
||||
{
|
||||
int fd = p_open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
fd = GIT_ENOTFOUND;
|
||||
giterr_set(GITERR_OS, "Failed to open '%s'", path);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
extern int git_futils_open_ro(const char *path);
|
||||
|
||||
/**
|
||||
* Get the filesize in bytes of a file
|
||||
|
||||
@ -258,5 +258,10 @@ uint32_t git_hash__strhash_cb(const void *key, int hash_id)
|
||||
0x7daaab3c
|
||||
};
|
||||
|
||||
return git__hash(key, strlen((const char *)key), hash_seeds[hash_id]);
|
||||
size_t key_len = strlen((const char *)key);
|
||||
|
||||
/* won't take hash of strings longer than 2^31 right now */
|
||||
assert(key_len == (size_t)((int)key_len));
|
||||
|
||||
return git__hash(key, (int)key_len, hash_seeds[hash_id]);
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ GIT_INLINE(int) git_hashtable_insert(git_hashtable *h, const void *key, void *va
|
||||
#define git_hashtable_node_at(nodes, pos) ((git_hashtable_node *)(&nodes[pos]))
|
||||
|
||||
#define GIT_HASHTABLE__FOREACH(self,block) { \
|
||||
unsigned int _c; \
|
||||
size_t _c; \
|
||||
git_hashtable_node *_n = (self)->nodes; \
|
||||
for (_c = (self)->size; _c > 0; _c--, _n++) { \
|
||||
if (!_n->key) continue; block } }
|
||||
|
||||
@ -319,8 +319,7 @@ static int index_entry_init(git_index_entry **entry_out, git_index *index, const
|
||||
if (error < GIT_SUCCESS)
|
||||
return error;
|
||||
|
||||
if (p_lstat(full_path.ptr, &st) < 0) {
|
||||
error = git__throw(GIT_ENOTFOUND, "Failed to initialize entry. '%s' cannot be opened. %s", full_path.ptr, strerror(errno));
|
||||
if ((error = git_path_lstat(full_path.ptr, &st)) < 0) {
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -133,12 +133,15 @@ int git_indexer_new(git_indexer **out, const char *packname)
|
||||
|
||||
idx->nr_objects = ntohl(idx->hdr.hdr_entries);
|
||||
|
||||
error = git_vector_init(&idx->pack->cache, idx->nr_objects, cache_cmp);
|
||||
/* for now, limit to 2^32 objects */
|
||||
assert(idx->nr_objects == (size_t)((unsigned int)idx->nr_objects));
|
||||
|
||||
error = git_vector_init(&idx->pack->cache, (unsigned int)idx->nr_objects, cache_cmp);
|
||||
if (error < GIT_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
idx->pack->has_cache = 1;
|
||||
error = git_vector_init(&idx->objects, idx->nr_objects, objects_cmp);
|
||||
error = git_vector_init(&idx->objects, (unsigned int)idx->nr_objects, objects_cmp);
|
||||
if (error < GIT_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
@ -319,7 +322,7 @@ int git_indexer_run(git_indexer *idx, git_indexer_stats *stats)
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to register mwindow file");
|
||||
|
||||
stats->total = idx->nr_objects;
|
||||
stats->total = (unsigned int)idx->nr_objects;
|
||||
stats->processed = processed = 0;
|
||||
|
||||
while (processed < idx->nr_objects) {
|
||||
@ -375,7 +378,7 @@ int git_indexer_run(git_indexer *idx, git_indexer_stats *stats)
|
||||
error = git__rethrow(error, "Failed to open window to read packed data");
|
||||
goto cleanup;
|
||||
}
|
||||
entry->crc = htonl(crc32(entry->crc, packed, entry_size));
|
||||
entry->crc = htonl(crc32(entry->crc, packed, (uInt)entry_size));
|
||||
git_mwindow_close(&w);
|
||||
|
||||
/* Add the object to the list */
|
||||
|
||||
@ -309,7 +309,7 @@ static int workdir_iterator__expand_dir(workdir_iterator *wi)
|
||||
|
||||
/* only push new ignores if this is not top level directory */
|
||||
if (wi->stack->next != NULL) {
|
||||
int slash_pos = git_buf_rfind_next(&wi->path, '/');
|
||||
ssize_t slash_pos = git_buf_rfind_next(&wi->path, '/');
|
||||
(void)git_ignore__push_dir(&wi->ignores, &wi->path.ptr[slash_pos + 1]);
|
||||
}
|
||||
|
||||
|
||||
@ -203,7 +203,7 @@ unsigned char *git_mwindow_open(
|
||||
git_mwindow_file *mwf,
|
||||
git_mwindow **cursor,
|
||||
git_off_t offset,
|
||||
int extra,
|
||||
size_t extra,
|
||||
unsigned int *left)
|
||||
{
|
||||
git_mwindow_ctl *ctl = &GIT_GLOBAL->mem_ctl;
|
||||
|
||||
@ -15,8 +15,8 @@ typedef struct git_mwindow {
|
||||
struct git_mwindow *next;
|
||||
git_map window_map;
|
||||
git_off_t offset;
|
||||
unsigned int last_used;
|
||||
unsigned int inuse_cnt;
|
||||
size_t last_used;
|
||||
size_t inuse_cnt;
|
||||
} git_mwindow;
|
||||
|
||||
typedef struct git_mwindow_file {
|
||||
@ -37,7 +37,7 @@ typedef struct git_mwindow_ctl {
|
||||
|
||||
int git_mwindow_contains(git_mwindow *win, git_off_t offset);
|
||||
void git_mwindow_free_all(git_mwindow_file *mwf);
|
||||
unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, git_off_t offset, int extra, unsigned int *left);
|
||||
unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, git_off_t offset, size_t extra, unsigned int *left);
|
||||
void git_mwindow_scan_lru(git_mwindow_file *mwf, git_mwindow **lru_w, git_mwindow **lru_l);
|
||||
int git_mwindow_file_register(git_mwindow_file *mwf);
|
||||
void git_mwindow_close(git_mwindow **w_cursor);
|
||||
|
||||
@ -145,10 +145,8 @@ int git_odb__hashlink(git_oid *out, const char *path)
|
||||
git_off_t size;
|
||||
int result;
|
||||
|
||||
if (p_lstat(path, &st) < 0) {
|
||||
giterr_set(GITERR_OS, "Failed to stat object '%s'", path);
|
||||
if (git_path_lstat(path, &st) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
size = st.st_size;
|
||||
|
||||
|
||||
37
src/path.c
37
src/path.c
@ -49,7 +49,8 @@ int git_path_basename_r(git_buf *buffer, const char *path)
|
||||
while (startp > path && *(startp - 1) != '/')
|
||||
startp--;
|
||||
|
||||
len = endp - startp +1;
|
||||
/* Cast is safe because max path < max int */
|
||||
len = (int)(endp - startp + 1);
|
||||
|
||||
Exit:
|
||||
result = len;
|
||||
@ -96,7 +97,8 @@ int git_path_dirname_r(git_buf *buffer, const char *path)
|
||||
endp--;
|
||||
} while (endp > path && *endp == '/');
|
||||
|
||||
len = endp - path +1;
|
||||
/* Cast is safe because max path < max int */
|
||||
len = (int)(endp - path + 1);
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
/* Mimic unix behavior where '/.git' returns '/': 'C:/.git' will return
|
||||
@ -146,7 +148,7 @@ char *git_path_basename(const char *path)
|
||||
const char *git_path_topdir(const char *path)
|
||||
{
|
||||
size_t len;
|
||||
int i;
|
||||
ssize_t i;
|
||||
|
||||
assert(path);
|
||||
len = strlen(path);
|
||||
@ -154,7 +156,7 @@ const char *git_path_topdir(const char *path)
|
||||
if (!len || path[len - 1] != '/')
|
||||
return NULL;
|
||||
|
||||
for (i = len - 2; i >= 0; --i)
|
||||
for (i = (ssize_t)len - 2; i >= 0; --i)
|
||||
if (path[i] == '/')
|
||||
break;
|
||||
|
||||
@ -235,7 +237,7 @@ int git__percent_decode(git_buf *decoded_out, const char *input)
|
||||
int len, hi, lo, i;
|
||||
assert(decoded_out && input);
|
||||
|
||||
len = strlen(input);
|
||||
len = (int)strlen(input);
|
||||
git_buf_clear(decoded_out);
|
||||
|
||||
for(i = 0; i < len; i++)
|
||||
@ -281,7 +283,7 @@ int git_path_fromurl(git_buf *local_path_out, const char *file_url)
|
||||
return error_invalid_local_file_uri(file_url);
|
||||
|
||||
offset += 7;
|
||||
len = strlen(file_url);
|
||||
len = (int)strlen(file_url);
|
||||
|
||||
if (offset < len && file_url[offset] == '/')
|
||||
offset++;
|
||||
@ -381,6 +383,18 @@ bool git_path_isfile(const char *path)
|
||||
return S_ISREG(st.st_mode) != 0;
|
||||
}
|
||||
|
||||
int git_path_lstat(const char *path, struct stat *st)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (p_lstat(path, st) < 0) {
|
||||
err = (errno == ENOENT) ? GIT_ENOTFOUND : -1;
|
||||
giterr_set(GITERR_OS, "Failed to stat file '%s'", path);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool _check_dir_contents(
|
||||
git_buf *dir,
|
||||
const char *sub,
|
||||
@ -600,16 +614,9 @@ int git_path_dirload_with_stat(
|
||||
memmove(ps->path, ps, path_len + 1);
|
||||
ps->path_len = path_len;
|
||||
|
||||
if (git_buf_joinpath(&full, full.ptr, ps->path) < 0) {
|
||||
error = -1;
|
||||
if ((error = git_buf_joinpath(&full, full.ptr, ps->path)) < 0 ||
|
||||
(error = git_path_lstat(full.ptr, &ps->st)) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_lstat(full.ptr, &ps->st) < 0) {
|
||||
giterr_set(GITERR_OS, "Failed to stat file '%s'", full.ptr);
|
||||
error = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
git_buf_truncate(&full, prefix_len);
|
||||
|
||||
|
||||
@ -129,6 +129,11 @@ extern bool git_path_isdir(const char *path);
|
||||
*/
|
||||
extern bool git_path_isfile(const char *path);
|
||||
|
||||
/**
|
||||
* Stat a file and/or link and set error if needed.
|
||||
*/
|
||||
extern int git_path_lstat(const char *path, struct stat *st);
|
||||
|
||||
/**
|
||||
* Check if the parent directory contains the item.
|
||||
*
|
||||
|
||||
@ -34,9 +34,9 @@ int p_getcwd(char *buffer_out, size_t size)
|
||||
return -1;
|
||||
|
||||
git_path_mkposix(buffer_out);
|
||||
git_path_string_to_dir(buffer_out, size); //Ensure the path ends with a trailing slash
|
||||
git_path_string_to_dir(buffer_out, size); /* append trailing slash */
|
||||
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int p_rename(const char *from, const char *to)
|
||||
|
||||
@ -377,17 +377,15 @@ void git_repository_set_index(git_repository *repo, git_index *index)
|
||||
|
||||
static int retrieve_device(dev_t *device_out, const char *path)
|
||||
{
|
||||
int error;
|
||||
struct stat path_info;
|
||||
|
||||
assert(device_out);
|
||||
|
||||
if (p_lstat(path, &path_info)) {
|
||||
giterr_set(GITERR_OS, "Failed to retrieve file information: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if ((error = git_path_lstat(path, &path_info)) == 0)
|
||||
*device_out = path_info.st_dev;
|
||||
|
||||
*device_out = path_info.st_dev;
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -27,8 +27,8 @@ static int init_filter(char *filter, size_t n, const char *dir)
|
||||
git__DIR *git__opendir(const char *dir)
|
||||
{
|
||||
char filter[4096];
|
||||
wchar_t* filter_w;
|
||||
git__DIR *new;
|
||||
wchar_t* filter_w = NULL;
|
||||
git__DIR *new = NULL;
|
||||
|
||||
if (!dir || !init_filter(filter, sizeof(filter), dir))
|
||||
return NULL;
|
||||
@ -37,25 +37,29 @@ git__DIR *git__opendir(const char *dir)
|
||||
if (!new)
|
||||
return NULL;
|
||||
|
||||
new->dir = git__malloc(strlen(dir)+1);
|
||||
if (!new->dir) {
|
||||
git__free(new);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(new->dir, dir);
|
||||
new->dir = git__strdup(dir);
|
||||
if (!new->dir)
|
||||
goto fail;
|
||||
|
||||
filter_w = gitwin_to_utf16(filter);
|
||||
if (!filter_w)
|
||||
goto fail;
|
||||
|
||||
new->h = FindFirstFileW(filter_w, &new->f);
|
||||
git__free(filter_w);
|
||||
|
||||
if (new->h == INVALID_HANDLE_VALUE) {
|
||||
git__free(new->dir);
|
||||
git__free(new);
|
||||
return NULL;
|
||||
giterr_set(GITERR_OS, "Could not open directory '%s'", dir);
|
||||
goto fail;
|
||||
}
|
||||
new->first = 1;
|
||||
|
||||
new->first = 1;
|
||||
return new;
|
||||
|
||||
fail:
|
||||
git__free(new->dir);
|
||||
git__free(new);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int git__readdir_ext(
|
||||
@ -67,22 +71,32 @@ int git__readdir_ext(
|
||||
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)) {
|
||||
*result = NULL;
|
||||
return 0;
|
||||
if (GetLastError() == ERROR_NO_MORE_FILES)
|
||||
return 0;
|
||||
giterr_set(GITERR_OS, "Could not read from directory '%s'", d->dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wcslen(d->f.cFileName) >= sizeof(entry->d_name))
|
||||
return -1;
|
||||
|
||||
entry->d_ino = 0;
|
||||
WideCharToMultiByte(
|
||||
|
||||
if (WideCharToMultiByte(
|
||||
gitwin_get_codepage(), 0, d->f.cFileName, -1,
|
||||
entry->d_name, GIT_PATH_MAX, NULL, NULL);
|
||||
entry->d_name, GIT_PATH_MAX, NULL, NULL) == 0)
|
||||
{
|
||||
giterr_set(GITERR_OS, "Could not convert filename to UTF-8");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*result = entry;
|
||||
|
||||
if (is_dir != NULL)
|
||||
*is_dir = ((d->f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
|
||||
|
||||
@ -102,32 +116,40 @@ void git__rewinddir(git__DIR *d)
|
||||
char filter[4096];
|
||||
wchar_t* filter_w;
|
||||
|
||||
if (d) {
|
||||
if (d->h != INVALID_HANDLE_VALUE)
|
||||
FindClose(d->h);
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
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)) {
|
||||
filter_w = gitwin_to_utf16(filter);
|
||||
d->h = FindFirstFileW(filter_w, &d->f);
|
||||
git__free(filter_w);
|
||||
|
||||
if (d->h != INVALID_HANDLE_VALUE)
|
||||
d->first = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!init_filter(filter, sizeof(filter), d->dir) ||
|
||||
(filter_w = gitwin_to_utf16(filter)) == NULL)
|
||||
return;
|
||||
|
||||
d->h = FindFirstFileW(filter_w, &d->f);
|
||||
git__free(filter_w);
|
||||
|
||||
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) {
|
||||
if (d->h != INVALID_HANDLE_VALUE)
|
||||
FindClose(d->h);
|
||||
if (d->dir)
|
||||
git__free(d->dir);
|
||||
git__free(d);
|
||||
if (!d)
|
||||
return 0;
|
||||
|
||||
if (d->h != INVALID_HANDLE_VALUE) {
|
||||
FindClose(d->h);
|
||||
d->h = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
git__free(d->dir);
|
||||
d->dir = NULL;
|
||||
git__free(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -17,10 +17,11 @@ int p_unlink(const char *path)
|
||||
int ret = 0;
|
||||
wchar_t* buf;
|
||||
|
||||
buf = gitwin_to_utf16(path);
|
||||
_wchmod(buf, 0666);
|
||||
ret = _wunlink(buf);
|
||||
git__free(buf);
|
||||
if ((buf = gitwin_to_utf16(path)) != NULL) {
|
||||
_wchmod(buf, 0666);
|
||||
ret = _wunlink(buf);
|
||||
git__free(buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -60,6 +61,8 @@ static int do_lstat(const char *file_name, struct stat *buf)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA fdata;
|
||||
wchar_t* fbuf = gitwin_to_utf16(file_name);
|
||||
if (!fbuf)
|
||||
return -1;
|
||||
|
||||
if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) {
|
||||
int fMode = S_IREAD;
|
||||
@ -87,54 +90,43 @@ static int do_lstat(const char *file_name, struct stat *buf)
|
||||
buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
|
||||
|
||||
git__free(fbuf);
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
git__free(fbuf);
|
||||
|
||||
switch (GetLastError()) {
|
||||
case ERROR_ACCESS_DENIED:
|
||||
case ERROR_SHARING_VIOLATION:
|
||||
case ERROR_LOCK_VIOLATION:
|
||||
case ERROR_SHARING_BUFFER_EXCEEDED:
|
||||
return GIT_EOSERR;
|
||||
|
||||
case ERROR_BUFFER_OVERFLOW:
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
return GIT_ENOMEM;
|
||||
|
||||
default:
|
||||
return GIT_EINVALIDPATH;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int p_lstat(const char *file_name, struct stat *buf)
|
||||
{
|
||||
int namelen, error;
|
||||
char alt_name[GIT_PATH_MAX];
|
||||
int error;
|
||||
size_t namelen;
|
||||
char *alt_name;
|
||||
|
||||
if ((error = do_lstat(file_name, buf)) == GIT_SUCCESS)
|
||||
return GIT_SUCCESS;
|
||||
if (do_lstat(file_name, buf) == 0)
|
||||
return 0;
|
||||
|
||||
/* if file_name ended in a '/', Windows returned ENOENT;
|
||||
* try again without trailing slashes
|
||||
*/
|
||||
if (error != GIT_EINVALIDPATH)
|
||||
return git__throw(GIT_EOSERR, "Failed to lstat file");
|
||||
|
||||
namelen = strlen(file_name);
|
||||
if (namelen && file_name[namelen-1] != '/')
|
||||
return git__throw(GIT_EOSERR, "Failed to lstat file");
|
||||
return -1;
|
||||
|
||||
while (namelen && file_name[namelen-1] == '/')
|
||||
--namelen;
|
||||
|
||||
if (!namelen || namelen >= GIT_PATH_MAX)
|
||||
return git__throw(GIT_ENOMEM, "Failed to lstat file");
|
||||
if (!namelen)
|
||||
return -1;
|
||||
|
||||
memcpy(alt_name, file_name, namelen);
|
||||
alt_name[namelen] = 0;
|
||||
return do_lstat(alt_name, buf);
|
||||
alt_name = git__strndup(file_name, namelen);
|
||||
if (!alt_name)
|
||||
return -1;
|
||||
|
||||
error = do_lstat(alt_name, buf);
|
||||
|
||||
git__free(alt_name);
|
||||
return error;
|
||||
}
|
||||
|
||||
int p_readlink(const char *link, char *target, size_t target_len)
|
||||
@ -145,6 +137,9 @@ int p_readlink(const char *link, char *target, size_t target_len)
|
||||
DWORD dwRet;
|
||||
wchar_t* link_w;
|
||||
wchar_t* target_w;
|
||||
int error = 0;
|
||||
|
||||
assert(link && target && target_len > 0);
|
||||
|
||||
/*
|
||||
* Try to load the pointer to pGetFinalPath dynamically, because
|
||||
@ -156,12 +151,15 @@ int p_readlink(const char *link, char *target, size_t target_len)
|
||||
if (library != NULL)
|
||||
pGetFinalPath = (fpath_func)GetProcAddress(library, "GetFinalPathNameByHandleW");
|
||||
|
||||
if (pGetFinalPath == NULL)
|
||||
return git__throw(GIT_EOSERR,
|
||||
if (pGetFinalPath == NULL) {
|
||||
giterr_set(GITERR_OS,
|
||||
"'GetFinalPathNameByHandleW' is not available in this platform");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
link_w = gitwin_to_utf16(link);
|
||||
GITERR_CHECK_ALLOC(link_w);
|
||||
|
||||
hFile = CreateFileW(link_w, // file to open
|
||||
GENERIC_READ, // open for reading
|
||||
@ -173,50 +171,49 @@ int p_readlink(const char *link, char *target, size_t target_len)
|
||||
|
||||
git__free(link_w);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return GIT_EOSERR;
|
||||
|
||||
if (target_len <= 0) {
|
||||
return GIT_EINVALIDARGS;
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
giterr_set(GITERR_OS, "Cannot open '%s' for reading", link);
|
||||
return -1;
|
||||
}
|
||||
|
||||
target_w = (wchar_t*)git__malloc(target_len * sizeof(wchar_t));
|
||||
GITERR_CHECK_ALLOC(target_w);
|
||||
|
||||
dwRet = pGetFinalPath(hFile, target_w, target_len, 0x0);
|
||||
if (dwRet >= target_len) {
|
||||
git__free(target_w);
|
||||
CloseHandle(hFile);
|
||||
return GIT_ENOMEM;
|
||||
}
|
||||
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, target_w, -1, target, target_len * sizeof(char), NULL, NULL)) {
|
||||
git__free(target_w);
|
||||
return GIT_EOSERR;
|
||||
}
|
||||
if (dwRet == 0 ||
|
||||
dwRet >= target_len ||
|
||||
!WideCharToMultiByte(CP_UTF8, 0, target_w, -1, target,
|
||||
target_len * sizeof(char), NULL, NULL))
|
||||
error = -1;
|
||||
|
||||
git__free(target_w);
|
||||
CloseHandle(hFile);
|
||||
|
||||
if (dwRet > 4) {
|
||||
/* Skip first 4 characters if they are "\\?\" */
|
||||
if (target[0] == '\\' && target[1] == '\\' && target[2] == '?' && target[3] == '\\') {
|
||||
char tmp[GIT_PATH_MAX];
|
||||
unsigned int offset = 4;
|
||||
dwRet -= 4;
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* \??\UNC\ */
|
||||
if (dwRet > 7 && target[4] == 'U' && target[5] == 'N' && target[6] == 'C') {
|
||||
offset += 2;
|
||||
dwRet -= 2;
|
||||
target[offset] = '\\';
|
||||
}
|
||||
/* Skip first 4 characters if they are "\\?\" */
|
||||
if (dwRet > 4 &&
|
||||
target[0] == '\\' && target[1] == '\\' &&
|
||||
target[2] == '?' && target[3] == '\\')
|
||||
{
|
||||
unsigned int offset = 4;
|
||||
dwRet -= 4;
|
||||
|
||||
memcpy(tmp, target + offset, dwRet);
|
||||
memcpy(target, tmp, dwRet);
|
||||
/* \??\UNC\ */
|
||||
if (dwRet > 7 &&
|
||||
target[4] == 'U' && target[5] == 'N' && target[6] == 'C')
|
||||
{
|
||||
offset += 2;
|
||||
dwRet -= 2;
|
||||
target[offset] = '\\';
|
||||
}
|
||||
|
||||
memmove(target, target + offset, dwRet);
|
||||
}
|
||||
|
||||
target[dwRet] = '\0';
|
||||
|
||||
return dwRet;
|
||||
}
|
||||
|
||||
@ -224,8 +221,9 @@ int p_open(const char *path, int flags)
|
||||
{
|
||||
int fd;
|
||||
wchar_t* buf = gitwin_to_utf16(path);
|
||||
if (!buf)
|
||||
return -1;
|
||||
fd = _wopen(buf, flags | _O_BINARY);
|
||||
|
||||
git__free(buf);
|
||||
return fd;
|
||||
}
|
||||
@ -234,8 +232,9 @@ int p_creat(const char *path, mode_t mode)
|
||||
{
|
||||
int fd;
|
||||
wchar_t* buf = gitwin_to_utf16(path);
|
||||
if (!buf)
|
||||
return -1;
|
||||
fd = _wopen(buf, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY, mode);
|
||||
|
||||
git__free(buf);
|
||||
return fd;
|
||||
}
|
||||
@ -243,15 +242,15 @@ int p_creat(const char *path, mode_t mode)
|
||||
int p_getcwd(char *buffer_out, size_t size)
|
||||
{
|
||||
wchar_t* buf = (wchar_t*)git__malloc(sizeof(wchar_t) * (int)size);
|
||||
int ret;
|
||||
|
||||
_wgetcwd(buf, (int)size);
|
||||
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, buf, -1, buffer_out, size, NULL, NULL)) {
|
||||
git__free(buf);
|
||||
return GIT_EOSERR;
|
||||
}
|
||||
ret = WideCharToMultiByte(
|
||||
CP_UTF8, 0, buf, -1, buffer_out, size, NULL, NULL);
|
||||
|
||||
git__free(buf);
|
||||
return GIT_SUCCESS;
|
||||
return !ret ? -1 : 0;
|
||||
}
|
||||
|
||||
int p_stat(const char* path, struct stat* buf)
|
||||
@ -262,8 +261,10 @@ int p_stat(const char* path, struct stat* buf)
|
||||
int p_chdir(const char* path)
|
||||
{
|
||||
wchar_t* buf = gitwin_to_utf16(path);
|
||||
int ret = _wchdir(buf);
|
||||
|
||||
int ret;
|
||||
if (!buf)
|
||||
return -1;
|
||||
ret = _wchdir(buf);
|
||||
git__free(buf);
|
||||
return ret;
|
||||
}
|
||||
@ -271,8 +272,10 @@ int p_chdir(const char* path)
|
||||
int p_chmod(const char* path, mode_t mode)
|
||||
{
|
||||
wchar_t* buf = gitwin_to_utf16(path);
|
||||
int ret = _wchmod(buf, mode);
|
||||
|
||||
int ret;
|
||||
if (!buf)
|
||||
return -1;
|
||||
ret = _wchmod(buf, mode);
|
||||
git__free(buf);
|
||||
return ret;
|
||||
}
|
||||
@ -280,8 +283,10 @@ int p_chmod(const char* path, mode_t mode)
|
||||
int p_rmdir(const char* path)
|
||||
{
|
||||
wchar_t* buf = gitwin_to_utf16(path);
|
||||
int ret = _wrmdir(buf);
|
||||
|
||||
int ret;
|
||||
if (!buf)
|
||||
return -1;
|
||||
ret = _wrmdir(buf);
|
||||
git__free(buf);
|
||||
return ret;
|
||||
}
|
||||
@ -290,11 +295,13 @@ int p_hide_directory__w32(const char *path)
|
||||
{
|
||||
int res;
|
||||
wchar_t* buf = gitwin_to_utf16(path);
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
res = SetFileAttributesW(buf, FILE_ATTRIBUTE_HIDDEN);
|
||||
git__free(buf);
|
||||
|
||||
return (res != 0) ? GIT_SUCCESS : GIT_ERROR; /* MSDN states a "non zero" value indicates a success */
|
||||
|
||||
return (res != 0) ? 0 : -1; /* MSDN states a "non zero" value indicates a success */
|
||||
}
|
||||
|
||||
char *p_realpath(const char *orig_path, char *buffer)
|
||||
@ -303,6 +310,9 @@ char *p_realpath(const char *orig_path, char *buffer)
|
||||
wchar_t* orig_path_w = gitwin_to_utf16(orig_path);
|
||||
wchar_t* buffer_w = (wchar_t*)git__malloc(GIT_PATH_MAX * sizeof(wchar_t));
|
||||
|
||||
if (!orig_path_w || !buffer_w)
|
||||
return NULL;
|
||||
|
||||
ret = GetFullPathNameW(orig_path_w, GIT_PATH_MAX, buffer_w, NULL);
|
||||
git__free(orig_path_w);
|
||||
|
||||
@ -365,10 +375,10 @@ int p_mkstemp(char *tmp_path)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
if (_mktemp_s(tmp_path, strlen(tmp_path) + 1) != 0)
|
||||
return GIT_EOSERR;
|
||||
return -1;
|
||||
#else
|
||||
if (_mktemp(tmp_path) == NULL)
|
||||
return GIT_EOSERR;
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return p_creat(tmp_path, 0744);
|
||||
@ -377,15 +387,17 @@ int p_mkstemp(char *tmp_path)
|
||||
int p_setenv(const char* name, const char* value, int overwrite)
|
||||
{
|
||||
if (overwrite != 1)
|
||||
return EINVAL;
|
||||
return -1;
|
||||
|
||||
return (SetEnvironmentVariableA(name, value) == 0 ? GIT_EOSERR : GIT_SUCCESS);
|
||||
return (SetEnvironmentVariableA(name, value) == 0 ? -1 : 0);
|
||||
}
|
||||
|
||||
int p_access(const char* path, mode_t mode)
|
||||
{
|
||||
wchar_t *buf = gitwin_to_utf16(path);
|
||||
int ret;
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
ret = _waccess(buf, mode);
|
||||
git__free(buf);
|
||||
@ -393,13 +405,16 @@ int p_access(const char* path, mode_t mode)
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern int p_rename(const char *from, const char *to)
|
||||
int p_rename(const char *from, const char *to)
|
||||
{
|
||||
wchar_t *wfrom = gitwin_to_utf16(from);
|
||||
wchar_t *wto = gitwin_to_utf16(to);
|
||||
int ret;
|
||||
|
||||
ret = MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? GIT_SUCCESS : GIT_EOSERR;
|
||||
if (!wfrom || !wto)
|
||||
return -1;
|
||||
|
||||
ret = MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? 0 : -1;
|
||||
|
||||
git__free(wfrom);
|
||||
git__free(wto);
|
||||
|
||||
@ -7,13 +7,16 @@
|
||||
|
||||
#include "pthread.h"
|
||||
|
||||
int pthread_create(pthread_t *GIT_RESTRICT thread,
|
||||
const pthread_attr_t *GIT_RESTRICT attr,
|
||||
void *(*start_routine)(void*), void *GIT_RESTRICT arg)
|
||||
int pthread_create(
|
||||
pthread_t *GIT_RESTRICT thread,
|
||||
const pthread_attr_t *GIT_RESTRICT attr,
|
||||
void *(*start_routine)(void*),
|
||||
void *GIT_RESTRICT arg)
|
||||
{
|
||||
GIT_UNUSED(attr);
|
||||
*thread = (pthread_t) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, NULL);
|
||||
return *thread ? GIT_SUCCESS : git__throw(GIT_EOSERR, "Failed to create pthread");
|
||||
*thread = (pthread_t) CreateThread(
|
||||
NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, NULL);
|
||||
return *thread ? 0 : -1;
|
||||
}
|
||||
|
||||
int pthread_join(pthread_t thread, void **value_ptr)
|
||||
|
||||
@ -33,14 +33,14 @@ wchar_t* gitwin_to_utf16(const char* str)
|
||||
wchar_t* ret;
|
||||
int cb;
|
||||
|
||||
if (!str) {
|
||||
if (!str)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cb = strlen(str) * sizeof(wchar_t);
|
||||
if (cb == 0) {
|
||||
ret = (wchar_t*)git__malloc(sizeof(wchar_t));
|
||||
ret[0] = 0;
|
||||
if (ret)
|
||||
ret[0] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -48,8 +48,11 @@ wchar_t* gitwin_to_utf16(const char* str)
|
||||
cb += sizeof(wchar_t);
|
||||
|
||||
ret = (wchar_t*)git__malloc(cb);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
if (MultiByteToWideChar(_active_codepage, 0, str, -1, ret, cb) == 0) {
|
||||
giterr_set(GITERR_OS, "Could not convert string to UTF-16");
|
||||
git__free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
@ -59,7 +62,10 @@ wchar_t* gitwin_to_utf16(const char* str)
|
||||
|
||||
int gitwin_append_utf16(wchar_t *buffer, const char *str, size_t len)
|
||||
{
|
||||
return MultiByteToWideChar(_active_codepage, 0, str, -1, buffer, len);
|
||||
int result = MultiByteToWideChar(_active_codepage, 0, str, -1, buffer, len);
|
||||
if (result == 0)
|
||||
giterr_set(GITERR_OS, "Could not convert string to UTF-16");
|
||||
return result;
|
||||
}
|
||||
|
||||
char* gitwin_from_utf16(const wchar_t* str)
|
||||
@ -74,7 +80,8 @@ char* gitwin_from_utf16(const wchar_t* str)
|
||||
cb = wcslen(str) * sizeof(char);
|
||||
if (cb == 0) {
|
||||
ret = (char*)git__malloc(sizeof(char));
|
||||
ret[0] = 0;
|
||||
if (ret)
|
||||
ret[0] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -82,8 +89,11 @@ char* gitwin_from_utf16(const wchar_t* str)
|
||||
cb += sizeof(char);
|
||||
|
||||
ret = (char*)git__malloc(cb);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
if (WideCharToMultiByte(_active_codepage, 0, str, -1, ret, cb, NULL, NULL) == 0) {
|
||||
giterr_set(GITERR_OS, "Could not convert string to UTF-8");
|
||||
git__free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user