ignoring a process' last words: SIGPIPE ...
apenwarr at gmail.com
Thu Mar 27 11:40:11 PDT 2008
On Thu, Mar 27, 2008 at 2:13 PM, Havoc Pennington <hp at pobox.com> wrote:
> Both ends need to deal with the other end crashing or disconnecting. I
> would think adding a "clean" way to disconnect just creates another
> special case. It's a bug if a "dirty" or "abrupt" disconnect doesn't
> work, so the single, only codepath to test may as well be "just close
> the socket"
This seems to be the going theory nowadays, with http as well. I
guess even Jon Postel isn't perfect :)
> > In this case, dbus-send is disconnecting without telling the server,
> > and the server doesn't deal well with the surprise.
> Which is a bug, even if there is a clean way to disconnect.
Right. I meant to imply that both ends had fixable bugs. It always
takes two to miscommunicate.
> > One perfectly good solution, as proposed already, is to use the
> > --print-reply option to dbus-send, which forces it to stay connected
> > until it gets the answer back. In fact, this isn't such a bad idea
> > either way.
> What I meant on this btw was not to use --print-reply, but make
> dbus-send block for reply even if it will not be printing the reply.
Be careful that this won't work when sending signals, though.
Forcing a synchronous wait for reply would also needlessly slow down
clients that have no way to deal with it anyway if the receiving end
The nice thing about --print-reply is it already exists, so the daemon
with the problem can be easily updated that way without waiting for a
new dbus release.
> > In the case of dbus-daemon, I'd think it should be safe to just ignore
> > EPIPE and pretend the data has been written. Remember, the socket
> > isn't really "closed" until you close it, and the fd will remain valid
> > and won't be reused, so there's no reason to throw away any
> > authentication data structures, etc. The socket will close just fine
> > next time through the normal execution path where select() returns
> > true for readable, and then read() returns 0 bytes (EOF).
> This may be part of the solution. I would be pretty worried about
> introducing bugs, though, if this were not done very carefully. It
> would definitely need test cases to be added and all uses of
> connection_get_connected(), transport_get_connected(), etc. audited to
> see if they "really meant" connected for read or for write.
I'm always an advocate of being careful, but in this case I wouldn't
expect to find a problem. Fundamentally, even if write() succeeds,
you don't know if the remote end got it or not. They might have
disconnected *after* you did the write() but before they read the
response. So if anything in dbus assumes success just because write()
was successful, it's a bug anyhow and always has been.
That's the same rationale for when, above, you wrote that you can't
assume a method call was successful until you get the reply.
So in general, checking for errors on write() is just a fast-path to
reporting (and possibly dealing with) an error. It never tells you
anything you shouldn't already have had a way to know, and not getting
the error is not a guarantee of success. Errors on read() are another
> Perhaps it is less work than figuring out how
> to force immediate read-and-dispatch of remaining incoming messages on
Immediate read-and-dispatch is actually fundamentally wrong, because
an insane client could shutdown() its read path, causing all replies
from the daemon to get SIGPIPE, but happily continue sending messages
in its own output queue for the next five minutes. dbus-daemon, in
that case, ought to keep the connection open and do the best it can.
No sensible client will expect a guarantee from dbus-daemon that their
method replies were delivered successfully, since it's impossible to
guarantee that without having second order "method-reply-replies."
(It can be polite of dbus-daemon to let you know when it's *sure* that
it failed, but that has to be only an optimization, not a critical
More information about the dbus