files-backend: convert git_path() to strbuf_git_path()

git_path() and friends are going to be killed in files-backend.c in near future. And because there's a risk with overwriting buffer in git_path(), let's convert them all to strbuf_git_path(). We'll have easier time killing/converting strbuf_git_path() then because we won't have to worry about memory management again. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Mar 26, 2017 at 09:42 UTC e9dcc3054fb0fdf0faafd0ef57a238f4a692fb23
1 file changed +97 -33
refs/files-backend.c
+97 -33
@@ -2316,6 +2316,7 @@ enum {
2316 static void try_remove_empty_parents(const char *refname, unsigned int flags)
2317 {
2318 struct strbuf buf = STRBUF_INIT;
2319 + struct strbuf sb = STRBUF_INIT;
2320 char *p, *q;
2321 int i;
2322
@@ -2337,14 +2338,19 @@ static void try_remove_empty_parents(const char *refname, unsigned int flags)
2338 if (q == p)
2339 break;
2340 strbuf_setlen(&buf, q - buf.buf);
2340 - if ((flags & REMOVE_EMPTY_PARENTS_REF) &&
2341 - rmdir(git_path("%s", buf.buf)))
2341 +
2342 + strbuf_reset(&sb);
2343 + strbuf_git_path(&sb, "%s", buf.buf);
2344 + if ((flags & REMOVE_EMPTY_PARENTS_REF) && rmdir(sb.buf))
2345 flags &= ~REMOVE_EMPTY_PARENTS_REF;
2343 - if ((flags & REMOVE_EMPTY_PARENTS_REFLOG) &&
2344 - rmdir(git_path("logs/%s", buf.buf)))
2346 +
2347 + strbuf_reset(&sb);
2348 + strbuf_git_path(&sb, "logs/%s", buf.buf);
2349 + if ((flags & REMOVE_EMPTY_PARENTS_REFLOG) && rmdir(sb.buf))
2350 flags &= ~REMOVE_EMPTY_PARENTS_REFLOG;
2351 }
2352 strbuf_release(&buf);
2353 + strbuf_release(&sb);
2354 }
2355
2356 /* make sure nobody touched the ref, and unlink */
@@ -2506,11 +2512,16 @@ out:
2512 */
2513 #define TMP_RENAMED_LOG "logs/refs/.tmp-renamed-log"
2514
2509 -static int rename_tmp_log_callback(const char *path, void *cb)
2515 +struct rename_cb {
2516 + const char *tmp_renamed_log;
2517 + int true_errno;
2518 +};
2519 +
2520 +static int rename_tmp_log_callback(const char *path, void *cb_data)
2521 {
2511 - int *true_errno = cb;
2522 + struct rename_cb *cb = cb_data;
2523
2513 - if (rename(git_path(TMP_RENAMED_LOG), path)) {
2524 + if (rename(cb->tmp_renamed_log, path)) {
2525 /*
2526 * rename(a, b) when b is an existing directory ought
2527 * to result in ISDIR, but Solaris 5.8 gives ENOTDIR.
@@ -2518,7 +2529,7 @@ static int rename_tmp_log_callback(const char *path, void *cb)
2529 * but report EISDIR to raceproof_create_file() so
2530 * that it knows to retry.
2531 */
2521 - *true_errno = errno;
2532 + cb->true_errno = errno;
2533 if (errno == ENOTDIR)
2534 errno = EISDIR;
2535 return -1;
@@ -2529,20 +2540,26 @@ static int rename_tmp_log_callback(const char *path, void *cb)
2540
2541 static int rename_tmp_log(const char *newrefname)
2542 {
2532 - char *path = git_pathdup("logs/%s", newrefname);
2533 - int ret, true_errno;
2543 + struct strbuf path = STRBUF_INIT;
2544 + struct strbuf tmp = STRBUF_INIT;
2545 + struct rename_cb cb;
2546 + int ret;
2547
2535 - ret = raceproof_create_file(path, rename_tmp_log_callback, &true_errno);
2548 + strbuf_git_path(&path, "logs/%s", newrefname);
2549 + strbuf_git_path(&tmp, TMP_RENAMED_LOG);
2550 + cb.tmp_renamed_log = tmp.buf;
2551 + ret = raceproof_create_file(path.buf, rename_tmp_log_callback, &cb);
2552 if (ret) {
2553 if (errno == EISDIR)
2538 - error("directory not empty: %s", path);
2554 + error("directory not empty: %s", path.buf);
2555 else
2556 error("unable to move logfile %s to %s: %s",
2541 - git_path(TMP_RENAMED_LOG), path,
2542 - strerror(true_errno));
2557 + tmp.buf, path.buf,
2558 + strerror(cb.true_errno));
2559 }
2560
2545 - free(path);
2561 + strbuf_release(&path);
2562 + strbuf_release(&tmp);
2563 return ret;
2564 }
2565
@@ -2583,10 +2600,17 @@ static int files_rename_ref(struct ref_store *ref_store,
2600 int flag = 0, logmoved = 0;
2601 struct ref_lock *lock;
2602 struct stat loginfo;
2586 - int log = !lstat(git_path("logs/%s", oldrefname), &loginfo);
2603 + struct strbuf sb_oldref = STRBUF_INIT;
2604 + struct strbuf sb_newref = STRBUF_INIT;
2605 + struct strbuf tmp_renamed_log = STRBUF_INIT;
2606 + int log, ret;
2607 struct strbuf err = STRBUF_INIT;
2588 - int ret;
2608
2609 + strbuf_git_path(&sb_oldref, "logs/%s", oldrefname);
2610 + strbuf_git_path(&sb_newref, "logs/%s", newrefname);
2611 + strbuf_git_path(&tmp_renamed_log, TMP_RENAMED_LOG);
2612 +
2613 + log = !lstat(sb_oldref.buf, &loginfo);
2614 if (log && S_ISLNK(loginfo.st_mode)) {
2615 ret = error("reflog for %s is a symlink", oldrefname);
2616 goto out;
@@ -2608,7 +2632,7 @@ static int files_rename_ref(struct ref_store *ref_store,
2632 goto out;
2633 }
2634
2611 - if (log && rename(git_path("logs/%s", oldrefname), git_path(TMP_RENAMED_LOG))) {
2635 + if (log && rename(sb_oldref.buf, tmp_renamed_log.buf)) {
2636 ret = error("unable to move logfile logs/%s to "TMP_RENAMED_LOG": %s",
2637 oldrefname, strerror(errno));
2638 goto out;
@@ -2690,16 +2714,19 @@ static int files_rename_ref(struct ref_store *ref_store,
2714 log_all_ref_updates = flag;
2715
2716 rollbacklog:
2693 - if (logmoved && rename(git_path("logs/%s", newrefname), git_path("logs/%s", oldrefname)))
2717 + if (logmoved && rename(sb_newref.buf, sb_oldref.buf))
2718 error("unable to restore logfile %s from %s: %s",
2719 oldrefname, newrefname, strerror(errno));
2720 if (!logmoved && log &&
2697 - rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", oldrefname)))
2721 + rename(tmp_renamed_log.buf, sb_oldref.buf))
2722 error("unable to restore logfile %s from "TMP_RENAMED_LOG": %s",
2723 oldrefname, strerror(errno));
2700 -
2724 ret = 1;
2725 out:
2726 + strbuf_release(&sb_newref);
2727 + strbuf_release(&sb_oldref);
2728 + strbuf_release(&tmp_renamed_log);
2729 +
2730 return ret;
2731 }
2732
@@ -2872,18 +2899,24 @@ static int files_log_ref_write(const char *refname, const unsigned char *old_sha
2899 result = log_ref_write_fd(logfd, old_sha1, new_sha1,
2900 git_committer_info(0), msg);
2901 if (result) {
2902 + struct strbuf sb = STRBUF_INIT;
2903 int save_errno = errno;
2904
2905 + strbuf_git_path(&sb, "logs/%s", refname);
2906 strbuf_addf(err, "unable to append to '%s': %s",
2878 - git_path("logs/%s", refname), strerror(save_errno));
2907 + sb.buf, strerror(save_errno));
2908 + strbuf_release(&sb);
2909 close(logfd);
2910 return -1;
2911 }
2912 if (close(logfd)) {
2913 + struct strbuf sb = STRBUF_INIT;
2914 int save_errno = errno;
2915
2916 + strbuf_git_path(&sb, "logs/%s", refname);
2917 strbuf_addf(err, "unable to append to '%s': %s",
2886 - git_path("logs/%s", refname), strerror(save_errno));
2918 + sb.buf, strerror(save_errno));
2919 + strbuf_release(&sb);
2920 return -1;
2921 }
2922 return 0;
@@ -3103,22 +3136,32 @@ int set_worktree_head_symref(const char *gitdir, const char *target, const char
3136 static int files_reflog_exists(struct ref_store *ref_store,
3137 const char *refname)
3138 {
3139 + struct strbuf sb = STRBUF_INIT;
3140 struct stat st;
3141 + int ret;
3142
3143 /* Check validity (but we don't need the result): */
3144 files_downcast(ref_store, 0, "reflog_exists");
3145
3111 - return !lstat(git_path("logs/%s", refname), &st) &&
3112 - S_ISREG(st.st_mode);
3146 + strbuf_git_path(&sb, "logs/%s", refname);
3147 + ret = !lstat(sb.buf, &st) && S_ISREG(st.st_mode);
3148 + strbuf_release(&sb);
3149 + return ret;
3150 }
3151
3152 static int files_delete_reflog(struct ref_store *ref_store,
3153 const char *refname)
3154 {
3155 + struct strbuf sb = STRBUF_INIT;
3156 + int ret;
3157 +
3158 /* Check validity (but we don't need the result): */
3159 files_downcast(ref_store, 0, "delete_reflog");
3160
3121 - return remove_path(git_path("logs/%s", refname));
3161 + strbuf_git_path(&sb, "logs/%s", refname);
3162 + ret = remove_path(sb.buf);
3163 + strbuf_release(&sb);
3164 + return ret;
3165 }
3166
3167 static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *cb_data)
@@ -3174,7 +3217,9 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
3217 /* Check validity (but we don't need the result): */
3218 files_downcast(ref_store, 0, "for_each_reflog_ent_reverse");
3219
3177 - logfp = fopen(git_path("logs/%s", refname), "r");
3220 + strbuf_git_path(&sb, "logs/%s", refname);
3221 + logfp = fopen(sb.buf, "r");
3222 + strbuf_release(&sb);
3223 if (!logfp)
3224 return -1;
3225
@@ -3280,7 +3325,9 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store,
3325 /* Check validity (but we don't need the result): */
3326 files_downcast(ref_store, 0, "for_each_reflog_ent");
3327
3283 - logfp = fopen(git_path("logs/%s", refname), "r");
3328 + strbuf_git_path(&sb, "logs/%s", refname);
3329 + logfp = fopen(sb.buf, "r");
3330 + strbuf_release(&sb);
3331 if (!logfp)
3332 return -1;
3333
@@ -3362,12 +3409,15 @@ static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st
3409 {
3410 struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
3411 struct ref_iterator *ref_iterator = &iter->base;
3412 + struct strbuf sb = STRBUF_INIT;
3413
3414 /* Check validity (but we don't need the result): */
3415 files_downcast(ref_store, 0, "reflog_iterator_begin");
3416
3417 base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable);
3370 - iter->dir_iterator = dir_iterator_begin(git_path("logs"));
3418 + strbuf_git_path(&sb, "logs");
3419 + iter->dir_iterator = dir_iterator_begin(sb.buf);
3420 + strbuf_release(&sb);
3421 return ref_iterator;
3422 }
3423
@@ -3705,6 +3755,7 @@ static int files_transaction_commit(struct ref_store *ref_store,
3755 char *head_ref = NULL;
3756 int head_type;
3757 struct object_id head_oid;
3758 + struct strbuf sb = STRBUF_INIT;
3759
3760 assert(err);
3761
@@ -3826,7 +3877,9 @@ static int files_transaction_commit(struct ref_store *ref_store,
3877 if (!(update->type & REF_ISPACKED) ||
3878 update->type & REF_ISSYMREF) {
3879 /* It is a loose reference. */
3829 - if (unlink_or_msg(git_path("%s", lock->ref_name), err)) {
3880 + strbuf_reset(&sb);
3881 + strbuf_git_path(&sb, "%s", lock->ref_name);
3882 + if (unlink_or_msg(sb.buf, err)) {
3883 ret = TRANSACTION_GENERIC_ERROR;
3884 goto cleanup;
3885 }
@@ -3846,7 +3899,9 @@ static int files_transaction_commit(struct ref_store *ref_store,
3899
3900 /* Delete the reflogs of any references that were deleted: */
3901 for_each_string_list_item(ref_to_delete, &refs_to_delete) {
3849 - if (!unlink_or_warn(git_path("logs/%s", ref_to_delete->string)))
3902 + strbuf_reset(&sb);
3903 + strbuf_git_path(&sb, "logs/%s", ref_to_delete->string);
3904 + if (!unlink_or_warn(sb.buf))
3905 try_remove_empty_parents(ref_to_delete->string,
3906 REMOVE_EMPTY_PARENTS_REFLOG);
3907 }
@@ -3854,6 +3909,7 @@ static int files_transaction_commit(struct ref_store *ref_store,
3909 clear_loose_ref_cache(refs);
3910
3911 cleanup:
3912 + strbuf_release(&sb);
3913 transaction->state = REF_TRANSACTION_CLOSED;
3914
3915 for (i = 0; i < transaction->nr; i++) {
@@ -4120,14 +4176,22 @@ static int files_reflog_expire(struct ref_store *ref_store,
4176
4177 static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
4178 {
4179 + struct strbuf sb = STRBUF_INIT;
4180 +
4181 /* Check validity (but we don't need the result): */
4182 files_downcast(ref_store, 0, "init_db");
4183
4184 /*
4185 * Create .git/refs/{heads,tags}
4186 */
4129 - safe_create_dir(git_path("refs/heads"), 1);
4130 - safe_create_dir(git_path("refs/tags"), 1);
4187 + strbuf_git_path(&sb, "refs/heads");
4188 + safe_create_dir(sb.buf, 1);
4189 +
4190 + strbuf_reset(&sb);
4191 + strbuf_git_path(&sb, "refs/tags");
4192 + safe_create_dir(sb.buf, 1);
4193 +
4194 + strbuf_release(&sb);
4195 return 0;
4196 }
4197