diff options
| author | Russell Belfer <arrbee@arrbee.com> | 2011-11-30 11:27:15 -0800 |
|---|---|---|
| committer | Russell Belfer <arrbee@arrbee.com> | 2011-12-07 23:08:15 -0800 |
| commit | 97769280ba9938ae27f6e06cbd0d5e8a768a86b9 (patch) | |
| tree | 4fe43e99acb55f904f6b586bd7c5158610f9512f /src/reflog.c | |
| parent | a22b14d32dd8d5f06f121aa154d45bac3b10a305 (diff) | |
| download | libgit2-97769280ba9938ae27f6e06cbd0d5e8a768a86b9.tar.gz | |
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/reflog.c')
| -rw-r--r-- | src/reflog.c | 119 |
1 files changed, 74 insertions, 45 deletions
diff --git a/src/reflog.c b/src/reflog.c index fbaaaea67..84ce52d91 100644 --- a/src/reflog.c +++ b/src/reflog.c @@ -51,7 +51,7 @@ static int reflog_write(const char *log_path, const char *oid_old, git_buf_puts(&log, oid_new); git_signature__writebuf(&log, " ", committer); - log.size--; /* drop LF */ + git_buf_truncate(&log, log.size - 1); /* drop LF */ if (msg) { if (strchr(msg, '\n')) { @@ -65,15 +65,21 @@ static int reflog_write(const char *log_path, const char *oid_old, git_buf_putc(&log, '\n'); + if ((error = git_buf_lasterror(&log)) < GIT_SUCCESS) { + git_buf_free(&log); + return git__rethrow(error, "Failed to write reflog. Memory allocation failure"); + } + if ((error = git_filebuf_open(&fbuf, log_path, GIT_FILEBUF_APPEND)) < GIT_SUCCESS) { git_buf_free(&log); - return git__throw(GIT_ERROR, "Failed to write reflog. Cannot open reflog `%s`", log_path); + return git__rethrow(error, "Failed to write reflog. Cannot open reflog `%s`", log_path); } git_filebuf_write(&fbuf, log.ptr, log.size); error = git_filebuf_commit(&fbuf, GIT_REFLOG_FILE_MODE); git_buf_free(&log); + return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to write reflog"); } @@ -176,7 +182,7 @@ void git_reflog_free(git_reflog *reflog) int git_reflog_read(git_reflog **reflog, git_reference *ref) { int error; - char log_path[GIT_PATH_MAX]; + git_buf log_path = GIT_BUF_INIT; git_fbuffer log_file = GIT_FBUFFER_INIT; git_reflog *log = NULL; @@ -185,23 +191,28 @@ int git_reflog_read(git_reflog **reflog, git_reference *ref) if ((error = reflog_init(&log, ref)) < GIT_SUCCESS) return git__rethrow(error, "Failed to read reflog. Cannot init reflog"); - git_path_join_n(log_path, 3, ref->owner->path_repository, GIT_REFLOG_DIR, ref->name); + error = git_buf_join_n(&log_path, '/', 3, + ref->owner->path_repository, GIT_REFLOG_DIR, ref->name); + if (error < GIT_SUCCESS) + goto cleanup; - if ((error = git_futils_readbuffer(&log_file, log_path)) < GIT_SUCCESS) { - git_reflog_free(log); - return git__rethrow(error, "Failed to read reflog. Cannot read file `%s`", log_path); + if ((error = git_futils_readbuffer(&log_file, log_path.ptr)) < GIT_SUCCESS) { + git__rethrow(error, "Failed to read reflog. Cannot read file `%s`", log_path.ptr); + goto cleanup; } - error = reflog_parse(log, log_file.data, log_file.len); - - git_futils_freebuffer(&log_file); - - if (error == GIT_SUCCESS) - *reflog = log; + if ((error = reflog_parse(log, log_file.data, log_file.len)) < GIT_SUCCESS) + git__rethrow(error, "Failed to read reflog"); else + *reflog = log; + +cleanup: + if (error != GIT_SUCCESS && log != NULL) git_reflog_free(log); + git_futils_freebuffer(&log_file); + git_buf_free(&log_path); - return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to read reflog"); + return error; } int git_reflog_write(git_reference *ref, const git_oid *oid_old, @@ -210,7 +221,7 @@ int git_reflog_write(git_reference *ref, const git_oid *oid_old, int error; char old[GIT_OID_HEXSZ+1]; char new[GIT_OID_HEXSZ+1]; - char log_path[GIT_PATH_MAX]; + git_buf log_path = GIT_BUF_INIT; git_reference *r; const git_oid *oid; @@ -220,65 +231,83 @@ int git_reflog_write(git_reference *ref, const git_oid *oid_old, oid = git_reference_oid(r); if (oid == NULL) { - git_reference_free(r); - return git__throw(GIT_ERROR, + error = git__throw(GIT_ERROR, "Failed to write reflog. Cannot resolve reference `%s`", r->name); + git_reference_free(r); + return error; } + git_reference_free(r); + git_oid_to_string(new, GIT_OID_HEXSZ+1, oid); - git_path_join_n(log_path, 3, + error = git_buf_join_n(&log_path, '/', 3, ref->owner->path_repository, GIT_REFLOG_DIR, ref->name); + if (error < GIT_SUCCESS) + goto cleanup; - git_reference_free(r); - - if (git_futils_exists(log_path)) { - error = git_futils_mkpath2file(log_path, GIT_REFLOG_DIR_MODE); + if (git_futils_exists(log_path.ptr)) { + error = git_futils_mkpath2file(log_path.ptr, GIT_REFLOG_DIR_MODE); if (error < GIT_SUCCESS) - return git__rethrow(error, + git__rethrow(error, "Failed to write reflog. Cannot create reflog directory"); - - } else if (git_futils_isfile(log_path)) { - return git__throw(GIT_ERROR, - "Failed to write reflog. `%s` is directory", log_path); - + } else if (git_futils_isfile(log_path.ptr)) { + error = git__throw(GIT_ERROR, + "Failed to write reflog. `%s` is directory", log_path.ptr); } else if (oid_old == NULL) { - return git__throw(GIT_ERROR, + error = git__throw(GIT_ERROR, "Failed to write reflog. Old OID cannot be NULL for existing reference"); } + if (error < GIT_SUCCESS) + goto cleanup; + if (oid_old) - git_oid_to_string(old, GIT_OID_HEXSZ+1, oid_old); + git_oid_to_string(old, sizeof(old), oid_old); else - p_snprintf(old, GIT_OID_HEXSZ+1, "%0*d", GIT_OID_HEXSZ, 0); + p_snprintf(old, sizeof(old), "%0*d", GIT_OID_HEXSZ, 0); + + error = reflog_write(log_path.ptr, old, new, committer, msg); - return reflog_write(log_path, old, new, committer, msg); +cleanup: + git_buf_free(&log_path); + return error; } int git_reflog_rename(git_reference *ref, const char *new_name) { - char old_path[GIT_PATH_MAX]; - char new_path[GIT_PATH_MAX]; + int error; + git_buf old_path = GIT_BUF_INIT; + git_buf new_path = GIT_BUF_INIT; + + if (git_buf_join_n(&old_path, '/', 3, ref->owner->path_repository, + GIT_REFLOG_DIR, ref->name) && + git_buf_join_n(&new_path, '/', 3, ref->owner->path_repository, + GIT_REFLOG_DIR, new_name)) + error = p_rename(git_buf_cstr(&old_path), git_buf_cstr(&new_path)); + else + error = GIT_ENOMEM; - git_path_join_n(old_path, 3, ref->owner->path_repository, - GIT_REFLOG_DIR, ref->name); - git_path_join_n(new_path, 3, ref->owner->path_repository, - GIT_REFLOG_DIR, new_name); + git_buf_free(&old_path); + git_buf_free(&new_path); - return p_rename(old_path, new_path); + return error; } int git_reflog_delete(git_reference *ref) { - char path[GIT_PATH_MAX]; + int error = GIT_SUCCESS; + git_buf path = GIT_BUF_INIT; + + error = git_buf_join_n(&path, '/', 3, + ref->owner->path_repository, GIT_REFLOG_DIR, ref->name); - git_path_join_n(path, 3, ref->owner->path_repository, - GIT_REFLOG_DIR, ref->name); + if (error == GIT_SUCCESS && git_futils_exists(path.ptr) == 0) + error = p_unlink(path.ptr); - if (git_futils_exists(path)) - return GIT_SUCCESS; + git_buf_free(&path); - return p_unlink(path); + return error; } unsigned int git_reflog_entrycount(git_reflog *reflog) |
