git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [RFC/PATCH] avoid SIGPIPE warnings for aliases
@ 2013-01-04 12:47 Jeff King
  2013-01-04 16:55 ` Johannes Sixt
                   ` (3 more replies)
  0 siblings, 4 replies; 23+ messages in thread
From: Jeff King @ 2013-01-04 12:47 UTC (permalink / raw)
  To: git; +Cc: Bart Trojanowski

When git executes an alias that specifies an external
command, it will complain if the alias dies due to a signal.
This is usually a good thing, as signal deaths are
unexpected. However, SIGPIPE is not unexpected for many
commands which produce a lot of output; it is intended that
the user closing the pager would kill them them via SIGPIPE.

As a result, the user might see annoying messages in a
scenario like this:

  $ cat ~/.gitconfig
  [alias]
  lgbase = log --some-options
  lg = !git lgbase --more-options
  lg2 = !git lgbase --other-options

  $ git lg -p
  [user hits 'q' to exit pager]
  error: git lgbase --more-options died of signal 13
  fatal: While expanding alias 'lg': 'git lgbase --more-options': Success

Many users won't see this, because we execute the external
command with the shell, and a POSIX shell will silently
rewrite the signal-death exit code into 128+signal, and we
will treat it like a normal exit code. However, this does
not always happen:

  1. If the sub-command does not have shell metacharacters,
     we will skip the shell and exec it directly, getting
     the signal code.

  2. Some shells do not do this rewriting; for example,
     setting SHELL_PATH set to zsh will reveal this problem.

This patch squelches the message, and let's git exit
silently (with the same exit code that a shell would use in
case of a signal).

The first line of the message comes from run-command's
wait_or_whine. To silence that message, we remain quiet
anytime we see SIGPIPE.

The second line comes from handle_alias itself. It calls
die_errno whenever run_command returns a negative value.
However, only -1 indicates a syscall error where errno has
something useful (note that it says the useless "success"
above). Instead, we treat negative returns from run_command
(except for -1) as a normal code to be passed to exit.

Signed-off-by: Jeff King <peff@peff.net>
---
I have two reservations with this patch:

  1. We are ignoring SIGPIPE all the time. For an alias that is calling
     "log", that is fine. But if pack-objects dies on the server side,
     seeing that it died from SIGPIPE is useful data, and we are
     squelching that. Maybe callers of run-command should have to pass
     an "ignore SIGPIPE" flag?

  2. The die_errno in handle_alias is definitely wrong. Even if we want
     to print a message for signal death, showing errno is bogus unless
     the return value was -1. But is it the right thing to just pass the
     negative value straight to exit()? It works, but it is depending on
     the fact that (unsigned char)(ret & 0xff) behaves in a certain way
     (i.e., that we are on a twos-complement platform, and -13 becomes
     141). That is not strictly portable, but it is probably fine in
     practice. I'd worry more about exit() doing something weird on
     Windows.

 git.c         | 2 +-
 run-command.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/git.c b/git.c
index d33f9b3..07edb8a 100644
--- a/git.c
+++ b/git.c
@@ -175,7 +175,7 @@ static int handle_alias(int *argcp, const char ***argv)
 			alias_argv[argc] = NULL;
 
 			ret = run_command_v_opt(alias_argv, RUN_USING_SHELL);
-			if (ret >= 0)   /* normal exit */
+			if (ret != -1)  /* normal exit */
 				exit(ret);
 
 			die_errno("While expanding alias '%s': '%s'",
diff --git a/run-command.c b/run-command.c
index 757f263..01a4c9b 100644
--- a/run-command.c
+++ b/run-command.c
@@ -242,7 +242,7 @@ static int wait_or_whine(pid_t pid, const char *argv0)
 		error("waitpid is confused (%s)", argv0);
 	} else if (WIFSIGNALED(status)) {
 		code = WTERMSIG(status);
-		if (code != SIGINT && code != SIGQUIT)
+		if (code != SIGINT && code != SIGQUIT && code != SIGPIPE)
 			error("%s died of signal %d", argv0, code);
 		/*
 		 * This return value is chosen so that code & 0xff
-- 
1.8.1.rc1.16.g6d46841

^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-07-21  6:45 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-04 12:47 [RFC/PATCH] avoid SIGPIPE warnings for aliases Jeff King
2013-01-04 16:55 ` Johannes Sixt
2013-01-04 21:25   ` Jeff King
2013-01-04 22:20 ` Junio C Hamano
2013-01-05 14:03   ` Jeff King
2013-01-05 14:49     ` [PATCH] run-command: encode signal death as a positive integer Jeff King
2013-01-05 19:50       ` Johannes Sixt
2013-01-05 22:19       ` Jonathan Nieder
2013-01-05 23:12         ` Jeff King
2013-01-05 23:58           ` Jonathan Nieder
2013-01-06  7:05       ` Junio C Hamano
2013-01-09 20:48 ` [RFC/PATCH] avoid SIGPIPE warnings for aliases Junio C Hamano
2013-01-09 20:51   ` Jeff King
2013-01-09 21:49     ` Junio C Hamano
2013-01-10  0:18       ` Jonathan Nieder
2013-01-10  0:39         ` Junio C Hamano
2013-01-10 11:26         ` Jeff King
2013-01-10 20:22           ` Junio C Hamano
2013-01-10 21:39             ` Jeff King
2013-01-10 21:52             ` Johannes Sixt
2013-01-10 22:51               ` Junio C Hamano
2013-01-10 10:49       ` Jeff King
2014-07-21  6:45 ` mimimimi

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).