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:
Russell Belfer 2012-03-14 17:36:15 -07:00
parent ab43ad2fd8
commit deafee7bd7
21 changed files with 342 additions and 273 deletions

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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

View 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]);
}

View File

@ -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 } }

View File

@ -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;
}

View File

@ -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 */

View File

@ -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]);
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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.
*

View File

@ -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)

View File

@ -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;
}
/*

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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;
}