diff options
Diffstat (limited to 'git.c')
-rw-r--r-- | git.c | 27 |
1 files changed, 24 insertions, 3 deletions
@@ -14,7 +14,7 @@ const char git_usage_string[] = " <command> [<args>]"; const char git_more_info_string[] = - N_("'git help -a' and 'git help -g' lists available subcommands and some\n" + N_("'git help -a' and 'git help -g' list available subcommands and some\n" "concept guides. See 'git help <command>' or 'git help <concept>'\n" "to read about a specific subcommand or concept."); @@ -282,8 +282,7 @@ static int handle_alias(int *argcp, const char ***argv) "trace: alias expansion: %s =>", alias_command); - new_argv = xrealloc(new_argv, sizeof(char *) * - (count + *argcp)); + REALLOC_ARRAY(new_argv, count + *argcp); /* insert after command name */ memcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp); @@ -594,6 +593,26 @@ static int run_argv(int *argcp, const char ***argv) return done_alias; } +/* + * Many parts of Git have subprograms communicate via pipe, expect the + * upstream of a pipe to die with SIGPIPE when the downstream of a + * pipe does not need to read all that is written. Some third-party + * programs that ignore or block SIGPIPE for their own reason forget + * to restore SIGPIPE handling to the default before spawning Git and + * break this carefully orchestrated machinery. + * + * Restore the way SIGPIPE is handled to default, which is what we + * expect. + */ +static void restore_sigpipe_to_default(void) +{ + sigset_t unblock; + + sigemptyset(&unblock); + sigaddset(&unblock, SIGPIPE); + sigprocmask(SIG_UNBLOCK, &unblock, NULL); + signal(SIGPIPE, SIG_DFL); +} int main(int argc, char **av) { @@ -613,6 +632,8 @@ int main(int argc, char **av) */ sanitize_stdfds(); + restore_sigpipe_to_default(); + git_setup_gettext(); trace_command_performance(argv); |