summaryrefslogtreecommitdiff
path: root/src/blob.c
diff options
context:
space:
mode:
authorVicent Martí <tanoku@gmail.com>2012-02-10 20:16:42 +0100
committerVicent Martí <tanoku@gmail.com>2012-02-10 20:16:42 +0100
commitf19e3ca28835eab8dbef62915c475caa18f355fe (patch)
tree65018936e22b2fea693bc57a6433e14e4d127df5 /src/blob.c
parent18e5b8547d075afc53c2b20ba15ef7c09cb5efd6 (diff)
downloadlibgit2-f19e3ca28835eab8dbef62915c475caa18f355fe.tar.gz
odb: Proper symlink hashing
Diffstat (limited to 'src/blob.c')
-rw-r--r--src/blob.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/src/blob.c b/src/blob.c
index 7497ba7b..4e95bd9c 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -68,10 +68,7 @@ int git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *b
int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path)
{
int error = GIT_SUCCESS;
- int islnk = 0;
- int fd = 0;
git_buf full_path = GIT_BUF_INIT;
- char buffer[2048];
git_off_t size;
git_odb_stream *stream = NULL;
struct stat st;
@@ -92,39 +89,59 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
goto cleanup;
}
- islnk = S_ISLNK(st.st_mode);
size = st.st_size;
error = git_repository_odb__weakptr(&odb, repo);
if (error < GIT_SUCCESS)
goto cleanup;
- if (!islnk) {
- if ((fd = p_open(full_path.ptr, O_RDONLY)) < 0) {
- error = git__throw(GIT_ENOTFOUND, "Failed to create blob. Could not open '%s'", full_path.ptr
-);
- goto cleanup;
- }
- }
-
if ((error = git_odb_open_wstream(&stream, odb, (size_t)size, GIT_OBJ_BLOB)) < GIT_SUCCESS)
goto cleanup;
- while (size > 0) {
+ if (S_ISLNK(st.st_mode)) {
+ char *link_data;
ssize_t read_len;
- if (!islnk)
- read_len = p_read(fd, buffer, sizeof(buffer));
- else
- read_len = p_readlink(full_path.ptr, buffer, sizeof(buffer));
+ link_data = git__malloc(size);
+ if (!link_data) {
+ error = GIT_ENOMEM;
+ goto cleanup;
+ }
+
+ read_len = p_readlink(full_path.ptr, link_data, size);
- if (read_len < 0) {
- error = git__throw(GIT_EOSERR, "Failed to create blob. Can't read full file");
+ if (read_len != (ssize_t)size) {
+ error = git__throw(GIT_EOSERR, "Failed to create blob. Can't read symlink");
+ free(link_data);
goto cleanup;
}
- stream->write(stream, buffer, read_len);
- size -= read_len;
+ stream->write(stream, link_data, size);
+ free(link_data);
+
+ } else {
+ int fd;
+ char buffer[2048];
+
+ if ((fd = p_open(full_path.ptr, O_RDONLY)) < 0) {
+ error = git__throw(GIT_ENOTFOUND, "Failed to create blob. Could not open '%s'", full_path.ptr);
+ goto cleanup;
+ }
+
+ while (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;
+ }
+
+ stream->write(stream, buffer, read_len);
+ size -= read_len;
+ }
+
+ p_close(fd);
}
error = stream->finalize_write(oid, stream);
@@ -132,11 +149,9 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
cleanup:
if (stream)
stream->free(stream);
- if (!islnk && fd)
- p_close(fd);
+
git_buf_free(&full_path);
- return error == GIT_SUCCESS ? GIT_SUCCESS :
- git__rethrow(error, "Failed to create blob");
+ return error;
}