git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: t5570-git-daemon fails with SIGPIPE on OSX

From
Jeff King <peff@peff.net>
Date
Mar 1, 2019, 19:00 UTC
Message-ID
<20190301190042.GF30847@sigill.intra.peff.net>
In-Reply-To
<nycvar.QRO.7.76.6.1903011557430.41@tvgsbejvaqbjf.bet>
On Fri, Mar 01, 2019 at 04:02:22PM +0100, Johannes Schindelin wrote:
Show 15 quoted lines
> > I think that patch does the write_or_die conversion to handle EPIPE, but
> > it would still need to turn off SIGPIPE for the whole process.
> > 
> > So you'd also need to stick a:
> > 
> >   sigchain_push(SIGPIPE, SIG_IGN);
> > 
> > somewhere near the start of cmd_fetch(). (There may be a less
> > coarse-grained place to put it, but at this point I think we're just
> > trying to find out whether this approach even solves the problem).
> 
> This fixes it, it seems. I let the job run with `--stress=50` and even
> after half an hour, it did not fail:
> 
> attempts ://git.visualstudio.com/git/_build/results?buildId=354
Cool, I'm glad it works!
> (I had to cancel it, I thought that `--stress=50` would stop trying after
> 50 runs, but I was obviously incorrect in that assumption...)
No, that will do 50 simultaneous jobs. You want --stress-limit=50.

It might make more sense to have --stress-jobs, and make --stress=X set the limit, as I think it's much more useful to set the limit than it is to set the number of jobs. At least that's my experience.

> So. Good, we have a diff that works. But you mentioned that you'd like to
> put it somewhere else? I am a bit unfamiliar with the code paths of
> `cmd_fetch()`, so I would be hard pressed to find a better spot. Any hint?

Well, I'm of two minds there. If we want to make the minimum change, then we'd just want to disable SIGPIPE while we're actually conversing with the other side. So I guess that would be somewhere in do_fetch(), before we start talking to the other side, and restoring it after we've finished our half of the conversation (i.e., after we've done all the want/have bits and we're receiving the pack). But that's actually pretty awkward to do, because most of those details are handled under the hood by the transport code.

So probably something like this is the least-terrible place to put it:
diff --git a/builtin/fetch.c b/builtin/fetch.c
index b620fd54b4..4ba63d5ac6 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1556,7 +1556,9 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
 
 	sigchain_push_common(unlock_pack_on_signal);
 	atexit(unlock_pack);
+	sigchain_push(SIGPIPE, SIG_IGN);
 	exit_code = do_fetch(gtransport, &rs);
+	sigchain_pop(SIGPIPE);
 	refspec_clear(&rs);
 	transport_disconnect(gtransport);
 	gtransport = NULL;

That said, I actually think it's kind of pointless for git-fetch to use
SIGPIPE at all. The purpose of SIGPIPE is that you can write a naive
program that spews output, and you'll get informed (forcefully) by the
OS if the process consuming your output stops listening. That makes
sense for programs like "git log", whose primary purpose is generating
output.

But for git-fetch, our primary purpose is receiving data and writing it
to disk. We should be checking all of our write()s already, and SIGPIPE
is just confusing. The only "big" output we generate is the status table
at the end. And even if that is going to a pipe that closes, I don't
think we'd want to fail the whole command (we'd want to finalize any
writes for what we just fetched, clean up after ourselves, etc).

So I'd actually be fine with just declaring that certain commands (like
fetch) just ignore SIGPIPE entirely.

-Peff
Previous: Johannes SchindelinNext: Johannes Schindelin
Message 11 of 21 in “t5570-git-daemon fails with SIGPIPE on OSX”
  1. SZEDER GáborAug 6, 2018
  2. SZEDER GáborAug 6, 2018
  3. Johannes SchindelinFeb 8, 2019
  4. SZEDER GáborFeb 8, 2019
  5. Jeff KingAug 14, 2018
  6. Jeff KingAug 14, 2018
  7. Johannes SchindelinFeb 8, 2019
  8. Johannes SchindelinFeb 8, 2019
  9. Jeff KingFeb 8, 2019
  10. Johannes SchindelinMar 1, 2019
  11. Jeff KingMar 1, 2019
  12. Johannes SchindelinMar 2, 2019
  13. Jeff KingMar 3, 2019
  14. 1/2 fetch: avoid calling write_or_die()Jeff King, Mar 3, 2019
  15. Duy NguyenMar 4, 2019
  16. Jeff KingMar 5, 2019
  17. 2/2 fetch: ignore SIGPIPE during network operationJeff King, Mar 3, 2019
  18. Junio C HamanoMar 4, 2019
  19. Jeff KingMar 5, 2019
  20. Junio C HamanoMar 3, 2019
  21. Johannes SchindelinMar 3, 2019

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.