summaryrefslogtreecommitdiff
path: root/src/indexer.c
diff options
context:
space:
mode:
authorRussell Belfer <arrbee@arrbee.com>2011-11-30 11:27:15 -0800
committerRussell Belfer <arrbee@arrbee.com>2011-12-07 23:08:15 -0800
commit97769280ba9938ae27f6e06cbd0d5e8a768a86b9 (patch)
tree4fe43e99acb55f904f6b586bd7c5158610f9512f /src/indexer.c
parenta22b14d32dd8d5f06f121aa154d45bac3b10a305 (diff)
downloadlibgit2-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/indexer.c')
-rw-r--r--src/indexer.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/src/indexer.c b/src/indexer.c
index a69ab850c..8fdf89d9d 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -151,28 +151,35 @@ cleanup:
return error;
}
-static void index_path(char *path, git_indexer *idx)
+static int index_path(git_buf *path, git_indexer *idx)
{
- char *ptr;
const char prefix[] = "pack-", suffix[] = ".idx";
+ size_t slash = (size_t)path->size;
- ptr = strrchr(path, '/') + 1;
+ /* search backwards for '/' */
+ while (slash > 0 && path->ptr[slash - 1] != '/')
+ slash--;
- memcpy(ptr, prefix, strlen(prefix));
- ptr += strlen(prefix);
- git_oid_fmt(ptr, &idx->hash);
- ptr += GIT_OID_HEXSZ;
- memcpy(ptr, suffix, strlen(suffix) + 1);
+ if (git_buf_grow(path, slash + 1 + strlen(prefix) +
+ GIT_OID_HEXSZ + strlen(suffix) + 1) < GIT_SUCCESS)
+ return GIT_ENOMEM;
+
+ git_buf_truncate(path, slash + 1);
+ git_buf_puts(path, prefix);
+ git_oid_fmt(path->ptr + path->size, &idx->hash);
+ path->size += GIT_OID_HEXSZ;
+ git_buf_puts(path, suffix);
+
+ return git_buf_lasterror(path);
}
int git_indexer_write(git_indexer *idx)
{
git_mwindow *w = NULL;
int error;
- size_t namelen;
unsigned int i, long_offsets = 0, left;
struct git_pack_idx_header hdr;
- char filename[GIT_PATH_MAX];
+ git_buf filename = GIT_BUF_INIT;
struct entry *entry;
void *packfile_hash;
git_oid file_hash;
@@ -180,16 +187,23 @@ int git_indexer_write(git_indexer *idx)
git_vector_sort(&idx->objects);
- namelen = strlen(idx->pack->pack_name);
- memcpy(filename, idx->pack->pack_name, namelen);
- memcpy(filename + namelen - strlen("pack"), "idx", strlen("idx") + 1);
+ git_buf_sets(&filename, idx->pack->pack_name);
+ git_buf_truncate(&filename, filename.size - strlen("pack"));
+ git_buf_puts(&filename, "idx");
- error = git_filebuf_open(&idx->file, filename, GIT_FILEBUF_HASH_CONTENTS);
+ if ((error = git_buf_lasterror(&filename)) < GIT_SUCCESS)
+ goto cleanup;
+
+ error = git_filebuf_open(&idx->file, filename.ptr, GIT_FILEBUF_HASH_CONTENTS);
+ if (error < GIT_SUCCESS)
+ goto cleanup;
/* Write out the header */
hdr.idx_signature = htonl(PACK_IDX_SIGNATURE);
hdr.idx_version = htonl(2);
error = git_filebuf_write(&idx->file, &hdr, sizeof(hdr));
+ if (error < GIT_SUCCESS)
+ goto cleanup;
/* Write out the fanout table */
for (i = 0; i < 256; ++i) {
@@ -270,14 +284,18 @@ int git_indexer_write(git_indexer *idx)
goto cleanup;
/* Figure out what the final name should be */
- index_path(filename, idx);
+ error = index_path(&filename, idx);
+ if (error < GIT_SUCCESS)
+ goto cleanup;
+
/* Commit file */
- error = git_filebuf_commit_at(&idx->file, filename, GIT_PACK_FILE_MODE);
+ error = git_filebuf_commit_at(&idx->file, filename.ptr, GIT_PACK_FILE_MODE);
cleanup:
git_mwindow_free_all(&idx->pack->mwf);
if (error < GIT_SUCCESS)
git_filebuf_cleanup(&idx->file);
+ git_buf_free(&filename);
return error;
}