summaryrefslogtreecommitdiffstats
path: root/mojo/edk/embedder/platform_channel_utils_posix.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/edk/embedder/platform_channel_utils_posix.cc')
-rw-r--r--mojo/edk/embedder/platform_channel_utils_posix.cc12
1 files changed, 12 insertions, 0 deletions
diff --git a/mojo/edk/embedder/platform_channel_utils_posix.cc b/mojo/edk/embedder/platform_channel_utils_posix.cc
index 4af45e82..c064139 100644
--- a/mojo/edk/embedder/platform_channel_utils_posix.cc
+++ b/mojo/edk/embedder/platform_channel_utils_posix.cc
@@ -12,6 +12,10 @@
#include "base/posix/eintr_wrapper.h"
#include "build/build_config.h"
+#if !defined(SO_PEEK_OFF)
+#define SO_PEEK_OFF 42
+#endif
+
namespace mojo {
namespace edk {
@@ -155,10 +159,18 @@ ssize_t PlatformChannelRecvmsg(PlatformHandle h,
msg.msg_control = cmsg_buf;
msg.msg_controllen = sizeof(cmsg_buf);
+ // We use SO_PEEK_OFF to hold a common identifier between sockets to detect if
+ // they're connected. recvmsg modifies it, so we cache it and set it again
+ // after the call.
+ int id = 0;
+ socklen_t peek_off_size = sizeof(id);
+ getsockopt(h.fd, SOL_SOCKET, SO_PEEK_OFF, &id, &peek_off_size);
ssize_t result = HANDLE_EINTR(recvmsg(h.fd, &msg, MSG_DONTWAIT));
if (result < 0)
return result;
+ setsockopt(h.fd, SOL_SOCKET, SO_PEEK_OFF, &id, sizeof(id));
+
// Success; no control messages.
if (msg.msg_controllen == 0)
return result;