Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2013-04-16 19:46:41 +0400
committerVicent Marti <tanoku@gmail.com>2013-04-16 19:46:41 +0400
commita50086d174658914d4d6462afbc83b02825b1f5b (patch)
treee8daa1c7bf678222cf351445179837bed7db3a72 /src/filebuf.c
parent5b9fac39d8a76b9139667c26a63e6b3f204b3977 (diff)
parentf124ebd457bfbf43de3516629aaba5a279636e04 (diff)
Merge branch 'development'v0.18.0
Diffstat (limited to 'src/filebuf.c')
-rw-r--r--src/filebuf.c81
1 files changed, 62 insertions, 19 deletions
diff --git a/src/filebuf.c b/src/filebuf.c
index 6538aea66..246ae34e7 100644
--- a/src/filebuf.c
+++ b/src/filebuf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
@@ -50,6 +50,7 @@ static int lock_file(git_filebuf *file, int flags)
if (flags & GIT_FILEBUF_FORCE)
p_unlink(file->path_lock);
else {
+ giterr_clear(); /* actual OS error code just confuses */
giterr_set(GITERR_OS,
"Failed to lock file '%s' for writing", file->path_lock);
return -1;
@@ -72,7 +73,7 @@ static int lock_file(git_filebuf *file, int flags)
if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == true) {
git_file source;
char buffer[2048];
- size_t read_bytes;
+ ssize_t read_bytes;
source = p_open(file->path_original, O_RDONLY);
if (source < 0) {
@@ -82,13 +83,18 @@ static int lock_file(git_filebuf *file, int flags)
return -1;
}
- while ((read_bytes = p_read(source, buffer, 2048)) > 0) {
+ while ((read_bytes = p_read(source, buffer, sizeof(buffer))) > 0) {
p_write(file->fd, buffer, read_bytes);
- if (file->digest)
- git_hash_update(file->digest, buffer, read_bytes);
+ if (file->compute_digest)
+ git_hash_update(&file->digest, buffer, read_bytes);
}
p_close(source);
+
+ if (read_bytes < 0) {
+ giterr_set(GITERR_OS, "Failed to read file '%s'", file->path_original);
+ return -1;
+ }
}
return 0;
@@ -102,8 +108,10 @@ void git_filebuf_cleanup(git_filebuf *file)
if (file->fd_is_open && file->path_lock && git_path_exists(file->path_lock))
p_unlink(file->path_lock);
- if (file->digest)
- git_hash_free_ctx(file->digest);
+ if (file->compute_digest) {
+ git_hash_ctx_cleanup(&file->digest);
+ file->compute_digest = 0;
+ }
if (file->buffer)
git__free(file->buffer);
@@ -130,6 +138,11 @@ GIT_INLINE(int) flush_buffer(git_filebuf *file)
return result;
}
+int git_filebuf_flush(git_filebuf *file)
+{
+ return flush_buffer(file);
+}
+
static int write_normal(git_filebuf *file, void *source, size_t len)
{
if (len > 0) {
@@ -138,8 +151,8 @@ static int write_normal(git_filebuf *file, void *source, size_t len)
return -1;
}
- if (file->digest)
- git_hash_update(file->digest, source, len);
+ if (file->compute_digest)
+ git_hash_update(&file->digest, source, len);
}
return 0;
@@ -175,8 +188,8 @@ static int write_deflate(git_filebuf *file, void *source, size_t len)
assert(zs->avail_in == 0);
- if (file->digest)
- git_hash_update(file->digest, source, len);
+ if (file->compute_digest)
+ git_hash_update(&file->digest, source, len);
}
return 0;
@@ -210,8 +223,10 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags)
/* If we are hashing on-write, allocate a new hash context */
if (flags & GIT_FILEBUF_HASH_CONTENTS) {
- file->digest = git_hash_new_ctx();
- GITERR_CHECK_ALLOC(file->digest);
+ file->compute_digest = 1;
+
+ if (git_hash_ctx_init(&file->digest) < 0)
+ goto cleanup;
}
compression = flags >> GIT_FILEBUF_DEFLATE_SHIFT;
@@ -280,16 +295,16 @@ cleanup:
int git_filebuf_hash(git_oid *oid, git_filebuf *file)
{
- assert(oid && file && file->digest);
+ assert(oid && file && file->compute_digest);
flush_buffer(file);
if (verify_last_error(file) < 0)
return -1;
- git_hash_final(oid, file->digest);
- git_hash_free_ctx(file->digest);
- file->digest = NULL;
+ git_hash_final(oid, &file->digest);
+ git_hash_ctx_cleanup(&file->digest);
+ file->compute_digest = 0;
return 0;
}
@@ -314,10 +329,15 @@ int git_filebuf_commit(git_filebuf *file, mode_t mode)
if (verify_last_error(file) < 0)
goto on_error;
- p_close(file->fd);
- file->fd = -1;
file->fd_is_open = false;
+ if (p_close(file->fd) < 0) {
+ giterr_set(GITERR_OS, "Failed to close file at '%s'", file->path_lock);
+ goto on_error;
+ }
+
+ file->fd = -1;
+
if (p_chmod(file->path_lock, mode)) {
giterr_set(GITERR_OS, "Failed to set attributes for file at '%s'", file->path_lock);
goto on_error;
@@ -450,3 +470,26 @@ int git_filebuf_printf(git_filebuf *file, const char *format, ...)
return res;
}
+int git_filebuf_stats(time_t *mtime, size_t *size, git_filebuf *file)
+{
+ int res;
+ struct stat st;
+
+ if (file->fd_is_open)
+ res = p_fstat(file->fd, &st);
+ else
+ res = p_stat(file->path_original, &st);
+
+ if (res < 0) {
+ giterr_set(GITERR_OS, "Could not get stat info for '%s'",
+ file->path_original);
+ return res;
+ }
+
+ if (mtime)
+ *mtime = st.st_mtime;
+ if (size)
+ *size = (size_t)st.st_size;
+
+ return 0;
+}