Download raw body.
avoid per tree-entry asprintf/free
Avoid doing asprintf/free per tree entry in got_pack_load_tree_entries().
Allocate one path buffer and keep growing it as needed. For directories we
still need to copy the path. But blobs can use the path buffer directly.
ok?
M lib/pack_create.c | 38+ 11-
1 file changed, 38 insertions(+), 11 deletions(-)
commit - 23c16b295963fd2cfddf454ef642b1dfb6afa3d1
commit + bf9514555f3e1bcbc972ed5f791d2cf0a9c797e6
blob - 88ae6a7f7857b14079689f7c4e8f26ef6cebdfce
blob + 0e3b3d8caf3352ddb1c89e6e64acc9d0897aa079
--- lib/pack_create.c
+++ lib/pack_create.c
@@ -797,7 +797,7 @@ got_pack_load_tree_entries(struct got_object_id_queue
{
const struct got_error *err;
char *p = NULL;
- int i;
+ int i, ret, psize = _POSIX_PATH_MAX;
(*ntrees)++;
err = got_pack_report_progress(progress_cb, progress_arg, rl,
@@ -805,6 +805,11 @@ got_pack_load_tree_entries(struct got_object_id_queue
if (err)
return err;
+ p = malloc(psize);
+ if (p == NULL)
+ return got_error_from_errno("malloc");
+ p[0] = '\0';
+
for (i = 0; i < got_object_tree_get_nentries(tree); i++) {
struct got_tree_entry *e = got_object_tree_get_entry(tree, i);
struct got_object_id *id = got_tree_entry_get_id(e);
@@ -828,20 +833,47 @@ got_pack_load_tree_entries(struct got_object_id_queue
if (ids == NULL && S_ISDIR(mode))
continue;
- if (asprintf(&p, "%s%s%s", dpath,
+ ret = snprintf(p, psize, "%s%s%s", dpath,
got_path_is_root_dir(dpath) ? "" : "/",
- got_tree_entry_get_name(e)) == -1) {
- err = got_error_from_errno("asprintf");
+ got_tree_entry_get_name(e));
+ if (ret == -1) {
+ err = got_error_from_errno("snprintf");
break;
}
+ if (ret >= psize) {
+ char *s;
+ s = realloc(p, ret + 1);
+ if (s == NULL) {
+ err = got_error_from_errno("realloc");
+ break;
+ }
+ p = s;
+ psize = ret + 1;
+
+ ret = snprintf(p, psize, "%s%s%s", dpath,
+ got_path_is_root_dir(dpath) ? "" : "/",
+ got_tree_entry_get_name(e));
+ if (ret == -1) {
+ err = got_error_from_errno("snprintf");
+ break;
+ }
+ if (ret >= psize) { /* should not happen */
+ err = got_error(GOT_ERR_NO_SPACE);
+ break;
+ }
+ }
+
if (S_ISDIR(mode)) {
struct got_object_qid *qid;
err = got_object_qid_alloc(&qid, id);
if (err)
break;
- qid->data = p;
- p = NULL;
+ qid->data = strdup(p);
+ if (qid->data == NULL) {
+ err = got_error_from_errno("strdup");
+ break;
+ }
STAILQ_INSERT_TAIL(ids, qid, entry);
} else if (S_ISREG(mode) || S_ISLNK(mode)) {
err = got_pack_add_object(want_meta,
@@ -851,11 +883,6 @@ got_pack_load_tree_entries(struct got_object_id_queue
progress_cb, progress_arg, rl);
if (err)
break;
- free(p);
- p = NULL;
- } else {
- free(p);
- p = NULL;
}
}
avoid per tree-entry asprintf/free