Skip to content

Commit ee0e387

Browse files
peffgitster
authored andcommitted
clone: initialize atexit cleanup handler earlier
If clone fails, we generally try to clean up any directories we've created. We do this by installing an atexit handler, so that we don't have to manually trigger cleanup. However, since we install this after touching the filesystem, any errors between our initial mkdir() and our atexit() call will result in us leaving a crufty directory around. We can fix this by moving our atexit() call earlier. It's OK to do it before the junk_work_tree variable is set, because remove_junk makes sure the variable is initialized. This means we "activate" the handler by assigning to the junk_work_tree variable, which we now bump down to just after we call mkdir(). We probably do not want to do it before, because a plausible reason for mkdir() to fail is EEXIST (i.e., we are racing with another "git init"), and we would not want to remove their work. OTOH, this is probably not that big a deal; we will allow cloning into an empty directory (and skip the mkdir), which is already racy (i.e., one clone may see the other's empty dir and start writing into it). Still, it does not hurt to err on the side of caution here. Note that writing into junk_work_tree and junk_git_dir after installing the handler is also technically racy, as we call our handler on an async signal. Depending on the platform, we could see a sheared write to the variables. Traditionally we have not worried about this, and indeed we already do this later in the function. If we want to address that, it can come as a separate topic. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 282616c commit ee0e387

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

builtin/clone.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -841,20 +841,21 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
841841
git_dir = mkpathdup("%s/.git", dir);
842842
}
843843

844+
atexit(remove_junk);
845+
sigchain_push_common(remove_junk_on_signal);
846+
844847
if (!option_bare) {
845-
junk_work_tree = work_tree;
846848
if (safe_create_leading_directories_const(work_tree) < 0)
847849
die_errno(_("could not create leading directories of '%s'"),
848850
work_tree);
849851
if (!dest_exists && mkdir(work_tree, 0777))
850852
die_errno(_("could not create work tree dir '%s'."),
851853
work_tree);
854+
junk_work_tree = work_tree;
852855
set_git_work_tree(work_tree);
853856
}
854-
junk_git_dir = git_dir;
855-
atexit(remove_junk);
856-
sigchain_push_common(remove_junk_on_signal);
857857

858+
junk_git_dir = git_dir;
858859
if (safe_create_leading_directories_const(git_dir) < 0)
859860
die(_("could not create leading directories of '%s'"), git_dir);
860861

0 commit comments

Comments
 (0)