From: Junio C Hamano Date: Tue, 30 Sep 2014 05:17:20 +0000 (-0700) Subject: Merge branch 'pr/use-default-sigpipe-setting' X-Git-Tag: v2.2.0-rc0~70 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/131f0315c46c30d5a9e6743354808230cf4908c0?ds=inline;hp=-c Merge branch 'pr/use-default-sigpipe-setting' We used to get confused when a process called us with SIGPIPE ignored; we do want to die with SIGPIPE when the output is not read by default, and do ignore the signal when appropriate. * pr/use-default-sigpipe-setting: mingw.h: add dummy functions for sigset_t operations unblock and unignore SIGPIPE --- 131f0315c46c30d5a9e6743354808230cf4908c0 diff --combined git.c index 4076b014ab,bf4d41f0e6..4cebf32126 --- a/git.c +++ b/git.c @@@ -14,13 -14,13 +14,13 @@@ const char git_usage_string[] " []"; 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 ' or 'git help '\n" "to read about a specific subcommand or concept."); static struct startup_info git_startup_info; static int use_pager = -1; -static char orig_cwd[PATH_MAX]; +static char *orig_cwd; static const char *env_names[] = { GIT_DIR_ENVIRONMENT, GIT_WORK_TREE_ENVIRONMENT, @@@ -36,7 -36,8 +36,7 @@@ static void save_env(void if (saved_environment) return; saved_environment = 1; - if (!getcwd(orig_cwd, sizeof(orig_cwd))) - die_errno("cannot getcwd"); + orig_cwd = xgetcwd(); for (i = 0; i < ARRAY_SIZE(env_names); i++) { orig_env[i] = getenv(env_names[i]); if (orig_env[i]) @@@ -47,9 -48,8 +47,9 @@@ static void restore_env(void) { int i; - if (*orig_cwd && chdir(orig_cwd)) + if (orig_cwd && chdir(orig_cwd)) die_errno("could not move to %s", orig_cwd); + free(orig_cwd); for (i = 0; i < ARRAY_SIZE(env_names); i++) { if (orig_env[i]) setenv(env_names[i], orig_env[i], 1); @@@ -161,10 -161,9 +161,10 @@@ static int handle_options(const char ** if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--bare")) { - static char git_dir[PATH_MAX+1]; + char *cwd = xgetcwd(); is_bare_repository_cfg = 1; - setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0); + setenv(GIT_DIR_ENVIRONMENT, cwd, 0); + free(cwd); setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1); if (envchanged) *envchanged = 1; @@@ -282,7 -281,8 +282,7 @@@ static int handle_alias(int *argcp, con "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); @@@ -592,6 -592,26 +592,26 @@@ static int run_argv(int *argcp, const c 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) { @@@ -611,6 -631,8 +631,8 @@@ */ sanitize_stdfds(); + restore_sigpipe_to_default(); + git_setup_gettext(); trace_command_performance(argv);