Subject: git subcommand sigint gotcha

From: Joey Hess <[email-masked]>
Date: Tue, 19 Oct 2010 00:53:00 -0400

I was trying to write a git subcommand, and I noticed that if I ctrl-c'd
it, git would return, but leave the subcommand running in the
background.

You can see the problem with this test case. 

#!/usr/bin/perl
print "first sleep...\n";
$ret=system("sleep", "1m");
print "second sleep...\n";
system("sleep", "1s");
print "done with second sleep\n";

If you put it in path named git-sleep, then run "git sleep" and press ctrl-c,
it keeps running:

joey@gnu:~>git sleep
first sleep...
^Csecond sleep...
joey@gnu:~>done with second sleep

So what's going on? Well, perl's system() blocks sigint while the child
process is running. So if you run this as git-sleep, and press ctrl-c,
it will continue on to the second sleep. If the code above checked the
return status of system() it could detect that it was killed by SIGINT
and itself exit.

What I don't understand is, why does git not wait() on the subcommand it
ran? Any subcommand that forgets to check exit codes is liable to exhibit
this weird behavior sometimes. 

Ie, imagine the subcommand was running something like 
"git config --get core.bare" instead of sleep. 
It'd be easy to forget to check the exit status of that for a SIGINT; if
the user ctrl-c'd at just the right instant, weird things would happen.

-- 
see shy jo