{"thread":{"id":"18695","subject":"[PATCH] builtin-clone.c: allow multiple cmd_clone() calls","startedAt":"2009-04-02T14:22:08Z","lastAt":"2009-04-02T14:22:08Z","messageCount":1,"participants":["Ali Gholami Rudi"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"110219","messageId":"20090402142208.GA3886@lilem.mirepesht","threadId":"18695","inReplyTo":null,"subject":"[PATCH] builtin-clone.c: allow multiple cmd_clone() calls","fromName":"Ali Gholami Rudi","fromEmail":"ali@rudi.ir","sentAt":"2009-04-02T14:22:08Z","receivedAt":"2009-04-02T14:22:08Z","isPatch":true,"sender":{"key":"ali@rudi.ir","avatar":null},"body":"With this patch, cmd_clone() safely frees its xstrdup()-allocated\nmemory.  Also cmd_clone() registers remove_junk() (for getting called in\na signal handler or atexit()) at most once.\n\njunk_work_tree and junk_git_dir (used in remove_junk()) were changed to\nuse static arrays rather than sharing the memory allocated in\ncmd_clone().  The junk_* global variables are overwritten in each\ncmd_clone() call.  But if concurrent cmd_clone() calls are disallowed\nthat won't be an issue since we only care about the currently executing\ncmd_clone() in remove_junk().\n\nSigned-off-by: Ali Gholami Rudi <ali@rudi.ir>\n---\n builtin-clone.c |   30 +++++++++++++++++++-----------\n 1 files changed, 19 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin-clone.c b/builtin-clone.c\nindex 880373f..6ef31cd 100644\n--- a/builtin-clone.c\n+++ b/builtin-clone.c\n@@ -268,8 +268,9 @@ static const struct ref *clone_local(const char *src_repo,\n \treturn ret;\n }\n \n-static const char *junk_work_tree;\n-static const char *junk_git_dir;\n+static int junk_registered;\n+static char junk_work_tree[PATH_MAX];\n+static char junk_git_dir[PATH_MAX];\n static pid_t junk_pid;\n \n static void remove_junk(void)\n@@ -277,12 +278,12 @@ static void remove_junk(void)\n \tstruct strbuf sb = STRBUF_INIT;\n \tif (getpid() != junk_pid)\n \t\treturn;\n-\tif (junk_git_dir) {\n+\tif (*junk_git_dir) {\n \t\tstrbuf_addstr(&sb, junk_git_dir);\n \t\tremove_dir_recursively(&sb, 0);\n \t\tstrbuf_reset(&sb);\n \t}\n-\tif (junk_work_tree) {\n+\tif (*junk_work_tree) {\n \t\tstrbuf_addstr(&sb, junk_work_tree);\n \t\tremove_dir_recursively(&sb, 0);\n \t\tstrbuf_reset(&sb);\n@@ -320,8 +321,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n {\n \tint is_bundle = 0;\n \tstruct stat buf;\n-\tconst char *repo_name, *repo, *work_tree, *git_dir;\n-\tchar *path, *dir;\n+\tconst char *repo_name, *work_tree;\n+\tchar *path, *dir, *repo, *git_dir;\n \tint dest_exists;\n \tconst struct ref *refs, *head_points_at, *remote_head, *mapped_refs;\n \tstruct strbuf key = STRBUF_INIT, value = STRBUF_INIT;\n@@ -362,7 +363,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \telse if (!strchr(repo_name, ':'))\n \t\trepo = xstrdup(make_absolute_path(repo_name));\n \telse\n-\t\trepo = repo_name;\n+\t\trepo = xstrdup(repo_name);\n \n \tif (argc == 2)\n \t\tdir = xstrdup(argv[1]);\n@@ -393,7 +394,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (!option_bare) {\n-\t\tjunk_work_tree = work_tree;\n+\t\tstrcpy(junk_work_tree, work_tree);\n \t\tif (safe_create_leading_directories_const(work_tree) < 0)\n \t\t\tdie(\"could not create leading directories of '%s': %s\",\n \t\t\t\t\twork_tree, strerror(errno));\n@@ -402,9 +403,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \t\t\t\t\twork_tree, strerror(errno));\n \t\tset_git_work_tree(work_tree);\n \t}\n-\tjunk_git_dir = git_dir;\n-\tatexit(remove_junk);\n-\tsigchain_push_common(remove_junk_on_signal);\n+\tstrcpy(junk_git_dir, git_dir);\n+\tif (!junk_registered) {\n+\t\tjunk_registered = 1;\n+\t\tatexit(remove_junk);\n+\t\tsigchain_push_common(remove_junk_on_signal);\n+\t}\n \n \tsetenv(CONFIG_ENVIRONMENT, mkpath(\"%s/config\", git_dir), 1);\n \n@@ -590,6 +594,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tstrbuf_release(&branch_top);\n \tstrbuf_release(&key);\n \tstrbuf_release(&value);\n+\tfree(path);\n+\tfree(repo);\n+\tfree(dir);\n+\tfree(git_dir);\n \tjunk_pid = 0;\n \treturn err;\n }\n"}]}