diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/attr.c | 4 | ||||
-rw-r--r-- | src/attr_file.c | 2 | ||||
-rw-r--r-- | src/filebuf.c | 6 | ||||
-rw-r--r-- | src/fileops.c | 181 | ||||
-rw-r--r-- | src/fileops.h | 61 | ||||
-rw-r--r-- | src/hashtable.c | 3 | ||||
-rw-r--r-- | src/hashtable.h | 10 | ||||
-rw-r--r-- | src/ignore.c | 2 | ||||
-rw-r--r-- | src/index.c | 4 | ||||
-rw-r--r-- | src/indexer.c | 2 | ||||
-rw-r--r-- | src/odb.c | 2 | ||||
-rw-r--r-- | src/odb_loose.c | 12 | ||||
-rw-r--r-- | src/odb_pack.c | 4 | ||||
-rw-r--r-- | src/pack.c | 2 | ||||
-rw-r--r-- | src/path.c | 175 | ||||
-rw-r--r-- | src/path.h | 149 | ||||
-rw-r--r-- | src/reflog.c | 6 | ||||
-rw-r--r-- | src/refs.c | 28 | ||||
-rw-r--r-- | src/refspec.c | 2 | ||||
-rw-r--r-- | src/remote.c | 3 | ||||
-rw-r--r-- | src/repository.c | 18 | ||||
-rw-r--r-- | src/status.c | 14 | ||||
-rw-r--r-- | src/transport.c | 2 | ||||
-rw-r--r-- | src/transports/http.c | 2 | ||||
-rw-r--r-- | src/tree.c | 3 | ||||
-rw-r--r-- | src/win32/dir.h (renamed from src/dir.h) | 8 | ||||
-rw-r--r-- | src/win32/posix_w32.c | 2 |
27 files changed, 392 insertions, 315 deletions
diff --git a/src/attr.c b/src/attr.c index fa1a4f121..da0f72371 100644 --- a/src/attr.c +++ b/src/attr.c @@ -230,7 +230,7 @@ int git_attr_cache__push_file( /* either get attr_file from cache or read from disk */ file = git_hashtable_lookup(cache->files, filename); - if (file == NULL && git_futils_exists(filename) == GIT_SUCCESS) { + if (file == NULL && git_path_exists(filename) == GIT_SUCCESS) { if ((error = git_attr_file__new(&file)) == GIT_SUCCESS) error = loader(repo, filename, file); add_to_cache = (error == GIT_SUCCESS); @@ -280,7 +280,7 @@ static int collect_attr_files( if ((error = git_vector_init(files, 4, NULL)) < GIT_SUCCESS) goto cleanup; - if ((error = git_futils_dir_for_path(&dir, path, workdir)) < GIT_SUCCESS) + if ((error = git_path_find_dir(&dir, path, workdir)) < GIT_SUCCESS) goto cleanup; /* in precendence order highest to lowest: diff --git a/src/attr_file.c b/src/attr_file.c index 4303c7667..5fd136c77 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -243,7 +243,7 @@ int git_attr_path__init( info->basename++; if (!info->basename || !*info->basename) info->basename = path; - info->is_dir = (git_futils_isdir(path) == GIT_SUCCESS); + info->is_dir = (git_path_isdir(path) == GIT_SUCCESS); return GIT_SUCCESS; } diff --git a/src/filebuf.c b/src/filebuf.c index aa47d5eb0..447d8a089 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -16,7 +16,7 @@ static const size_t WRITE_BUFFER_SIZE = (4096 * 2); static int lock_file(git_filebuf *file, int flags) { - if (git_futils_exists(file->path_lock) == 0) { + if (git_path_exists(file->path_lock) == 0) { if (flags & GIT_FILEBUF_FORCE) p_unlink(file->path_lock); else @@ -34,7 +34,7 @@ static int lock_file(git_filebuf *file, int flags) if (file->fd < 0) return git__throw(GIT_EOSERR, "Failed to create lock"); - if ((flags & GIT_FILEBUF_APPEND) && git_futils_exists(file->path_original) == 0) { + if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == 0) { git_file source; char buffer[2048]; size_t read_bytes; @@ -60,7 +60,7 @@ void git_filebuf_cleanup(git_filebuf *file) if (file->fd >= 0) p_close(file->fd); - if (file->fd >= 0 && file->path_lock && git_futils_exists(file->path_lock) == GIT_SUCCESS) + if (file->fd >= 0 && file->path_lock && git_path_exists(file->path_lock) == GIT_SUCCESS) p_unlink(file->path_lock); if (file->digest) diff --git a/src/fileops.c b/src/fileops.c index 3412a47e2..e2a6adf0b 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -23,7 +23,7 @@ int git_futils_mkpath2file(const char *file_path, const mode_t mode) } /* Does the containing folder exist? */ - if (git_futils_isdir(target_folder.ptr) != GIT_SUCCESS) + if (git_path_isdir(target_folder.ptr) != GIT_SUCCESS) /* Let's create the tree structure */ error = git_futils_mkdir_r(target_folder.ptr, NULL, mode); @@ -70,47 +70,6 @@ int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, con return git_futils_creat_locked(path, mode); } -int git_futils_isdir(const char *path) -{ -#ifdef GIT_WIN32 - DWORD attr = GetFileAttributes(path); - if (attr == INVALID_FILE_ATTRIBUTES) - return GIT_ERROR; - - return (attr & FILE_ATTRIBUTE_DIRECTORY) ? GIT_SUCCESS : GIT_ERROR; - -#else - struct stat st; - if (p_stat(path, &st) < GIT_SUCCESS) - return GIT_ERROR; - - return S_ISDIR(st.st_mode) ? GIT_SUCCESS : GIT_ERROR; -#endif -} - -int git_futils_isfile(const char *path) -{ - struct stat st; - int stat_error; - - assert(path); - stat_error = p_stat(path, &st); - - if (stat_error < GIT_SUCCESS) - return -1; - - if (!S_ISREG(st.st_mode)) - return -1; - - return 0; -} - -int git_futils_exists(const char *path) -{ - assert(path); - return p_access(path, F_OK); -} - git_off_t git_futils_filesize(git_file fd) { struct stat sb; @@ -219,54 +178,6 @@ void git_futils_mmap_free(git_map *out) p_munmap(out); } -/* Taken from git.git */ -GIT_INLINE(int) is_dot_or_dotdot(const char *name) -{ - return (name[0] == '.' && - (name[1] == '\0' || - (name[1] == '.' && name[2] == '\0'))); -} - -int git_futils_direach( - git_buf *path, - int (*fn)(void *, git_buf *), - void *arg) -{ - ssize_t wd_len; - DIR *dir; - struct dirent *de; - - if (git_path_to_dir(path) < GIT_SUCCESS) - return git_buf_lasterror(path); - - wd_len = path->size; - dir = opendir(path->ptr); - if (!dir) - return git__throw(GIT_EOSERR, "Failed to process `%s` tree structure. An error occured while opening the directory", path->ptr); - - while ((de = readdir(dir)) != NULL) { - int result; - - if (is_dot_or_dotdot(de->d_name)) - continue; - - if (git_buf_puts(path, de->d_name) < GIT_SUCCESS) - return git_buf_lasterror(path); - - result = fn(arg, path); - - git_buf_truncate(path, wd_len); /* restore path */ - - if (result != GIT_SUCCESS) { - closedir(dir); - return result; /* The callee is reponsible for setting the correct error message */ - } - } - - closedir(dir); - return GIT_SUCCESS; -} - int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode) { int error, root_path_offset; @@ -291,7 +202,7 @@ int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode) pp += root_path_offset; /* On Windows, will skip the drive name (eg. C: or D:) */ while (error == GIT_SUCCESS && (sp = strchr(pp, '/')) != NULL) { - if (sp != pp && git_futils_isdir(make_path.ptr) < GIT_SUCCESS) { + if (sp != pp && git_path_isdir(make_path.ptr) < GIT_SUCCESS) { *sp = 0; error = p_mkdir(make_path.ptr, mode); @@ -324,8 +235,8 @@ static int _rmdir_recurs_foreach(void *opaque, git_buf *path) int error = GIT_SUCCESS; int force = *(int *)opaque; - if (git_futils_isdir(path->ptr) == GIT_SUCCESS) { - error = git_futils_direach(path, _rmdir_recurs_foreach, opaque); + if (git_path_isdir(path->ptr) == GIT_SUCCESS) { + 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); @@ -349,60 +260,6 @@ int git_futils_rmdir_r(const char *path, int force) return error; } -int git_futils_cmp_path(const char *name1, int len1, int isdir1, - const char *name2, int len2, int isdir2) -{ - int len = len1 < len2 ? len1 : len2; - int cmp; - - cmp = memcmp(name1, name2, len); - if (cmp) - return cmp; - if (len1 < len2) - return ((!isdir1 && !isdir2) ? -1 : - (isdir1 ? '/' - name2[len1] : name2[len1] - '/')); - if (len1 > len2) - return ((!isdir1 && !isdir2) ? 1 : - (isdir2 ? name1[len2] - '/' : '/' - name1[len2])); - return 0; -} - -static int _check_dir_contents( - git_buf *dir, - const char *sub, - int append_on_success, - int (*predicate)(const char *)) -{ - int error = GIT_SUCCESS; - size_t dir_size = dir->size; - size_t sub_size = strlen(sub); - - /* leave base valid even if we could not make space for subdir */ - if ((error = git_buf_try_grow(dir, dir_size + sub_size + 2)) < GIT_SUCCESS) - return error; - - /* save excursion */ - git_buf_joinpath(dir, dir->ptr, sub); - - error = (*predicate)(dir->ptr); - - /* restore excursion */ - if (!append_on_success || error != GIT_SUCCESS) - git_buf_truncate(dir, dir_size); - - return error; -} - -int git_futils_contains_dir(git_buf *base, const char *subdir, int append_if_exists) -{ - return _check_dir_contents(base, subdir, append_if_exists, &git_futils_isdir); -} - -int git_futils_contains_file(git_buf *base, const char *file, int append_if_exists) -{ - return _check_dir_contents(base, file, append_if_exists, &git_futils_isfile); -} - int git_futils_find_global_file(git_buf *path, const char *filename) { int error; @@ -420,7 +277,7 @@ int git_futils_find_global_file(git_buf *path, const char *filename) if ((error = git_buf_joinpath(path, home, filename)) < GIT_SUCCESS) return error; - if (git_futils_exists(path->ptr) < GIT_SUCCESS) { + if (git_path_exists(path->ptr) < GIT_SUCCESS) { git_buf_clear(path); return GIT_ENOTFOUND; } @@ -522,7 +379,7 @@ int git_futils_find_system_file(git_buf *path, const char *filename) if (git_buf_joinpath(path, "/etc", filename) < GIT_SUCCESS) return git_buf_lasterror(path); - if (git_futils_exists(path->ptr) == GIT_SUCCESS) + if (git_path_exists(path->ptr) == GIT_SUCCESS) return GIT_SUCCESS; git_buf_clear(path); @@ -533,29 +390,3 @@ int git_futils_find_system_file(git_buf *path, const char *filename) return GIT_ENOTFOUND; #endif } - -int git_futils_dir_for_path(git_buf *dir, const char *path, const char *base) -{ - int error = GIT_SUCCESS; - - if (base != NULL && git_path_root(path) < 0) - error = git_buf_joinpath(dir, base, path); - else - error = git_buf_sets(dir, path); - - if (error == GIT_SUCCESS) { - char buf[GIT_PATH_MAX]; - if (p_realpath(dir->ptr, buf) != NULL) - error = git_buf_sets(dir, buf); - } - - /* call dirname if this is not a directory */ - if (error == GIT_SUCCESS && git_futils_isdir(dir->ptr) != GIT_SUCCESS) - if (git_path_dirname_r(dir, dir->ptr) < GIT_SUCCESS) - error = git_buf_lasterror(dir); - - if (error == GIT_SUCCESS) - error = git_path_to_dir(dir); - - return error; -} diff --git a/src/fileops.h b/src/fileops.h index 91903a731..1ded0d3b1 100644 --- a/src/fileops.h +++ b/src/fileops.h @@ -9,7 +9,6 @@ #include "common.h" #include "map.h" -#include "dir.h" #include "posix.h" #include "path.h" @@ -41,11 +40,6 @@ extern void git_futils_fbuffer_rtrim(git_fbuffer *obj); */ /** - * Check if a file exists and can be accessed. - */ -extern int git_futils_exists(const char *path); - -/** * Create and open a file, while also * creating all the folders in its path */ @@ -63,32 +57,6 @@ extern int git_futils_creat_locked(const char *path, const mode_t mode); extern int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, const mode_t mode); /** - * Check if the given path points to a directory - */ -extern int git_futils_isdir(const char *path); - -/** - * Check if the given path points to a regular file - */ -extern int git_futils_isfile(const char *path); - -/** - * Check if the given path contains the given subdirectory. - * - * If `append_if_exists` is true, then the subdir will be appended to the - * parent path if it does exists. - */ -extern int git_futils_contains_dir(git_buf *parent, const char *subdir, int append_if_exists); - -/** - * Check if the given path contains the given file - * - * If `append_if_exists` is true, then the filename will be appended to the - * parent path if it does exists. - */ -extern int git_futils_contains_file(git_buf *parent, const char *file, int append_if_exists); - -/** * Create a path recursively */ extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode); @@ -99,17 +67,10 @@ extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t m */ extern int git_futils_mkpath2file(const char *path, const mode_t mode); -extern int git_futils_rmdir_r(const char *path, int force); - /** - * Get the directory for a path. - * - * If the path is a directory, this does nothing (save append a '/' as - * needed). If path is a normal file, this gets the directory containing - * it. If the path does not exist, then this treats it a filename and - * returns the dirname of it. + * Remove path and any files and directories beneath it. */ -extern int git_futils_dir_for_path(git_buf *dir, const char *path, const char *base); +extern int git_futils_rmdir_r(const char *path, int force); /** * Create and open a temporary file with a `_git2_` suffix. @@ -158,24 +119,6 @@ extern int git_futils_mmap_ro( extern void git_futils_mmap_free(git_map *map); /** - * Walk each directory entry, except '.' and '..', calling fn(state). - * - * @param pathbuf buffer the function reads the initial directory - * path from, and updates with each successive entry's name. - * @param fn function to invoke with each entry. The first arg is - * the input state and the second arg is pathbuf. The function - * may modify the pathbuf, but only by appending new text. - * @param state to pass to fn as the first arg. - */ -extern int git_futils_direach( - git_buf *pathbuf, - int (*fn)(void *, git_buf *), - void *state); - -extern int git_futils_cmp_path(const char *name1, int len1, int isdir1, - const char *name2, int len2, int isdir2); - -/** * Find a "global" file (i.e. one in a user's home directory). * * @param pathbuf buffer to write the full path into diff --git a/src/hashtable.c b/src/hashtable.c index f836f166d..89c44ba9e 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -213,7 +213,7 @@ void *git_hashtable_lookup(git_hashtable *self, const void *key) return NULL; } -int git_hashtable_remove(git_hashtable *self, const void *key) +int git_hashtable_remove2(git_hashtable *self, const void *key, void **old_value) { int hash_id; git_hashtable_node *node; @@ -223,6 +223,7 @@ int git_hashtable_remove(git_hashtable *self, const void *key) for (hash_id = 0; hash_id < GIT_HASHTABLE_HASHES; ++hash_id) { node = node_with_hash(self, key, hash_id); if (node->key && self->key_equal(key, node->key) == 0) { + *old_value = node->value; node->key = NULL; node->value = NULL; self->key_count--; diff --git a/src/hashtable.h b/src/hashtable.h index 485b17aa6..cd458eb17 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -42,7 +42,15 @@ git_hashtable *git_hashtable_alloc(size_t min_size, git_hash_ptr hash, git_hash_keyeq_ptr key_eq); void *git_hashtable_lookup(git_hashtable *h, const void *key); -int git_hashtable_remove(git_hashtable *table, const void *key); +int git_hashtable_remove2(git_hashtable *table, const void *key, void **old_value); + +GIT_INLINE(int) git_hashtable_remove(git_hashtable *table, const void *key) +{ + void *_unused; + return git_hashtable_remove2(table, key, &_unused); +} + + void git_hashtable_free(git_hashtable *h); void git_hashtable_clear(git_hashtable *h); int git_hashtable_merge(git_hashtable *self, git_hashtable *other); diff --git a/src/ignore.c b/src/ignore.c index 388a4b280..516da645c 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -88,7 +88,7 @@ int git_ignore__for_path(git_repository *repo, const char *path, git_vector *sta if ((error = git_attr_cache__init(repo)) < GIT_SUCCESS) goto cleanup; - if ((error = git_futils_dir_for_path(&dir, path, workdir)) < GIT_SUCCESS) + if ((error = git_path_find_dir(&dir, path, workdir)) < GIT_SUCCESS) goto cleanup; /* insert internals */ diff --git a/src/index.c b/src/index.c index 9e88012bb..66e7a81da 100644 --- a/src/index.c +++ b/src/index.c @@ -150,7 +150,7 @@ int git_index_open(git_index **index_out, const char *index_path) git_vector_init(&index->entries, 32, index_cmp); /* Check if index file is stored on disk already */ - if (git_futils_exists(index->index_file_path) == 0) + if (git_path_exists(index->index_file_path) == 0) index->on_disk = 1; *index_out = index; @@ -221,7 +221,7 @@ int git_index_read(git_index *index) assert(index->index_file_path); - if (!index->on_disk || git_futils_exists(index->index_file_path) < 0) { + if (!index->on_disk || git_path_exists(index->index_file_path) < 0) { git_index_clear(index); index->on_disk = 0; return GIT_SUCCESS; diff --git a/src/indexer.c b/src/indexer.c index 8fdf89d9d..1b2cd61e0 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -164,7 +164,7 @@ static int index_path(git_buf *path, git_indexer *idx) GIT_OID_HEXSZ + strlen(suffix) + 1) < GIT_SUCCESS) return GIT_ENOMEM; - git_buf_truncate(path, slash + 1); + git_buf_truncate(path, slash); git_buf_puts(path, prefix); git_oid_fmt(path->ptr + path->size, &idx->hash); path->size += GIT_OID_HEXSZ; @@ -354,7 +354,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir) if (error < GIT_SUCCESS) return error; - if (git_futils_exists(alternates_path.ptr) < GIT_SUCCESS) { + if (git_path_exists(alternates_path.ptr) < GIT_SUCCESS) { git_buf_free(&alternates_path); return GIT_SUCCESS; } diff --git a/src/odb_loose.c b/src/odb_loose.c index f177af86c..d958fce9f 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -466,7 +466,7 @@ static int locate_object( int error = object_file_name(object_location, backend->objects_dir, oid); if (error == GIT_SUCCESS) - error = git_futils_exists(git_buf_cstr(object_location)); + error = git_path_exists(git_buf_cstr(object_location)); return error; } @@ -480,7 +480,7 @@ static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) { return GIT_SUCCESS; } - if (!git_futils_exists(pathbuf->ptr) && git_futils_isdir(pathbuf->ptr)) { + if (!git_path_exists(pathbuf->ptr) && git_path_isdir(pathbuf->ptr)) { /* We are already in the directory matching the 2 first hex characters, * compare the first ncmp characters of the oids */ if (!memcmp(sstate->short_oid + 2, @@ -533,8 +533,8 @@ static int locate_object_short_oid( return git__rethrow(error, "Failed to locate object from short oid"); /* Check that directory exists */ - if (git_futils_exists(object_location->ptr) || - git_futils_isdir(object_location->ptr)) + if (git_path_exists(object_location->ptr) || + git_path_isdir(object_location->ptr)) return git__throw(GIT_ENOTFOUND, "Failed to locate object from short oid. Object not found"); state.dir_len = object_location->size; @@ -542,7 +542,7 @@ static int locate_object_short_oid( state.found = 0; /* Explore directory to find a unique object matching short_oid */ - error = git_futils_direach(object_location, fn_locate_object_short_oid, &state); + error = git_path_direach(object_location, fn_locate_object_short_oid, &state); if (error) return git__rethrow(error, "Failed to locate object from short oid"); @@ -716,7 +716,7 @@ static int loose_backend__stream_fwrite(git_oid *oid, git_odb_stream *_stream) * is what git does and allows us to sidestep the fact that * we're not allowed to overwrite a read-only file on Windows. */ - if (git_futils_exists(final_path.ptr) == GIT_SUCCESS) { + if (git_path_exists(final_path.ptr) == GIT_SUCCESS) { git_filebuf_cleanup(&stream->fbuf); goto cleanup; } diff --git a/src/odb_pack.c b/src/odb_pack.c index 757d6277e..81168bfa6 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -254,7 +254,7 @@ static int packfile_refresh_all(struct pack_backend *backend) git_buf_sets(&path, backend->pack_folder); /* reload all packs */ - error = git_futils_direach(&path, packfile_load__cb, (void *)backend); + error = git_path_direach(&path, packfile_load__cb, (void *)backend); git_buf_free(&path); if (error < GIT_SUCCESS) @@ -469,7 +469,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) if (error < GIT_SUCCESS) goto cleanup; - if (git_futils_isdir(git_buf_cstr(&path)) == GIT_SUCCESS) { + if (git_path_isdir(git_buf_cstr(&path)) == GIT_SUCCESS) { backend->pack_folder = git_buf_detach(&path); backend->pack_folder_mtime = 0; } diff --git a/src/pack.c b/src/pack.c index 1510ded0c..cf64983ca 100644 --- a/src/pack.c +++ b/src/pack.c @@ -600,7 +600,7 @@ int git_packfile_check(struct git_pack_file **pack_out, const char *path) memcpy(p->pack_name, path, path_len); strcpy(p->pack_name + path_len, ".keep"); - if (git_futils_exists(p->pack_name) == GIT_SUCCESS) + if (git_path_exists(p->pack_name) == GIT_SUCCESS) p->pack_keep = 1; strcpy(p->pack_name + path_len, ".pack"); diff --git a/src/path.c b/src/path.c index 03ebfe090..5319ca6a5 100644 --- a/src/path.c +++ b/src/path.c @@ -7,7 +7,11 @@ #include "common.h" #include "path.h" #include "posix.h" - +#ifdef GIT_WIN32 +#include "win32/dir.h" +#else +#include <dirent.h> +#endif #include <stdarg.h> #include <stdio.h> #include <ctype.h> @@ -349,3 +353,172 @@ int git_path_walk_up( return error; } + +int git_path_exists(const char *path) +{ + assert(path); + return p_access(path, F_OK); +} + +int git_path_isdir(const char *path) +{ +#ifdef GIT_WIN32 + DWORD attr = GetFileAttributes(path); + if (attr == INVALID_FILE_ATTRIBUTES) + return GIT_ERROR; + + return (attr & FILE_ATTRIBUTE_DIRECTORY) ? GIT_SUCCESS : GIT_ERROR; + +#else + struct stat st; + if (p_stat(path, &st) < GIT_SUCCESS) + return GIT_ERROR; + + return S_ISDIR(st.st_mode) ? GIT_SUCCESS : GIT_ERROR; +#endif +} + +int git_path_isfile(const char *path) +{ + struct stat st; + int stat_error; + + assert(path); + stat_error = p_stat(path, &st); + + if (stat_error < GIT_SUCCESS) + return -1; + + if (!S_ISREG(st.st_mode)) + return -1; + + return 0; +} + +static int _check_dir_contents( + git_buf *dir, + const char *sub, + int append_on_success, + int (*predicate)(const char *)) +{ + int error = GIT_SUCCESS; + size_t dir_size = dir->size; + size_t sub_size = strlen(sub); + + /* leave base valid even if we could not make space for subdir */ + if ((error = git_buf_try_grow(dir, dir_size + sub_size + 2)) < GIT_SUCCESS) + return error; + + /* save excursion */ + git_buf_joinpath(dir, dir->ptr, sub); + + error = (*predicate)(dir->ptr); + + /* restore excursion */ + if (!append_on_success || error != GIT_SUCCESS) + git_buf_truncate(dir, dir_size); + + return error; +} + +int git_path_contains_dir(git_buf *base, const char *subdir, int append_if_exists) +{ + return _check_dir_contents(base, subdir, append_if_exists, &git_path_isdir); +} + +int git_path_contains_file(git_buf *base, const char *file, int append_if_exists) +{ + return _check_dir_contents(base, file, append_if_exists, &git_path_isfile); +} + +int git_path_find_dir(git_buf *dir, const char *path, const char *base) +{ + int error = GIT_SUCCESS; + + if (base != NULL && git_path_root(path) < 0) + error = git_buf_joinpath(dir, base, path); + else + error = git_buf_sets(dir, path); + + if (error == GIT_SUCCESS) { + char buf[GIT_PATH_MAX]; + if (p_realpath(dir->ptr, buf) != NULL) + error = git_buf_sets(dir, buf); + } + + /* call dirname if this is not a directory */ + if (error == GIT_SUCCESS && git_path_isdir(dir->ptr) != GIT_SUCCESS) + if (git_path_dirname_r(dir, dir->ptr) < GIT_SUCCESS) + error = git_buf_lasterror(dir); + + if (error == GIT_SUCCESS) + error = git_path_to_dir(dir); + + return error; +} + +int git_path_cmp(const char *name1, int len1, int isdir1, + const char *name2, int len2, int isdir2) +{ + int len = len1 < len2 ? len1 : len2; + int cmp; + + cmp = memcmp(name1, name2, len); + if (cmp) + return cmp; + if (len1 < len2) + return ((!isdir1 && !isdir2) ? -1 : + (isdir1 ? '/' - name2[len1] : name2[len1] - '/')); + if (len1 > len2) + return ((!isdir1 && !isdir2) ? 1 : + (isdir2 ? name1[len2] - '/' : '/' - name1[len2])); + return 0; +} + +/* Taken from git.git */ +GIT_INLINE(int) is_dot_or_dotdot(const char *name) +{ + return (name[0] == '.' && + (name[1] == '\0' || + (name[1] == '.' && name[2] == '\0'))); +} + +int git_path_direach( + git_buf *path, + int (*fn)(void *, git_buf *), + void *arg) +{ + ssize_t wd_len; + DIR *dir; + struct dirent *de; + + if (git_path_to_dir(path) < GIT_SUCCESS) + return git_buf_lasterror(path); + + wd_len = path->size; + dir = opendir(path->ptr); + if (!dir) + return git__throw(GIT_EOSERR, "Failed to process `%s` tree structure. An error occured while opening the directory", path->ptr); + + while ((de = readdir(dir)) != NULL) { + int result; + + if (is_dot_or_dotdot(de->d_name)) + continue; + + if (git_buf_puts(path, de->d_name) < GIT_SUCCESS) + return git_buf_lasterror(path); + + result = fn(arg, path); + + git_buf_truncate(path, wd_len); /* restore path */ + + if (result != GIT_SUCCESS) { + closedir(dir); + return result; /* The callee is reponsible for setting the correct error message */ + } + } + + closedir(dir); + return GIT_SUCCESS; +} diff --git a/src/path.h b/src/path.h index e59c19ad9..ee3607ce9 100644 --- a/src/path.h +++ b/src/path.h @@ -10,6 +10,13 @@ #include "common.h" #include "buffer.h" +/** + * Path manipulation utils + * + * These are path utilities that munge paths without actually + * looking at the real filesystem. + */ + /* * The dirname() function shall take a pointer to a character string * that contains a pathname, and return a pointer to a string that is a @@ -52,15 +59,30 @@ extern int git_path_basename_r(git_buf *buffer, const char *path); extern const char *git_path_topdir(const char *path); +/** + * Find offset to root of path if path has one. + * + * This will return a number >= 0 which is the offset to the start of the + * path, if the path is rooted (i.e. "/rooted/path" returns 0 and + * "c:/windows/rooted/path" returns 2). If the path is not rooted, this + * returns < 0. + */ extern int git_path_root(const char *path); -extern int git_path_prettify(git_buf *path_out, const char *path, const char *base); -extern int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base); - +/** + * Ensure path has a trailing '/'. + */ extern int git_path_to_dir(git_buf *path); + +/** + * Ensure string has a trailing '/' if there is space for it. + */ extern void git_path_string_to_dir(char* path, size_t size); #ifdef GIT_WIN32 +/** + * Convert backslashes in path to forward slashes. + */ GIT_INLINE(void) git_path_mkposix(char *path) { while (*path) { @@ -75,20 +97,123 @@ GIT_INLINE(void) git_path_mkposix(char *path) #endif extern int git__percent_decode(git_buf *decoded_out, const char *input); + +/** + * Extract path from file:// URL. + */ extern int git_path_fromurl(git_buf *local_path_out, const char *file_url); + +/** + * Path filesystem utils + * + * These are path utilities that actually access the filesystem. + */ + +/** + * Check if a file exists and can be accessed. + * @return GIT_SUCCESS if file exists, < 0 otherwise. + */ +extern int git_path_exists(const char *path); + +/** + * Check if the given path points to a directory. + * @return GIT_SUCCESS if it is a directory, < 0 otherwise. + */ +extern int git_path_isdir(const char *path); + /** - * Invoke callback directory by directory up the path until the ceiling - * is reached (inclusive of a final call at the root_path). + * Check if the given path points to a regular file. + * @return GIT_SUCCESS if it is a regular file, < 0 otherwise. + */ +extern int git_path_isfile(const char *path); + +/** + * Check if the given path contains the given subdirectory. + * + * @param parent Directory path that might contain subdir + * @param subdir Subdirectory name to look for in parent + * @param append_if_exists If true, then subdir will be appended to the parent path if it does exist + * @return GIT_SUCCESS if subdirectory exists, < 0 otherwise. + */ +extern int git_path_contains_dir(git_buf *parent, const char *subdir, int append_if_exists); + +/** + * Check if the given path contains the given file. + * + * @param dir Directory path that might contain file + * @param file File name to look for in parent + * @param append_if_exists If true, then file will be appended to the path if it does exist + * @return GIT_SUCCESS if file exists, < 0 otherwise. + */ +extern int git_path_contains_file(git_buf *dir, const char *file, int append_if_exists); + +/** + * Clean up path, prepending base if it is not already rooted. + */ +extern int git_path_prettify(git_buf *path_out, const char *path, const char *base); + +/** + * Clean up path, prepending base if it is not already rooted and + * appending a slash. + */ +extern int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base); + +/** + * Get a directory from a path. + * + * If path is a directory, this acts like `git_path_prettify_dir` + * (cleaning up path and appending a '/'). If path is a normal file, + * this prettifies it, then removed the filename a la dirname and + * appends the trailing '/'. If the path does not exist, it is + * treated like a regular filename. + */ +extern int git_path_find_dir(git_buf *dir, const char *path, const char *base); + +/** + * Walk each directory entry, except '.' and '..', calling fn(state). + * + * @param pathbuf buffer the function reads the initial directory + * path from, and updates with each successive entry's name. + * @param fn function to invoke with each entry. The first arg is + * the input state and the second arg is pathbuf. The function + * may modify the pathbuf, but only by appending new text. + * @param state to pass to fn as the first arg. + */ +extern int git_path_direach( + git_buf *pathbuf, + int (*fn)(void *, git_buf *), + void *state); + +/** + * Sort function to order two paths. + */ +extern int git_path_cmp( + const char *name1, int len1, int isdir1, + const char *name2, int len2, int isdir2); + +/** + * Invoke callback up path directory by directory until the ceiling is + * reached (inclusive of a final call at the root_path). + * + * Returning anything other than GIT_SUCCESS from the callback function + * will stop the iteration and propogate the error to the caller. * - * If the ceiling is NULL, this will walk all the way up to the root. - * If the ceiling is not a prefix of the path, the callback will be - * invoked a single time on the verbatim input path. Returning anything - * other than GIT_SUCCESS from the callback function will stop the - * iteration and propogate the error to the caller. + * @param pathbuf Buffer the function reads the directory from and + * and updates with each successive name. + * @param ceiling Prefix of path at which to stop walking up. If NULL, + * this will walk all the way up to the root. If not a prefix of + * pathbuf, the callback will be invoked a single time on the + * original input path. + * @param fn Function to invoke on each path. The first arg is the + * input satte and the second arg is the pathbuf. The function + * should not modify the pathbuf. + * @param state Passed to fn as the first ath. */ extern int git_path_walk_up( - git_buf *path, const char *ceiling, - int (*cb)(void *data, git_buf *), void *data); + git_buf *pathbuf, + const char *ceiling, + int (*fn)(void *state, git_buf *), + void *state); #endif diff --git a/src/reflog.c b/src/reflog.c index a327975d6..970e7c2de 100644 --- a/src/reflog.c +++ b/src/reflog.c @@ -246,12 +246,12 @@ int git_reflog_write(git_reference *ref, const git_oid *oid_old, if (error < GIT_SUCCESS) goto cleanup; - if (git_futils_exists(log_path.ptr)) { + if (git_path_exists(log_path.ptr)) { error = git_futils_mkpath2file(log_path.ptr, GIT_REFLOG_DIR_MODE); if (error < GIT_SUCCESS) git__rethrow(error, "Failed to write reflog. Cannot create reflog directory"); - } else if (git_futils_isfile(log_path.ptr)) { + } else if (git_path_isfile(log_path.ptr)) { error = git__throw(GIT_ERROR, "Failed to write reflog. `%s` is directory", log_path.ptr); } else if (oid_old == NULL) { @@ -302,7 +302,7 @@ int git_reflog_delete(git_reference *ref) error = git_buf_join_n(&path, '/', 3, ref->owner->path_repository, GIT_REFLOG_DIR, ref->name); - if (error == GIT_SUCCESS && git_futils_exists(path.ptr) == 0) + if (error == GIT_SUCCESS && git_path_exists(path.ptr) == 0) error = p_unlink(path.ptr); git_buf_free(&path); diff --git a/src/refs.c b/src/refs.c index 2842adab1..86e5f5dba 100644 --- a/src/refs.c +++ b/src/refs.c @@ -525,8 +525,8 @@ static int _dirent_loose_listall(void *_data, git_buf *full_path) struct dirent_list_data *data = (struct dirent_list_data *)_data; const char *file_path = full_path->ptr + data->repo_path_len; - if (git_futils_isdir(full_path->ptr) == GIT_SUCCESS) - return git_futils_direach(full_path, _dirent_loose_listall, _data); + if (git_path_isdir(full_path->ptr) == GIT_SUCCESS) + return git_path_direach(full_path, _dirent_loose_listall, _data); /* do not add twice a reference that exists already in the packfile */ if ((data->list_flags & GIT_REF_PACKED) != 0 && @@ -549,8 +549,8 @@ static int _dirent_loose_load(void *data, git_buf *full_path) const char *file_path; int error; - if (git_futils_isdir(full_path->ptr) == GIT_SUCCESS) - return git_futils_direach(full_path, _dirent_loose_load, repository); + if (git_path_isdir(full_path->ptr) == GIT_SUCCESS) + return git_path_direach(full_path, _dirent_loose_load, repository); file_path = full_path->ptr + strlen(repository->path_repository); error = loose_lookup_to_packfile(&ref, repository, file_path); @@ -596,7 +596,7 @@ static int packed_loadloose(git_repository *repository) * This will overwrite any old packed entries with their * updated loose versions */ - error = git_futils_direach(&refs_path, _dirent_loose_load, repository); + error = git_path_direach(&refs_path, _dirent_loose_load, repository); git_buf_free(&refs_path); return error; } @@ -719,7 +719,7 @@ static int packed_remove_loose(git_repository *repo, git_vector *packing_list) an_error = git_buf_joinpath(&full_path, repo->path_repository, ref->name); if (an_error == GIT_SUCCESS && - git_futils_exists(full_path.ptr) == GIT_SUCCESS && + git_path_exists(full_path.ptr) == GIT_SUCCESS && p_unlink(full_path.ptr) < GIT_SUCCESS) an_error = GIT_EOSERR; @@ -902,7 +902,7 @@ static int reference_exists(int *exists, git_repository *repo, const char *ref_n if (error < GIT_SUCCESS) return git__rethrow(error, "Cannot resolve if a reference exists"); - if (git_futils_isfile(ref_path.ptr) == GIT_SUCCESS || + if (git_path_isfile(ref_path.ptr) == GIT_SUCCESS || git_hashtable_lookup(repo->references.packfile, ref_path.ptr) != NULL) { *exists = 1; } else { @@ -984,14 +984,16 @@ static int reference_delete(git_reference *ref) * We need to reload the packfile, remove the reference from the * packing list, and repack */ if (ref->flags & GIT_REF_PACKED) { + struct packref *packref; /* load the existing packfile */ if ((error = packed_load(ref->owner)) < GIT_SUCCESS) return git__rethrow(error, "Failed to delete reference"); - if (git_hashtable_remove(ref->owner->references.packfile, - ref->name) < GIT_SUCCESS) + if (git_hashtable_remove2(ref->owner->references.packfile, + ref->name, (void **) &packref) < GIT_SUCCESS) return git__throw(GIT_ENOTFOUND, "Reference not found"); + git__free (packref); error = packed_write(ref->owner); /* If the reference is loose, we can just remove the reference @@ -1352,8 +1354,8 @@ int git_reference_rename(git_reference *ref, const char *new_name, int force) if ((error = reference_delete(ref)) < GIT_SUCCESS) goto cleanup; - if (git_futils_exists(aux_path.ptr) == GIT_SUCCESS) { - if (git_futils_isdir(aux_path.ptr) == GIT_SUCCESS) { + if (git_path_exists(aux_path.ptr) == GIT_SUCCESS) { + if (git_path_isdir(aux_path.ptr) == GIT_SUCCESS) { if ((error = git_futils_rmdir_r(aux_path.ptr, 0)) < GIT_SUCCESS) goto rollback; } else goto rollback; @@ -1398,7 +1400,7 @@ int git_reference_rename(git_reference *ref, const char *new_name, int force) if (error < GIT_SUCCESS) goto cleanup; - if (git_futils_exists(aux_path.ptr) == GIT_SUCCESS) + if (git_path_exists(aux_path.ptr) == GIT_SUCCESS) error = git_reflog_rename(ref, new_name); /* @@ -1536,7 +1538,7 @@ int git_reference_foreach( repo->path_repository, GIT_REFS_DIR)) < GIT_SUCCESS) return git__rethrow(error, "Failed to alloc space for references"); - error = git_futils_direach(&refs_path, _dirent_loose_listall, &data); + error = git_path_direach(&refs_path, _dirent_loose_listall, &data); git_buf_free(&refs_path); diff --git a/src/refspec.c b/src/refspec.c index 7ce32ba14..7694be525 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -57,7 +57,7 @@ const char *git_refspec_dst(const git_refspec *refspec) int git_refspec_src_match(const git_refspec *refspec, const char *refname) { - return refspec == NULL ? GIT_ENOMATCH : git__fnmatch(refspec->src, refname, 0); + return (refspec == NULL || refspec->src == NULL) ? GIT_ENOMATCH : git__fnmatch(refspec->src, refname, 0); } int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name) diff --git a/src/remote.c b/src/remote.c index ef42c6e2a..cdf28789b 100644 --- a/src/remote.c +++ b/src/remote.c @@ -279,9 +279,10 @@ int git_remote_update_tips(git_remote *remote) if (!strcmp(head->name, GIT_HEAD_FILE)) { error = git_reference_create_oid(&ref, remote->repo, GIT_FETCH_HEAD_FILE, &head->oid, 1); i = 1; - git_reference_free(ref); if (error < GIT_SUCCESS) return git__rethrow(error, "Failed to update FETCH_HEAD"); + + git_reference_free(ref); } for (; i < refs->length; ++i) { diff --git a/src/repository.c b/src/repository.c index a408599f7..97d70c437 100644 --- a/src/repository.c +++ b/src/repository.c @@ -79,14 +79,14 @@ void git_repository_free(git_repository *repo) static int quickcheck_repository_dir(git_buf *repository_path) { /* Check OBJECTS_DIR first, since it will generate the longest path name */ - if (git_futils_contains_dir(repository_path, GIT_OBJECTS_DIR, 0) < 0) + if (git_path_contains_dir(repository_path, GIT_OBJECTS_DIR, 0) < 0) return GIT_ERROR; /* Ensure HEAD file exists */ - if (git_futils_contains_file(repository_path, GIT_HEAD_FILE, 0) < 0) + if (git_path_contains_file(repository_path, GIT_HEAD_FILE, 0) < 0) return GIT_ERROR; - if (git_futils_contains_dir(repository_path, GIT_REFS_DIR, 0) < 0) + if (git_path_contains_dir(repository_path, GIT_REFS_DIR, 0) < 0) return GIT_ERROR; return GIT_SUCCESS; @@ -164,12 +164,12 @@ int git_repository_open(git_repository **repo_out, const char *path) * of the working dir, by testing if it contains a `.git` * folder inside of it. */ - git_futils_contains_dir(&path_buf, DOT_GIT, 1); /* append on success */ + git_path_contains_dir(&path_buf, DOT_GIT, 1); /* append on success */ /* ignore error, since it just means `path/.git` doesn't exist */ if (quickcheck_repository_dir(&path_buf) < GIT_SUCCESS) { error = git__throw(GIT_ENOTAREPO, - "The given path is not a valid Git repository"); + "The given path (%s) is not a valid Git repository", git_buf_cstr(&path_buf)); goto cleanup; } @@ -491,7 +491,7 @@ static int read_gitfile(git_buf *path_out, const char *file_path, const char *ba git_futils_freebuffer(&file); - if (error == GIT_SUCCESS && git_futils_exists(path_out->ptr) == 0) + if (error == GIT_SUCCESS && git_path_exists(path_out->ptr) == 0) return GIT_SUCCESS; return git__throw(GIT_EOBJCORRUPTED, "The `.git` file points to a nonexistent path"); @@ -535,7 +535,7 @@ int git_repository_discover( * If the `.git` file is regular instead of * a directory, it should contain the path of the actual git repository */ - if (git_futils_isfile(normal_path.ptr) == GIT_SUCCESS) { + if (git_path_isfile(normal_path.ptr) == GIT_SUCCESS) { git_buf gitfile_path = GIT_BUF_INIT; error = read_gitfile(&gitfile_path, normal_path.ptr, bare_path.ptr); @@ -557,7 +557,7 @@ int git_repository_discover( /** * If the `.git` file is a folder, we check inside of it */ - if (git_futils_isdir(normal_path.ptr) == GIT_SUCCESS) { + if (git_path_isdir(normal_path.ptr) == GIT_SUCCESS) { error = quickcheck_repository_dir(&normal_path); if (error == GIT_SUCCESS) { found_path = &normal_path; @@ -733,7 +733,7 @@ int git_repository_init(git_repository **repo_out, const char *path, unsigned is if (error < GIT_SUCCESS) return error; - if (git_futils_isdir(repository_path.ptr) == GIT_SUCCESS) { + if (git_path_isdir(repository_path.ptr) == GIT_SUCCESS) { if (quickcheck_repository_dir(&repository_path) == GIT_SUCCESS) { error = repo_init_reinit(repository_path.ptr, is_bare); git_buf_free(&repository_path); diff --git a/src/status.c b/src/status.c index 3ead15a87..492edf568 100644 --- a/src/status.c +++ b/src/status.c @@ -489,7 +489,7 @@ int git_status_foreach( dirent_st.index_position = 0; dirent_st.is_dir = 1; - if (git_futils_isdir(workdir)) { + if (git_path_isdir(workdir)) { error = git__throw(GIT_EINVALIDPATH, "Failed to determine status of file '%s'. " "The given path doesn't lead to a folder", workdir); @@ -592,7 +592,7 @@ int git_status_file(unsigned int *status_flags, git_repository *repo, const char return git__rethrow(error, "Failed to determine status of file '%s'", path); - if (git_futils_isdir(temp_path.ptr) == GIT_SUCCESS) { + if (git_path_isdir(temp_path.ptr) == GIT_SUCCESS) { git_buf_free(&temp_path); return git__throw(GIT_EINVALIDPATH, "Failed to determine status of file '%s'. " @@ -606,7 +606,7 @@ int git_status_file(unsigned int *status_flags, git_repository *repo, const char } /* Find file in Workdir */ - if (git_futils_exists(temp_path.ptr) == GIT_SUCCESS) { + if (git_path_exists(temp_path.ptr) == GIT_SUCCESS) { if ((error = status_entry_update_from_workdir(e, temp_path.ptr)) < GIT_SUCCESS) goto cleanup; /* The callee has already set the error message */ } @@ -672,8 +672,8 @@ cleanup: } /* - * git_futils_direach is not supposed to return entries in an ordered manner. - * alphasorted_futils_direach wraps git_futils_direach and invokes the callback + * git_path_direach is not supposed to return entries in an ordered manner. + * alphasorted_futils_direach wraps git_path_direach and invokes the callback * function by passing it alphabeticcally sorted paths parameters. * */ @@ -686,7 +686,7 @@ static char *alphasorted_dirent_info_new(const git_buf *path) git_buf_copy_cstr(di, path->size + 1, path); - if (git_futils_isdir(path->ptr) == GIT_SUCCESS) { + if (git_path_isdir(path->ptr) == GIT_SUCCESS) { /* * Append a forward slash to the name to force folders * to be ordered in a similar way than in a tree @@ -734,7 +734,7 @@ static int alphasorted_futils_direach( if (git_vector_init(&entry_names, 16, git__strcmp_cb) < GIT_SUCCESS) return GIT_ENOMEM; - error = git_futils_direach(path, alphasorted_dirent_cb, &entry_names); + error = git_path_direach(path, alphasorted_dirent_cb, &entry_names); git_vector_sort(&entry_names); diff --git a/src/transport.c b/src/transport.c index d836561b4..00b79dc6d 100644 --- a/src/transport.c +++ b/src/transport.c @@ -23,7 +23,7 @@ static struct { {NULL, 0} }; -#define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) +#define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) - 1 static git_transport_cb transport_find_fn(const char *url) { diff --git a/src/transports/http.c b/src/transports/http.c index 48ea78dce..38446bdef 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -71,7 +71,7 @@ static int gen_request(git_buf *buf, const char *url, const char *host, const ch if (content_length > 0) { git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", service); git_buf_printf(buf, "Content-Type: application/x-git-%s-request\r\n", service); - git_buf_printf(buf, "Content-Length: %zd\r\n", content_length); + git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", content_length); } else { git_buf_puts(buf, "Accept: */*\r\n"); } diff --git a/src/tree.c b/src/tree.c index 8bc17d975..373d82b3a 100644 --- a/src/tree.c +++ b/src/tree.c @@ -30,7 +30,7 @@ static int entry_sort_cmp(const void *a, const void *b) const git_tree_entry *entry_a = (const git_tree_entry *)(a); const git_tree_entry *entry_b = (const git_tree_entry *)(b); - return git_futils_cmp_path( + return git_path_cmp( entry_a->filename, entry_a->filename_len, entry_is_tree(entry_a), entry_b->filename, entry_b->filename_len, entry_is_tree(entry_b)); } @@ -993,6 +993,7 @@ static int diff_index_cb(const char *root, git_tree_entry *tentry, void *data) if (!ientry) { error = signal_deletion(tentry, cbdata->cb, cbdata->data); + git_buf_free(&fn_buf); goto exit; } diff --git a/src/dir.h b/src/win32/dir.h index 5d50692e4..b16a3cfeb 100644 --- a/src/dir.h +++ b/src/win32/dir.h @@ -9,12 +9,6 @@ #include "common.h" -#ifndef GIT_WIN32 -# include <dirent.h> -#endif - -#ifdef GIT_WIN32 - struct git__dirent { int d_ino; char d_name[261]; @@ -42,6 +36,4 @@ extern int git__closedir(git__DIR *); # define closedir git__closedir # endif -#endif - #endif /* INCLUDE_dir_h__ */ diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index f68742fc0..3786f0162 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -80,7 +80,7 @@ static int do_lstat(const char *file_name, struct stat *buf) buf->st_uid = 0; buf->st_nlink = 1; buf->st_mode = (mode_t)fMode; - buf->st_size = (fdata.nFileSizeHigh << 32) + fdata.nFileSizeLow; + buf->st_size = ((git_off_t)fdata.nFileSizeHigh << 32) + fdata.nFileSizeLow; buf->st_dev = buf->st_rdev = (_getdrive() - 1); buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime)); buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime)); |