diff options
author | Russell Belfer <arrbee@arrbee.com> | 2011-11-30 23:27:15 +0400 |
---|---|---|
committer | Russell Belfer <arrbee@arrbee.com> | 2011-12-08 11:08:15 +0400 |
commit | 97769280ba9938ae27f6e06cbd0d5e8a768a86b9 (patch) | |
tree | 4fe43e99acb55f904f6b586bd7c5158610f9512f /src/blob.c | |
parent | a22b14d32dd8d5f06f121aa154d45bac3b10a305 (diff) |
Use git_buf for path storage instead of stack-based buffers
This converts virtually all of the places that allocate GIT_PATH_MAX
buffers on the stack for manipulating paths to use git_buf objects
instead. The patch is pretty careful not to touch the public API
for libgit2, so there are a few places that still use GIT_PATH_MAX.
This extends and changes some details of the git_buf implementation
to add a couple of extra functions and to make error handling easier.
This includes serious alterations to all the path.c functions, and
several of the fileops.c ones, too. Also, there are a number of new
functions that parallel existing ones except that use a git_buf
instead of a stack-based buffer (such as git_config_find_global_r
that exists alongsize git_config_find_global).
This also modifies the win32 version of p_realpath to allocate whatever
buffer size is needed to accommodate the realpath instead of hardcoding
a GIT_PATH_MAX limit, but that change needs to be tested still.
Diffstat (limited to 'src/blob.c')
-rw-r--r-- | src/blob.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/src/blob.c b/src/blob.c index 87f5686af..7497ba7bf 100644 --- a/src/blob.c +++ b/src/blob.c @@ -67,12 +67,13 @@ 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, islnk; + int error = GIT_SUCCESS; + int islnk = 0; int fd = 0; - char full_path[GIT_PATH_MAX]; + git_buf full_path = GIT_BUF_INIT; char buffer[2048]; git_off_t size; - git_odb_stream *stream; + git_odb_stream *stream = NULL; struct stat st; const char *workdir; git_odb *odb; @@ -81,11 +82,14 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat if (workdir == NULL) return git__throw(GIT_ENOTFOUND, "Failed to create blob. (No working directory found)"); - git_path_join(full_path, workdir, path); + error = git_buf_joinpath(&full_path, workdir, path); + if (error < GIT_SUCCESS) + return error; - error = p_lstat(full_path, &st); + error = p_lstat(full_path.ptr, &st); if (error < 0) { - return git__throw(GIT_EOSERR, "Failed to stat blob. %s", strerror(errno)); + error = git__throw(GIT_EOSERR, "Failed to stat blob. %s", strerror(errno)); + goto cleanup; } islnk = S_ISLNK(st.st_mode); @@ -93,18 +97,18 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat error = git_repository_odb__weakptr(&odb, repo); if (error < GIT_SUCCESS) - return error; + goto cleanup; if (!islnk) { - if ((fd = p_open(full_path, O_RDONLY)) < 0) - return git__throw(GIT_ENOTFOUND, "Failed to create blob. Could not open '%s'", full_path); + 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) { - if (!islnk) - p_close(fd); - return git__rethrow(error, "Failed to create blob"); - } + if ((error = git_odb_open_wstream(&stream, odb, (size_t)size, GIT_OBJ_BLOB)) < GIT_SUCCESS) + goto cleanup; while (size > 0) { ssize_t read_len; @@ -112,13 +116,11 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat if (!islnk) read_len = p_read(fd, buffer, sizeof(buffer)); else - read_len = p_readlink(full_path, buffer, sizeof(buffer)); + read_len = p_readlink(full_path.ptr, buffer, sizeof(buffer)); if (read_len < 0) { - if (!islnk) - p_close(fd); - stream->free(stream); - return git__throw(GIT_EOSERR, "Failed to create blob. Can't read full file"); + error = git__throw(GIT_EOSERR, "Failed to create blob. Can't read full file"); + goto cleanup; } stream->write(stream, buffer, read_len); @@ -126,10 +128,15 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat } error = stream->finalize_write(oid, stream); - stream->free(stream); - if (!islnk) + +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 == GIT_SUCCESS ? GIT_SUCCESS : + git__rethrow(error, "Failed to create blob"); } |