From 7a4fd0fb71e698f3c8a04a245df9bf0187c45945 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 18 Mar 2009 19:26:33 -0400 Subject: [PATCH] Bug 896 - Ignore EPIPE on writes http://lists.freedesktop.org/archives/dbus/2008-March/009526.html We can get an EPIPE if the remote end has closed the connection on a write. However, it's possible we still have messages to read (and the socket can still be valid for reading). This is referred to as a "half open" connection. It turns out that things are correct if we simply ignore the EPIPE. We actually want to treat the connection as closed only when reading is complete (i.e. we get a hangup/EOF). --- dbus/dbus-sysdeps.c | 10 ++++++++++ dbus/dbus-sysdeps.h | 1 + dbus/dbus-transport-socket.c | 7 +++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 00a1a3d..d317f31 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -1078,6 +1078,16 @@ _dbus_get_is_errno_eintr (void) } /** + * See if errno is EPIPE + * @returns #TRUE if errno == EPIPE + */ +dbus_bool_t +_dbus_get_is_errno_epipe (void) +{ + return errno == EPIPE; +} + +/** * Get error message from errno * @returns _dbus_strerror(errno) */ diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index b766f3f..8e6cdc4 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -362,6 +362,7 @@ dbus_bool_t _dbus_get_is_errno_nonzero (void); dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock (void); dbus_bool_t _dbus_get_is_errno_enomem (void); dbus_bool_t _dbus_get_is_errno_eintr (void); +dbus_bool_t _dbus_get_is_errno_epipe (void); const char* _dbus_strerror_from_errno (void); void _dbus_disable_sigpipe (void); diff --git a/dbus/dbus-transport-socket.c b/dbus/dbus-transport-socket.c index 10b671c..76a53a2 100644 --- a/dbus/dbus-transport-socket.c +++ b/dbus/dbus-transport-socket.c @@ -615,8 +615,11 @@ do_writing (DBusTransport *transport) if (bytes_written < 0) { /* EINTR already handled for us */ - - if (_dbus_get_is_errno_eagain_or_ewouldblock ()) + /* For some discussion of why we also ignore EPIPE here, see + * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html + */ + + if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ()) goto out; else { -- 1.6.0.6