From: Junio C Hamano Date: Fri, 5 Dec 2014 19:42:26 +0000 (-0800) Subject: Merge branch 'sv/get-builtin' X-Git-Tag: v2.3.0-rc0~99 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/7f2186cadf4844616065c6175f179f1184c8fa75?hp=-c Merge branch 'sv/get-builtin' * sv/get-builtin: builtin: move builtin retrieval to get_builtin() --- 7f2186cadf4844616065c6175f179f1184c8fa75 diff --combined git.c index 18fbf79430,84310e30ee..82d7a1cfee --- 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); @@@ -417,7 -417,6 +417,7 @@@ static struct cmd_struct commands[] = { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY }, { "init", cmd_init_db, NO_SETUP }, { "init-db", cmd_init_db, NO_SETUP }, + { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP }, { "log", cmd_log, RUN_SETUP }, { "ls-files", cmd_ls_files, RUN_SETUP }, { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY }, @@@ -487,15 -486,20 +487,20 @@@ { "write-tree", cmd_write_tree, RUN_SETUP }, }; - int is_builtin(const char *s) + static struct cmd_struct *get_builtin(const char *s) { int i; for (i = 0; i < ARRAY_SIZE(commands); i++) { - struct cmd_struct *p = commands+i; + struct cmd_struct *p = commands + i; if (!strcmp(s, p->cmd)) - return 1; + return p; } - return 0; + return NULL; + } + + int is_builtin(const char *s) + { + return !!get_builtin(s); } static void handle_builtin(int argc, const char **argv) @@@ -503,6 -507,7 +508,7 @@@ const char *cmd = argv[0]; int i; static const char ext[] = STRIP_EXTENSION; + struct cmd_struct *builtin; if (sizeof(ext) > 1) { i = strlen(argv[0]) - strlen(ext); @@@ -519,15 -524,12 +525,12 @@@ argv[0] = cmd = "help"; } - for (i = 0; i < ARRAY_SIZE(commands); i++) { - struct cmd_struct *p = commands+i; - if (strcmp(p->cmd, cmd)) - continue; - if (saved_environment && (p->option & NO_SETUP)) { + builtin = get_builtin(cmd); + if (builtin) { + if (saved_environment && (builtin->option & NO_SETUP)) restore_env(); - break; - } - exit(run_builtin(p, argc, argv)); + else + exit(run_builtin(builtin, argc, argv)); } } @@@ -593,26 -595,6 +596,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) { @@@ -632,8 -614,6 +635,8 @@@ */ sanitize_stdfds(); + restore_sigpipe_to_default(); + git_setup_gettext(); trace_command_performance(argv);