Commit deafee7b by Russell Belfer

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