Merge branch 'lt/run'
* lt/run: Check for IO errors after running a command Clean up internal command handling
This commit is contained in:
commit
39741ab1c5
71
git.c
71
git.c
@ -216,14 +216,53 @@ const char git_version_string[] = GIT_VERSION;
|
|||||||
*/
|
*/
|
||||||
#define NOT_BARE (1<<2)
|
#define NOT_BARE (1<<2)
|
||||||
|
|
||||||
static void handle_internal_command(int argc, const char **argv, char **envp)
|
struct cmd_struct {
|
||||||
|
const char *cmd;
|
||||||
|
int (*fn)(int, const char **, const char *);
|
||||||
|
int option;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int run_command(struct cmd_struct *p, int argc, const char **argv)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
struct stat st;
|
||||||
|
const char *prefix;
|
||||||
|
|
||||||
|
prefix = NULL;
|
||||||
|
if (p->option & RUN_SETUP)
|
||||||
|
prefix = setup_git_directory();
|
||||||
|
if (p->option & USE_PAGER)
|
||||||
|
setup_pager();
|
||||||
|
if (p->option & NOT_BARE) {
|
||||||
|
if (is_bare_repository() || is_inside_git_dir())
|
||||||
|
die("%s must be run in a work tree", p->cmd);
|
||||||
|
}
|
||||||
|
trace_argv_printf(argv, argc, "trace: built-in: git");
|
||||||
|
|
||||||
|
status = p->fn(argc, argv, prefix);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
/* Somebody closed stdout? */
|
||||||
|
if (fstat(fileno(stdout), &st))
|
||||||
|
return 0;
|
||||||
|
/* Ignore write errors for pipes and sockets.. */
|
||||||
|
if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Check for ENOSPC and EIO errors.. */
|
||||||
|
if (ferror(stdout))
|
||||||
|
die("write failure on standard output");
|
||||||
|
if (fflush(stdout) || fclose(stdout))
|
||||||
|
die("write failure on standard output: %s", strerror(errno));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_internal_command(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
const char *cmd = argv[0];
|
const char *cmd = argv[0];
|
||||||
static struct cmd_struct {
|
static struct cmd_struct commands[] = {
|
||||||
const char *cmd;
|
|
||||||
int (*fn)(int, const char **, const char *);
|
|
||||||
int option;
|
|
||||||
} commands[] = {
|
|
||||||
{ "add", cmd_add, RUN_SETUP | NOT_BARE },
|
{ "add", cmd_add, RUN_SETUP | NOT_BARE },
|
||||||
{ "annotate", cmd_annotate, RUN_SETUP | USE_PAGER },
|
{ "annotate", cmd_annotate, RUN_SETUP | USE_PAGER },
|
||||||
{ "apply", cmd_apply },
|
{ "apply", cmd_apply },
|
||||||
@ -307,25 +346,13 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
|
|||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(commands); i++) {
|
for (i = 0; i < ARRAY_SIZE(commands); i++) {
|
||||||
struct cmd_struct *p = commands+i;
|
struct cmd_struct *p = commands+i;
|
||||||
const char *prefix;
|
|
||||||
if (strcmp(p->cmd, cmd))
|
if (strcmp(p->cmd, cmd))
|
||||||
continue;
|
continue;
|
||||||
|
exit(run_command(p, argc, argv));
|
||||||
prefix = NULL;
|
|
||||||
if (p->option & RUN_SETUP)
|
|
||||||
prefix = setup_git_directory();
|
|
||||||
if (p->option & USE_PAGER)
|
|
||||||
setup_pager();
|
|
||||||
if ((p->option & NOT_BARE) &&
|
|
||||||
(is_bare_repository() || is_inside_git_dir()))
|
|
||||||
die("%s must be run in a work tree", cmd);
|
|
||||||
trace_argv_printf(argv, argc, "trace: built-in: git");
|
|
||||||
|
|
||||||
exit(p->fn(argc, argv, prefix));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char **argv, char **envp)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
const char *cmd = argv[0] ? argv[0] : "git-help";
|
const char *cmd = argv[0] ? argv[0] : "git-help";
|
||||||
char *slash = strrchr(cmd, '/');
|
char *slash = strrchr(cmd, '/');
|
||||||
@ -358,7 +385,7 @@ int main(int argc, const char **argv, char **envp)
|
|||||||
if (!prefixcmp(cmd, "git-")) {
|
if (!prefixcmp(cmd, "git-")) {
|
||||||
cmd += 4;
|
cmd += 4;
|
||||||
argv[0] = cmd;
|
argv[0] = cmd;
|
||||||
handle_internal_command(argc, argv, envp);
|
handle_internal_command(argc, argv);
|
||||||
die("cannot handle %s internally", cmd);
|
die("cannot handle %s internally", cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +417,7 @@ int main(int argc, const char **argv, char **envp)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* See if it's an internal command */
|
/* See if it's an internal command */
|
||||||
handle_internal_command(argc, argv, envp);
|
handle_internal_command(argc, argv);
|
||||||
|
|
||||||
/* .. then try the external ones */
|
/* .. then try the external ones */
|
||||||
execv_git_cmd(argv);
|
execv_git_cmd(argv);
|
||||||
|
Loading…
Reference in New Issue
Block a user