All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org, "Shawn O. Pearce" <spearce@spearce.org>
Subject: Re: [PATCHv2 02/10] pkt-line: drop safe_write function
Date: Mon, 18 Feb 2013 01:56:45 -0800	[thread overview]
Message-ID: <20130218095644.GA7049@elie.Belkin> (raw)
In-Reply-To: <20130218091519.GB5096@sigill.intra.peff.net>

Jeff King wrote:

> This is just write_or_die by another name.
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> Actually, they are not quite the same. write_or_die will exit(0) when it
> sees EPIPE.

That information definitely belongs in the commit message.

>             Which makes me a little nervous.

Me, too.  Let's see:

[...]
> --- a/builtin/receive-pack.c
> +++ b/builtin/receive-pack.c
> @@ -908,7 +908,7 @@ static void report(struct command *commands, const char *unpack_status)
>  	if (use_sideband)
>  		send_sideband(1, 1, buf.buf, buf.len, use_sideband);
>  	else
> -		safe_write(1, buf.buf, buf.len);
> +		write_or_die(1, buf.buf, buf.len);

If the connection to send-pack is lost and stdout becomes a broken
pipe and I am updating enough refs to overflow the pipe buffer,
receive-pack will die with SIGPIPE.  So unless the sadistic caller has
set the inherited SIGPIPE action to SIG_IGN (for example by wrapping
git with an uncautious Python wrapper that uses subprocess.Popen), the
change to EPIPE handling is not a behavior change.

Since the pipe is closed, presumably the calling send-pack has hung up
and won't notice the exit status, so this should be safe.

Arguably it would be more friendly to stay alive to run the
post-receive and post-update hooks, though, given that a ref update
has occurred.  Maybe transport commands like this one should always
set the disposition of SIGPIPE to SIG_IGN.

[...]
> --- a/builtin/send-pack.c
> +++ b/builtin/send-pack.c
> @@ -79,7 +79,7 @@ static void print_helper_status(struct ref *ref)
>  		}
>  		strbuf_addch(&buf, '\n');
>  
> -		safe_write(1, buf.buf, buf.len);
> +		write_or_die(1, buf.buf, buf.len);

A signal will kill send-pack before write_or_die has a chance to
intervene so this change is a no-op unless the caller is sadistic
(as in the [1] case).  In the signal(SIGPIPE, SIG_IGN) case, it might
be a regression, since "git push" should not declare success when its
connection to receive-pack closes early.

[1] http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/2009-07-02-python-sigpipe.html

[...]
> --- a/fetch-pack.c
> +++ b/fetch-pack.c
> @@ -245,7 +245,7 @@ static void send_request(struct fetch_pack_args *args,
>  		send_sideband(fd, -1, buf->buf, buf->len, LARGE_PACKET_MAX);
>  		packet_flush(fd);
>  	} else
> -		safe_write(fd, buf->buf, buf->len);
> +		write_or_die(fd, buf->buf, buf->len);

Also a no-op except when the parent process is insane enough to let us
inherit signal(SIGPIPE, SIG_IGN).

In that case, if triggerable this looks like a bad change: if
upload-pack has gone missing, the fetch should not be considered a
success.

[...]
> --- a/http-backend.c
> +++ b/http-backend.c
> @@ -70,7 +70,7 @@ static void format_write(int fd, const char *fmt, ...)
>  	if (n >= sizeof(buffer))
>  		die("protocol error: impossibly long line");
>  
> -	safe_write(fd, buffer, n);
> +	write_or_die(fd, buffer, n);

Etc.  I'm stopping here.

I'm thinking before a patch like this we should make the following
change:

 1. at startup, set the signal action of SIGPIPE to SIG_DFL, to make
    the behavior a little more predictable.

Perhaps the following as well:

 2. in write_or_die(), when encountering EPIPE, set the signal action
    of SIGPIPE to SIG_DFL and raise(SIGPIPE), ensuring the exit status
    reflects the broken pipe.  If the parent process is unnecessarily
    noisy about that, that's a bug in the parent process (hopefully
    uncommon).

Or alternatively:

 2b. never set SIGPIPE to SIG_IGN except in short blocks of code that
     do not call write_or_die()

What do you think?
Jonathan

  reply	other threads:[~2013-02-18  9:57 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-16  6:44 [PATCH 0/3] make smart-http more robust against bogus server input Jeff King
2013-02-16  6:46 ` [PATCH 1/3] pkt-line: teach packet_get_line a no-op mode Jeff King
2013-02-17 10:41   ` Jonathan Nieder
2013-02-16  6:47 ` [PATCH 2/3] remote-curl: verify smart-http metadata lines Jeff King
2013-02-17 10:49   ` Jonathan Nieder
2013-02-17 19:14     ` Jeff King
2013-02-18  0:54       ` Jonathan Nieder
2013-02-18  8:59         ` Jeff King
2013-02-16  6:49 ` [PATCH 3/3] remote-curl: sanity check ref advertisement from server Jeff King
2013-02-17 11:05   ` Jonathan Nieder
2013-02-17 19:28     ` Jeff King
2013-02-18  1:41       ` Jonathan Nieder
2013-02-18  9:12         ` [PATCHv2 0/10] pkt-line and remote-curl cleanups server Jeff King
2013-02-18  9:14           ` [PATCHv2 01/10] pkt-line: move a misplaced comment Jeff King
2013-02-18  9:15           ` [PATCHv2 02/10] pkt-line: drop safe_write function Jeff King
2013-02-18  9:56             ` Jonathan Nieder [this message]
2013-02-18 10:24               ` Jeff King
2013-02-18  9:16           ` [PATCHv2 03/10] pkt-line: clean up "gentle" reading function Jeff King
2013-02-18 10:12             ` Jonathan Nieder
2013-02-18 10:25               ` Jeff King
2013-02-18  9:22           ` [PATCHv2 04/10] pkt-line: change error message for oversized packet Jeff King
2013-02-18  9:40             ` Junio C Hamano
2013-02-18  9:49               ` Jeff King
2013-02-18 21:25                 ` Junio C Hamano
2013-02-18 21:33                   ` Jeff King
2013-02-20  8:47                     ` Jeff King
2013-02-20  8:54                       ` Junio C Hamano
2013-02-18 10:15             ` Jonathan Nieder
2013-02-18 10:26               ` Jeff King
2013-02-18  9:22           ` [PATCHv2 05/10] pkt-line: rename s/packet_read_line/packet_read/ Jeff King
2013-02-18 10:19             ` Jonathan Nieder
2013-02-18 10:29               ` Jeff King
2013-02-18 11:05                 ` Jonathan Nieder
2013-02-18  9:26           ` [PATCHv2 06/10] pkt-line: share buffer/descriptor reading implementation Jeff King
2013-02-18 10:43             ` Jonathan Nieder
2013-02-18 10:48               ` Jeff King
2013-02-18 10:54                 ` Jonathan Nieder
2013-02-18  9:27           ` [PATCHv2 07/10] teach get_remote_heads to read from a memory buffer Jeff King
2013-02-18  9:29           ` [PATCHv2 08/10] remote-curl: pass buffer straight to get_remote_heads Jeff King
2013-02-18 10:47             ` Jonathan Nieder
2013-02-18  9:29           ` [PATCHv2 0/10] pkt-line and remote-curl cleanups server Junio C Hamano
2013-02-18  9:33             ` Jeff King
2013-02-18  9:49               ` Junio C Hamano
2013-02-18  9:55                 ` Jeff King
2013-02-20  7:14                 ` Shawn Pearce
2013-02-18  9:29           ` [PATCHv2 09/10] remote-curl: move ref-parsing code up in file Jeff King
2013-02-18  9:30           ` [PATCHv2 10/10] remote-curl: always parse incoming refs Jeff King
2013-02-18 10:50             ` Jonathan Nieder
2013-02-20  7:41               ` Shawn Pearce
2013-02-20  7:05           ` [PATCHv2 0/10] pkt-line and remote-curl cleanups server Shawn Pearce

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130218095644.GA7049@elie.Belkin \
    --to=jrnieder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=peff@peff.net \
    --cc=spearce@spearce.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.