COMMIT_MESSAGE

 1[GTK] Implement SharedMemory for WebKit2
 2https://bugs.webkit.org/show_bug.cgi?id=49791
 3
 4Reviewed by NOBODY (OOPS!).
 5
 6Share the SharedMemory, Attachment and Connection implementations with the Qt port.
 7Both implementation are, in fact, general Unix implementations using standard Unix
 8domain sockets and sendmsg / recvmsg. This should reduce the amount of duplicated code
 9greatly and lay the groundwork for GTK+/Qt implementations for other operating systems.
 10
 11* GNUmakefile.am: Replaced GTK+ versions of files with the Unix ones.
 12* Platform/CoreIPC/ArgumentDecoder.cpp: Extended Qt #ifdefs to include GTK.
 13(CoreIPC::ArgumentDecoder::~ArgumentDecoder):
 14* Platform/CoreIPC/ArgumentEncoder.cpp: Ditto.
 15(CoreIPC::ArgumentEncoder::~ArgumentEncoder):
 16* Platform/CoreIPC/Attachment.h: Ditto.
 17* Platform/CoreIPC/Connection.h: Combined the GTK+ and Qt sections.
 18* Platform/CoreIPC/unix/AttachmentUnix.cpp: Renamed from Source/WebKit2/Platform/CoreIPC/qt/AttachmentQt.cpp.
 19* Platform/CoreIPC/unix/ConnectionUnix.cpp: Renamed from Source/WebKit2/Platform/CoreIPC/qt/ConnectionQt.cpp.
 20* Platform/unix/SharedMemoryUnix.cpp: Renamed from Source/WebKit2/Platform/qt/SharedMemoryQt.cpp.
 21* UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp:
 22(WebKit::ProcessLauncher::launchProcess): Use SOCK_DGRAM instead of SOCK_STREAM to match Qt.
 23* WebKit2.pro: Updated source list to reflect file renaming.

Source/WebKit2/ChangeLog

 12011-03-11 Amruth Raj <amruthraj@motorola.com> and Martin Robinson <mrobinson@igalia.com>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 [GTK] Implement SharedMemory for WebKit2
 6 https://bugs.webkit.org/show_bug.cgi?id=49791
 7
 8 Share the SharedMemory, Attachment and Connection implementations with the Qt port.
 9 Both implementation are, in fact, general Unix implementations using standard Unix
 10 domain sockets and sendmsg / recvmsg. This should reduce the amount of duplicated code
 11 greatly and lay the groundwork for GTK+/Qt implementations for other operating systems.
 12
 13 * GNUmakefile.am: Replaced GTK+ versions of files with the Unix ones.
 14 * Platform/CoreIPC/ArgumentDecoder.cpp: Extended Qt #ifdefs to include GTK.
 15 (CoreIPC::ArgumentDecoder::~ArgumentDecoder):
 16 * Platform/CoreIPC/ArgumentEncoder.cpp: Ditto.
 17 (CoreIPC::ArgumentEncoder::~ArgumentEncoder):
 18 * Platform/CoreIPC/Attachment.h: Ditto.
 19 * Platform/CoreIPC/Connection.h: Combined the GTK+ and Qt sections.
 20 * Platform/CoreIPC/unix/AttachmentUnix.cpp: Renamed from Source/WebKit2/Platform/CoreIPC/qt/AttachmentQt.cpp.
 21 * Platform/CoreIPC/unix/ConnectionUnix.cpp: Renamed from Source/WebKit2/Platform/CoreIPC/qt/ConnectionQt.cpp.
 22 * Platform/unix/SharedMemoryUnix.cpp: Renamed from Source/WebKit2/Platform/qt/SharedMemoryQt.cpp.
 23 * UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp:
 24 (WebKit::ProcessLauncher::launchProcess): Use SOCK_DGRAM instead of SOCK_STREAM to match Qt.
 25 * WebKit2.pro: Updated source list to reflect file renaming.
 26
1272011-03-30 Anders Carlsson <andersca@apple.com>
228
329 Reviewed by Sam Weinig.

Source/WebKit2/GNUmakefile.am

@@libWebKit2_la_SOURCES = \
9393 Source/WebKit2/Platform/CoreIPC/CoreIPCMessageKinds.h \
9494 Source/WebKit2/Platform/CoreIPC/DataReference.cpp \
9595 Source/WebKit2/Platform/CoreIPC/DataReference.h \
96  Source/WebKit2/Platform/CoreIPC/gtk/ConnectionGtk.cpp \
9796 Source/WebKit2/Platform/CoreIPC/HandleMessage.h \
9897 Source/WebKit2/Platform/CoreIPC/MessageID.h \
9998 Source/WebKit2/Platform/CoreIPC/MessageSender.h \
 99 Source/WebKit2/Platform/CoreIPC/unix/ConnectionUnix.cpp \
 100 Source/WebKit2/Platform/CoreIPC/posix/AttachmentPOSIX.cpp \
100101 Source/WebKit2/Platform/gtk/ModuleGtk.cpp \
101102 Source/WebKit2/Platform/gtk/RunLoopGtk.cpp \
102  Source/WebKit2/Platform/gtk/SharedMemoryGtk.cpp \
103103 Source/WebKit2/Platform/gtk/WorkQueueGtk.cpp \
104104 Source/WebKit2/Platform/Logging.cpp \
105105 Source/WebKit2/Platform/Logging.h \

@@libWebKit2_la_SOURCES = \
109109 Source/WebKit2/Platform/RunLoop.cpp \
110110 Source/WebKit2/Platform/RunLoop.h \
111111 Source/WebKit2/Platform/SharedMemory.h \
 112 Source/WebKit2/Platform/posix/SharedMemoryPOSIX.cpp \
112113 Source/WebKit2/Platform/WorkItem.h \
113114 Source/WebKit2/Platform/WorkQueue.cpp \
114115 Source/WebKit2/Platform/WorkQueue.h \

Source/WebKit2/Platform/CoreIPC/ArgumentDecoder.cpp

@@ArgumentDecoder::~ArgumentDecoder()
4747{
4848 ASSERT(m_buffer);
4949 fastFree(m_buffer);
50 #if !PLATFORM(QT)
 50#if !PLATFORM(QT) && !PLATFORM(GTK)
5151 // FIXME: We need to dispose of the mach ports in cases of failure.
5252#else
5353 Deque<Attachment>::iterator end = m_attachments.end();

Source/WebKit2/Platform/CoreIPC/ArgumentEncoder.cpp

@@ArgumentEncoder::~ArgumentEncoder()
5050{
5151 if (m_buffer)
5252 fastFree(m_buffer);
53 #if !PLATFORM(QT)
 53#if !PLATFORM(QT) && !PLATFORM(GTK)
5454 // FIXME: We need to dispose of the attachments in cases of failure.
5555#else
5656 for (int i = 0; i < m_attachments.size(); ++i)

Source/WebKit2/Platform/CoreIPC/Attachment.h

@@public:
4040#if PLATFORM(MAC)
4141 MachPortType,
4242 MachOOLMemoryType
43 #elif PLATFORM(QT)
 43#elif PLATFORM(QT) || PLATFORM(GTK)
4444 MappedMemory
4545#endif
4646 };

@@public:
4848#if PLATFORM(MAC)
4949 Attachment(mach_port_name_t port, mach_msg_type_name_t disposition);
5050 Attachment(void* address, mach_msg_size_t size, mach_msg_copy_options_t copyOptions, bool deallocate);
51 #elif PLATFORM(QT)
 51#elif PLATFORM(QT) || PLATFORM(GTK)
5252 Attachment(int fileDescriptor, size_t);
5353#endif
5454

@@public:
6666 mach_msg_size_t size() const { ASSERT(m_type == MachOOLMemoryType); return m_oolMemory.size; }
6767 mach_msg_copy_options_t copyOptions() const { ASSERT(m_type == MachOOLMemoryType); return m_oolMemory.copyOptions; }
6868 bool deallocate() const { ASSERT(m_type == MachOOLMemoryType); return m_oolMemory.deallocate; }
69 #elif PLATFORM(QT)
 69#elif PLATFORM(QT) || PLATFORM(GTK)
7070 size_t size() const { return m_size; }
7171
7272 int releaseFileDescriptor() { int temp = m_fileDescriptor; m_fileDescriptor = -1; return temp; }

@@private:
9494 bool deallocate;
9595 } m_oolMemory;
9696 };
97 #elif PLATFORM(QT)
 97#elif PLATFORM(QT) || PLATFORM(GTK)
9898 int m_fileDescriptor;
9999 size_t m_size;
100100#endif

Source/WebKit2/Platform/CoreIPC/Connection.h

@@private:
305305 OwnPtr<ArgumentEncoder> m_pendingWriteArguments;
306306 OVERLAPPED m_writeState;
307307 HANDLE m_connectionPipe;
308 #elif PLATFORM(QT)
 308#elif PLATFORM(QT) || PLATFORM(GTK)
309309 // Called on the connection queue.
310310 void readyReadHandler();
311311
312312 Vector<uint8_t> m_readBuffer;
313313 size_t m_currentMessageSize;
314  QSocketNotifier* m_socketNotifier;
315314 int m_socketDescriptor;
316 #elif PLATFORM(GTK)
317  void readEventHandler();
318  void processCompletedMessage();
319  bool messageProcessingCompleted() { return !m_currentMessageSize; }
320315
321  int m_socket;
322  Vector<uint8_t> m_readBuffer;
323  size_t m_currentMessageSize;
324  size_t m_pendingBytes;
 316#if PLATFORM(QT)
 317 QSocketNotifier* m_socketNotifier;
 318#endif
325319#endif
326320};
327321

Source/WebKit2/Platform/CoreIPC/gtk/ConnectionGtk.cpp

1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "config.h"
28 #include "Connection.h"
29 
30 #include "ArgumentEncoder.h"
31 #include "WorkItem.h"
32 #include <errno.h>
33 #include <glib.h>
34 #include <sys/fcntl.h>
35 
36 using namespace std;
37 
38 namespace CoreIPC {
39 
40 static const size_t initialMessageBufferSize = 4096;
41 
42 static int readBytesFromSocket(int fileDescriptor, uint8_t* ptr, size_t length)
43 {
44  ASSERT(fileDescriptor > 0);
45  ASSERT(ptr);
46  ASSERT(length > 0);
47 
48  ssize_t numberOfBytesRead = 0;
49  size_t pendingBytesToRead = length;
50  uint8_t* buffer = ptr;
51 
52  while (pendingBytesToRead > 0) {
53  if ((numberOfBytesRead = read(fileDescriptor, buffer, pendingBytesToRead)) < 0) {
54  if (errno == EINTR)
55  numberOfBytesRead = 0;
56  else if (errno == EAGAIN || errno == EWOULDBLOCK)
57  break;
58  else
59  return 0;
60  } else if (!numberOfBytesRead)
61  break;
62 
63  buffer += numberOfBytesRead;
64  pendingBytesToRead -= numberOfBytesRead;
65  }
66 
67  return (length - pendingBytesToRead);
68 }
69 
70 static bool writeBytesToSocket(int fileDescriptor, uint8_t* ptr, size_t length)
71 {
72  ASSERT(fileDescriptor > 0);
73  ASSERT(ptr);
74  ASSERT(length > 0);
75 
76  ssize_t numberOfBytesWritten = 0;
77  size_t pendingBytesToWrite = length;
78  uint8_t* buffer = ptr;
79 
80  // Keep writing to the socket till the complete message has been written.
81  while (pendingBytesToWrite > 0) {
82  if ((numberOfBytesWritten = write(fileDescriptor, buffer, pendingBytesToWrite)) < 0) {
83  if (errno == EINTR)
84  numberOfBytesWritten = 0;
85  else
86  return false;
87  }
88  buffer += numberOfBytesWritten;
89  pendingBytesToWrite -= numberOfBytesWritten;
90  }
91 
92  // Write operation failed if complete message is not written.
93  return !pendingBytesToWrite;
94 }
95 
96 void Connection::platformInitialize(Identifier identifier)
97 {
98  m_currentMessageSize = 0;
99  m_pendingBytes = 0;
100  m_readBuffer.resize(initialMessageBufferSize);
101  m_socket = identifier;
102 }
103 
104 void Connection::platformInvalidate()
105 {
106  if (!m_isConnected)
107  return;
108 
109  m_connectionQueue.unregisterEventSourceHandler(m_socket);
110  if (m_socket > 0) {
111  close(m_socket);
112  m_socket = -1;
113  }
114 
115  m_isConnected = false;
116 }
117 
118 void Connection::processCompletedMessage()
119 {
120  size_t realBufferSize = m_currentMessageSize - sizeof(MessageID);
121  unsigned messageID = *reinterpret_cast<unsigned*>(m_readBuffer.data() + realBufferSize);
122 
123  processIncomingMessage(MessageID::fromInt(messageID), adoptPtr(new ArgumentDecoder(m_readBuffer.data(), realBufferSize)));
124 
125  // Prepare for the next message.
126  m_currentMessageSize = 0;
127  m_pendingBytes = 0;
128 }
129 
130 void Connection::readEventHandler()
131 {
132  if (m_socket < 0)
133  return;
134 
135  // Handle any previously unprocessed message.
136  if (!messageProcessingCompleted()) {
137  if ((m_pendingBytes -= readBytesFromSocket(m_socket, (m_readBuffer.data() + (m_currentMessageSize - m_pendingBytes)), m_pendingBytes)) > 0)
138  return;
139 
140  // Message received completely. Process the message now.
141  processCompletedMessage();
142  }
143 
144  // Prepare to read the next message.
145  uint8_t sizeBuffer[sizeof(size_t)];
146  memset(sizeBuffer, 0, sizeof(size_t));
147 
148  while (messageProcessingCompleted()) {
149  if (readBytesFromSocket(m_socket, sizeBuffer, sizeof(size_t)))
150  m_currentMessageSize = *reinterpret_cast<size_t*>(sizeBuffer);
151 
152  if (!m_currentMessageSize)
153  break;
154 
155  if (m_readBuffer.size() < m_currentMessageSize)
156  m_readBuffer.grow(m_currentMessageSize);
157 
158  m_pendingBytes = m_currentMessageSize - readBytesFromSocket(m_socket, m_readBuffer.data(), m_currentMessageSize);
159  if (m_pendingBytes > 0) // Message partially received.
160  break;
161 
162  // Message received completely. Process the message now.
163  processCompletedMessage();
164 
165  memset(sizeBuffer, 0, sizeof(size_t));
166  }
167 }
168 
169 bool Connection::open()
170 {
171  int flags = fcntl(m_socket, F_GETFL, 0);
172  fcntl(m_socket, F_SETFL, flags | O_NONBLOCK);
173 
174  m_isConnected = true;
175 
176  // Register callbacks for connection termination and input data on the WorkQueue.
177  m_connectionQueue.registerEventSourceHandler(m_socket, (G_IO_HUP | G_IO_ERR), WorkItem::create(this, &Connection::connectionDidClose));
178  m_connectionQueue.registerEventSourceHandler(m_socket, G_IO_IN, WorkItem::create(this, &Connection::readEventHandler));
179  return true;
180 }
181 
182 bool Connection::platformCanSendOutgoingMessages() const
183 {
184  return (m_socket > 0);
185 }
186 
187 bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<ArgumentEncoder> arguments)
188 {
189  if (m_socket < 0)
190  return false;
191 
192  // We put the message ID last.
193  arguments->encodeUInt32(messageID.toInt());
194 
195  size_t bufferSize = arguments->bufferSize();
196 
197  // Send the message size first.
198  if (!writeBytesToSocket(m_socket, reinterpret_cast<uint8_t*>(&bufferSize), sizeof(size_t)))
199  return false;
200 
201  if (!writeBytesToSocket(m_socket, arguments->buffer(), arguments->bufferSize()))
202  return false;
203 
204  return true;
205 }
206 
207 } // namespace CoreIPC

Source/WebKit2/Platform/CoreIPC/posix/AttachmentPOSIX.cpp

 1/*
 2 * Copyright (C) 2010 Apple Inc. All rights reserved.
 3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
 4 *
 5 * Redistribution and use in source and binary forms, with or without
 6 * modification, are permitted provided that the following conditions
 7 * are met:
 8 * 1. Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 * notice, this list of conditions and the following disclaimer in the
 12 * documentation and/or other materials provided with the distribution.
 13 *
 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 24 * THE POSSIBILITY OF SUCH DAMAGE.
 25 */
 26
 27#include "config.h"
 28#include "Attachment.h"
 29
 30#include <unistd.h>
 31#include <errno.h>
 32
 33namespace CoreIPC {
 34
 35Attachment::Attachment(int fileDescriptor, size_t size)
 36 : m_type(MappedMemory)
 37 , m_fileDescriptor(fileDescriptor)
 38 , m_size(size)
 39{
 40 ASSERT(m_fileDescriptor);
 41 ASSERT(m_size);
 42}
 43
 44void Attachment::dispose()
 45{
 46 if (m_fileDescriptor != -1)
 47 while (close(m_fileDescriptor) == -1 && (errno == EINTR)) { }
 48}
 49
 50} // namespace CoreIPC

Source/WebKit2/Platform/CoreIPC/qt/AttachmentQt.cpp

1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "config.h"
28 #include "Attachment.h"
29 
30 #if PLATFORM(QT)
31 #include <unistd.h>
32 #include <errno.h>
33 #endif
34 
35 
36 namespace CoreIPC {
37 
38 Attachment::Attachment(int fileDescriptor, size_t size)
39  : m_type(MappedMemory)
40  , m_fileDescriptor(fileDescriptor)
41  , m_size(size)
42 {
43  ASSERT(m_fileDescriptor);
44  ASSERT(m_size);
45 }
46 
47 void Attachment::dispose()
48 {
49  if (m_fileDescriptor != -1)
50  while (close(m_fileDescriptor) == -1 && (errno == EINTR)) { }
51 }
52 
53 } // namespace CoreIPC

Source/WebKit2/Platform/CoreIPC/qt/ConnectionQt.cpp

1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "config.h"
28 #include "Connection.h"
29 
30 #include "ArgumentEncoder.h"
31 #include "ProcessLauncher.h"
32 #include "WorkItem.h"
33 #include "SharedMemory.h"
34 #include "WebProcessProxy.h"
35 #include <QApplication>
36 #include <QSocketNotifier>
37 #include <sys/socket.h>
38 #include <unistd.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <wtf/Assertions.h>
42 
43 using namespace std;
44 
45 namespace CoreIPC {
46 
47 static const size_t messageMaxSize = 4096;
48 static const size_t attachmentMaxAmount = 255;
49 
50 enum {
51  MessageBodyIsOOL = 1 << 31
52 };
53 
54 class MessageInfo {
55 public:
56  MessageInfo() { }
57 
58  MessageInfo(MessageID messageID, size_t bodySize, size_t initialAttachmentCount)
59  : m_messageID(messageID.toInt())
60  , m_bodySize(bodySize)
61  , m_attachmentCount(initialAttachmentCount)
62  {
63  ASSERT(!(m_messageID & MessageBodyIsOOL));
64  }
65 
66  void setMessageBodyOOL()
67  {
68  ASSERT(!isMessageBodyOOL());
69 
70  m_messageID |= MessageBodyIsOOL;
71  m_attachmentCount++;
72  }
73 
74  bool isMessageBodyOOL() const { return m_messageID & MessageBodyIsOOL; }
75 
76  size_t bodySize() const { return m_bodySize; }
77 
78  MessageID messageID() const { return MessageID::fromInt(m_messageID & ~MessageBodyIsOOL); }
79 
80  size_t attachmentCount() const { return m_attachmentCount; }
81 
82 private:
83  uint32_t m_messageID;
84  size_t m_bodySize;
85  size_t m_attachmentCount;
86 };
87 
88 void Connection::platformInitialize(Identifier identifier)
89 {
90  m_socketDescriptor = identifier;
91  m_socketNotifier = 0;
92  m_readBuffer.resize(messageMaxSize);
93  m_currentMessageSize = 0;
94 }
95 
96 void Connection::platformInvalidate()
97 {
98  if (m_socketDescriptor != -1)
99  while (close(m_socketDescriptor) == -1 && errno == EINTR) { }
100 
101  if (!m_isConnected)
102  return;
103 
104  delete m_socketNotifier;
105  m_socketNotifier = 0;
106  m_socketDescriptor = -1;
107  m_isConnected = false;
108 }
109 
110 class SocketNotifierResourceGuard {
111 public:
112  SocketNotifierResourceGuard(QSocketNotifier* socketNotifier)
113  : m_socketNotifier(socketNotifier)
114  {
115  m_socketNotifier->setEnabled(false);
116  }
117 
118  ~SocketNotifierResourceGuard()
119  {
120  m_socketNotifier->setEnabled(true);
121  }
122 
123 private:
124  QSocketNotifier* const m_socketNotifier;
125 };
126 
127 template<class T, class iterator>
128 class AttachmentResourceGuard {
129 public:
130  AttachmentResourceGuard(T& attachments)
131  : m_attachments(attachments)
132  {
133  }
134  ~AttachmentResourceGuard()
135  {
136  iterator end = m_attachments.end();
137  for (iterator i = m_attachments.begin(); i != end; ++i)
138  i->dispose();
139  }
140 private:
141  T& m_attachments;
142 };
143 
144 void Connection::readyReadHandler()
145 {
146  Deque<Attachment> attachments;
147  SocketNotifierResourceGuard socketNotifierEnabler(m_socketNotifier);
148  AttachmentResourceGuard<Deque<Attachment>, Deque<Attachment>::iterator> attachementDisposer(attachments);
149 
150  char attachmentDescriptorBuffer[CMSG_SPACE(sizeof(int) * (attachmentMaxAmount))];
151  struct msghdr message;
152  memset(&message, 0, sizeof(message));
153 
154  struct iovec iov[1];
155  memset(&iov, 0, sizeof(iov));
156 
157  message.msg_control = attachmentDescriptorBuffer;
158  message.msg_controllen = CMSG_SPACE(sizeof(int) * (attachmentMaxAmount));
159 
160  iov[0].iov_base = m_readBuffer.data();
161  iov[0].iov_len = m_readBuffer.size();
162 
163  message.msg_iov = iov;
164  message.msg_iovlen = 1;
165 
166 
167  int messageLength = 0;
168  while ((messageLength = recvmsg(m_socketDescriptor, &message, 0)) == -1) {
169  if (errno != EINTR)
170  return;
171  }
172 
173  struct cmsghdr* controlMessage = CMSG_FIRSTHDR(&message);
174 
175  MessageInfo messageInfo;
176  unsigned char* messageData = m_readBuffer.data();
177 
178  memcpy(&messageInfo, messageData, sizeof(messageInfo));
179  ASSERT(messageLength == sizeof(messageInfo) + messageInfo.attachmentCount() * sizeof(size_t) + (messageInfo.isMessageBodyOOL() ? 0 : messageInfo.bodySize()));
180 
181  messageData += sizeof(messageInfo);
182 
183  RefPtr<WebKit::SharedMemory> oolMessageBody;
184 
185  if (messageInfo.attachmentCount()) {
186  if (controlMessage && controlMessage->cmsg_level == SOL_SOCKET && controlMessage->cmsg_type == SCM_RIGHTS) {
187  size_t attachmentSizes[messageInfo.attachmentCount()];
188  memcpy(attachmentSizes, messageData, sizeof(attachmentSizes));
189 
190  messageData += sizeof(attachmentSizes);
191 
192  int fileDescriptors[messageInfo.attachmentCount()];
193  memcpy(fileDescriptors, CMSG_DATA(controlMessage), sizeof(fileDescriptors));
194 
195  int attachmentCount = messageInfo.attachmentCount();
196 
197  if (messageInfo.isMessageBodyOOL())
198  attachmentCount--;
199 
200  for (int i = 0; i < attachmentCount; ++i) {
201  while (fcntl(fileDescriptors[i], F_SETFL, FD_CLOEXEC) == -1) {
202  if (errno != EINTR) {
203  ASSERT_NOT_REACHED();
204  return;
205  }
206  }
207  }
208 
209  for (int i = 0; i < attachmentCount; ++i)
210  attachments.append(Attachment(fileDescriptors[i], attachmentSizes[i]));
211 
212  if (messageInfo.isMessageBodyOOL()) {
213  ASSERT(messageInfo.bodySize());
214 
215  WebKit::SharedMemory::Handle handle;
216  handle.adoptFromAttachment(fileDescriptors[attachmentCount], attachmentSizes[attachmentCount]);
217  if (handle.isNull()) {
218  ASSERT_NOT_REACHED();
219  return;
220  }
221 
222  oolMessageBody = WebKit::SharedMemory::create(handle, WebKit::SharedMemory::ReadOnly);
223  if (!oolMessageBody) {
224  ASSERT_NOT_REACHED();
225  return;
226  }
227  }
228 
229  controlMessage = CMSG_NXTHDR(&message, controlMessage);
230  } else {
231  ASSERT_NOT_REACHED();
232  return;
233  }
234  }
235 
236  ASSERT(attachments.size() == messageInfo.isMessageBodyOOL() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount());
237 
238  unsigned char* messageBody = messageData;
239 
240  if (messageInfo.isMessageBodyOOL())
241  messageBody = reinterpret_cast<unsigned char*>(oolMessageBody->data());
242 
243  ArgumentDecoder* argumentDecoder;
244  if (attachments.isEmpty())
245  argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize());
246  else
247  argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize(), attachments);
248 
249  processIncomingMessage(messageInfo.messageID(), adoptPtr(argumentDecoder));
250 
251  ASSERT(!controlMessage);
252 }
253 
254 bool Connection::open()
255 {
256  ASSERT(!m_socketNotifier);
257  int flags = fcntl(m_socketDescriptor, F_GETFL, 0);
258  while (fcntl(m_socketDescriptor, F_SETFL, flags | O_NONBLOCK) == -1) {
259  if (errno != EINTR) {
260  ASSERT_NOT_REACHED();
261  return false;
262  }
263  }
264 
265  m_isConnected = true;
266  m_socketNotifier = m_connectionQueue.registerSocketEventHandler(m_socketDescriptor, QSocketNotifier::Read, WorkItem::create(this, &Connection::readyReadHandler));
267 
268  // Schedule a call to readyReadHandler. Data may have arrived before installation of the signal
269  // handler.
270  m_connectionQueue.scheduleWork(WorkItem::create(this, &Connection::readyReadHandler));
271 
272  return true;
273 }
274 
275 bool Connection::platformCanSendOutgoingMessages() const
276 {
277  return m_socketNotifier;
278 }
279 
280 bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<ArgumentEncoder> arguments)
281 {
282  ASSERT(m_socketNotifier);
283  COMPILE_ASSERT(sizeof(MessageInfo) + attachmentMaxAmount * sizeof(size_t) <= messageMaxSize, AttachmentsFitToMessageInline);
284 
285  Vector<Attachment> attachments = arguments->releaseAttachments();
286  AttachmentResourceGuard<Vector<Attachment>, Vector<Attachment>::iterator> attachementDisposer(attachments);
287 
288  if (attachments.size() > (attachmentMaxAmount - 1)) {
289  ASSERT_NOT_REACHED();
290  return false;
291  }
292 
293  MessageInfo messageInfo(messageID, arguments->bufferSize(), attachments.size());
294  size_t messageSizeWithBodyInline = sizeof(messageInfo) + (attachments.size() * sizeof(size_t)) + arguments->bufferSize();
295  if (messageSizeWithBodyInline > messageMaxSize && arguments->bufferSize()) {
296  RefPtr<WebKit::SharedMemory> oolMessageBody = WebKit::SharedMemory::create(arguments->bufferSize());
297  if (!oolMessageBody)
298  return false;
299 
300  WebKit::SharedMemory::Handle handle;
301  if (!oolMessageBody->createHandle(handle, WebKit::SharedMemory::ReadOnly))
302  return false;
303 
304  messageInfo.setMessageBodyOOL();
305 
306  memcpy(oolMessageBody->data(), arguments->buffer(), arguments->bufferSize());
307 
308  attachments.append(handle.releaseToAttachment());
309  }
310 
311  struct msghdr message;
312  memset(&message, 0, sizeof(message));
313 
314  struct iovec iov[3];
315  memset(&iov, 0, sizeof(iov));
316 
317  message.msg_iov = iov;
318  int iovLength = 1;
319 
320  iov[0].iov_base = reinterpret_cast<void*>(&messageInfo);
321  iov[0].iov_len = sizeof(messageInfo);
322 
323  char attachmentFDBuffer[CMSG_SPACE(sizeof(int) * (attachments.size()))];
324  size_t attachmentSizes[attachments.size()];
325 
326  if (!attachments.isEmpty()) {
327  message.msg_control = attachmentFDBuffer;
328  message.msg_controllen = sizeof(attachmentFDBuffer);
329 
330  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&message);
331  cmsg->cmsg_level = SOL_SOCKET;
332  cmsg->cmsg_type = SCM_RIGHTS;
333  cmsg->cmsg_len = CMSG_LEN(sizeof(int) * attachments.size());
334 
335  int* fdptr = reinterpret_cast<int*>(CMSG_DATA(cmsg));
336  for (int i = 0; i < attachments.size(); ++i) {
337  attachmentSizes[i] = attachments[i].size();
338  fdptr[i] = attachments[i].fileDescriptor();
339  }
340 
341  message.msg_controllen = cmsg->cmsg_len;
342 
343  iov[iovLength].iov_base = attachmentSizes;
344  iov[iovLength].iov_len = sizeof(attachmentSizes);
345  ++iovLength;
346  }
347 
348  if (!messageInfo.isMessageBodyOOL() && arguments->bufferSize()) {
349  iov[iovLength].iov_base = reinterpret_cast<void*>(arguments->buffer());
350  iov[iovLength].iov_len = arguments->bufferSize();
351  ++iovLength;
352  }
353 
354  message.msg_iovlen = iovLength;
355 
356  int bytesSent = 0;
357  while ((bytesSent = sendmsg(m_socketDescriptor, &message, 0)) == -1) {
358  if (errno != EINTR)
359  return false;
360  }
361  return true;
362 }
363 
364 void Connection::setShouldCloseConnectionOnProcessTermination(WebKit::PlatformProcessIdentifier process)
365 {
366  m_connectionQueue.scheduleWorkOnTermination(process, WorkItem::create(this, &Connection::connectionDidClose));
367 }
368 
369 } // namespace CoreIPC

Source/WebKit2/Platform/CoreIPC/unix/ConnectionUnix.cpp

 1/*
 2 * Copyright (C) 2010 Apple Inc. All rights reserved.
 3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
 4 *
 5 * Redistribution and use in source and binary forms, with or without
 6 * modification, are permitted provided that the following conditions
 7 * are met:
 8 * 1. Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 * notice, this list of conditions and the following disclaimer in the
 12 * documentation and/or other materials provided with the distribution.
 13 *
 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 24 * THE POSSIBILITY OF SUCH DAMAGE.
 25 */
 26
 27#include "config.h"
 28#include "Connection.h"
 29
 30#include "ArgumentEncoder.h"
 31#include "ProcessLauncher.h"
 32#include "WorkItem.h"
 33#include "SharedMemory.h"
 34#include "WebProcessProxy.h"
 35#include <sys/socket.h>
 36#include <unistd.h>
 37#include <errno.h>
 38#include <fcntl.h>
 39#include <wtf/Assertions.h>
 40
 41#if PLATFORM(QT)
 42#include <QApplication>
 43#include <QSocketNotifier>
 44#elif PLATFORM(GTK)
 45#include <glib.h>
 46#endif
 47
 48using namespace std;
 49
 50namespace CoreIPC {
 51
 52static const size_t messageMaxSize = 4096;
 53static const size_t attachmentMaxAmount = 255;
 54
 55enum {
 56 MessageBodyIsOOL = 1 << 31
 57};
 58
 59class MessageInfo {
 60public:
 61 MessageInfo() { }
 62
 63 MessageInfo(MessageID messageID, size_t bodySize, size_t initialAttachmentCount)
 64 : m_messageID(messageID.toInt())
 65 , m_bodySize(bodySize)
 66 , m_attachmentCount(initialAttachmentCount)
 67 {
 68 ASSERT(!(m_messageID & MessageBodyIsOOL));
 69 }
 70
 71 void setMessageBodyOOL()
 72 {
 73 ASSERT(!isMessageBodyOOL());
 74
 75 m_messageID |= MessageBodyIsOOL;
 76 m_attachmentCount++;
 77 }
 78
 79 bool isMessageBodyOOL() const { return m_messageID & MessageBodyIsOOL; }
 80
 81 size_t bodySize() const { return m_bodySize; }
 82
 83 MessageID messageID() const { return MessageID::fromInt(m_messageID & ~MessageBodyIsOOL); }
 84
 85 size_t attachmentCount() const { return m_attachmentCount; }
 86
 87private:
 88 uint32_t m_messageID;
 89 size_t m_bodySize;
 90 size_t m_attachmentCount;
 91};
 92
 93void Connection::platformInitialize(Identifier identifier)
 94{
 95 m_socketDescriptor = identifier;
 96 m_readBuffer.resize(messageMaxSize);
 97 m_currentMessageSize = 0;
 98
 99#if PLATFORM(QT)
 100 m_socketNotifier = 0;
 101#endif
 102}
 103
 104void Connection::platformInvalidate()
 105{
 106 if (m_socketDescriptor != -1)
 107 while (close(m_socketDescriptor) == -1 && errno == EINTR) { }
 108
 109 if (!m_isConnected)
 110 return;
 111
 112 m_socketDescriptor = -1;
 113 m_isConnected = false;
 114
 115#if PLATFORM(QT)
 116 delete m_socketNotifier;
 117 m_socketNotifier = 0;
 118#endif
 119
 120#if PLATFORM(GTK)
 121 m_connectionQueue.unregisterEventSourceHandler(m_socketDescriptor);
 122#endif
 123}
 124
 125#if PLATFORM(QT)
 126class SocketNotifierResourceGuard {
 127public:
 128 SocketNotifierResourceGuard(QSocketNotifier* socketNotifier)
 129 : m_socketNotifier(socketNotifier)
 130 {
 131 m_socketNotifier->setEnabled(false);
 132 }
 133
 134 ~SocketNotifierResourceGuard()
 135 {
 136 m_socketNotifier->setEnabled(true);
 137 }
 138
 139private:
 140 QSocketNotifier* const m_socketNotifier;
 141};
 142#endif
 143
 144template<class T, class iterator>
 145class AttachmentResourceGuard {
 146public:
 147 AttachmentResourceGuard(T& attachments)
 148 : m_attachments(attachments)
 149 {
 150 }
 151 ~AttachmentResourceGuard()
 152 {
 153 iterator end = m_attachments.end();
 154 for (iterator i = m_attachments.begin(); i != end; ++i)
 155 i->dispose();
 156 }
 157private:
 158 T& m_attachments;
 159};
 160
 161void Connection::readyReadHandler()
 162{
 163 Deque<Attachment> attachments;
 164#if PLATFORM(QT)
 165 SocketNotifierResourceGuard socketNotifierEnabler(m_socketNotifier);
 166#endif
 167 AttachmentResourceGuard<Deque<Attachment>, Deque<Attachment>::iterator> attachementDisposer(attachments);
 168
 169 char attachmentDescriptorBuffer[CMSG_SPACE(sizeof(int) * (attachmentMaxAmount))];
 170 struct msghdr message;
 171 memset(&message, 0, sizeof(message));
 172
 173 struct iovec iov[1];
 174 memset(&iov, 0, sizeof(iov));
 175
 176 message.msg_control = attachmentDescriptorBuffer;
 177 message.msg_controllen = CMSG_SPACE(sizeof(int) * (attachmentMaxAmount));
 178
 179 iov[0].iov_base = m_readBuffer.data();
 180 iov[0].iov_len = m_readBuffer.size();
 181
 182 message.msg_iov = iov;
 183 message.msg_iovlen = 1;
 184
 185
 186 int messageLength = 0;
 187 while ((messageLength = recvmsg(m_socketDescriptor, &message, 0)) == -1) {
 188 if (errno != EINTR)
 189 return;
 190 }
 191
 192 struct cmsghdr* controlMessage = CMSG_FIRSTHDR(&message);
 193
 194 MessageInfo messageInfo;
 195 unsigned char* messageData = m_readBuffer.data();
 196
 197 memcpy(&messageInfo, messageData, sizeof(messageInfo));
 198 ASSERT(messageLength == sizeof(messageInfo) + messageInfo.attachmentCount() * sizeof(size_t) + (messageInfo.isMessageBodyOOL() ? 0 : messageInfo.bodySize()));
 199
 200 messageData += sizeof(messageInfo);
 201
 202 RefPtr<WebKit::SharedMemory> oolMessageBody;
 203
 204 if (messageInfo.attachmentCount()) {
 205 if (controlMessage && controlMessage->cmsg_level == SOL_SOCKET && controlMessage->cmsg_type == SCM_RIGHTS) {
 206 size_t attachmentSizes[messageInfo.attachmentCount()];
 207 memcpy(attachmentSizes, messageData, sizeof(attachmentSizes));
 208
 209 messageData += sizeof(attachmentSizes);
 210
 211 int fileDescriptors[messageInfo.attachmentCount()];
 212 memcpy(fileDescriptors, CMSG_DATA(controlMessage), sizeof(fileDescriptors));
 213
 214 int attachmentCount = messageInfo.attachmentCount();
 215
 216 if (messageInfo.isMessageBodyOOL())
 217 attachmentCount--;
 218
 219 for (int i = 0; i < attachmentCount; ++i) {
 220 while (fcntl(fileDescriptors[i], F_SETFL, FD_CLOEXEC) == -1) {
 221 if (errno != EINTR) {
 222 ASSERT_NOT_REACHED();
 223 return;
 224 }
 225 }
 226 }
 227
 228 for (int i = 0; i < attachmentCount; ++i)
 229 attachments.append(Attachment(fileDescriptors[i], attachmentSizes[i]));
 230
 231 if (messageInfo.isMessageBodyOOL()) {
 232 ASSERT(messageInfo.bodySize());
 233
 234 WebKit::SharedMemory::Handle handle;
 235 handle.adoptFromAttachment(fileDescriptors[attachmentCount], attachmentSizes[attachmentCount]);
 236 if (handle.isNull()) {
 237 ASSERT_NOT_REACHED();
 238 return;
 239 }
 240
 241 oolMessageBody = WebKit::SharedMemory::create(handle, WebKit::SharedMemory::ReadOnly);
 242 if (!oolMessageBody) {
 243 ASSERT_NOT_REACHED();
 244 return;
 245 }
 246 }
 247
 248 controlMessage = CMSG_NXTHDR(&message, controlMessage);
 249 } else {
 250 ASSERT_NOT_REACHED();
 251 return;
 252 }
 253 }
 254
 255 ASSERT(attachments.size() == messageInfo.isMessageBodyOOL() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount());
 256
 257 unsigned char* messageBody = messageData;
 258
 259 if (messageInfo.isMessageBodyOOL())
 260 messageBody = reinterpret_cast<unsigned char*>(oolMessageBody->data());
 261
 262 ArgumentDecoder* argumentDecoder;
 263 if (attachments.isEmpty())
 264 argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize());
 265 else
 266 argumentDecoder = new ArgumentDecoder(messageBody, messageInfo.bodySize(), attachments);
 267
 268 processIncomingMessage(messageInfo.messageID(), adoptPtr(argumentDecoder));
 269
 270 ASSERT(!controlMessage);
 271}
 272
 273bool Connection::open()
 274{
 275#if PLATFORM(QT)
 276 ASSERT(!m_socketNotifier);
 277#endif
 278
 279 int flags = fcntl(m_socketDescriptor, F_GETFL, 0);
 280 while (fcntl(m_socketDescriptor, F_SETFL, flags | O_NONBLOCK) == -1) {
 281 if (errno != EINTR) {
 282 ASSERT_NOT_REACHED();
 283 return false;
 284 }
 285 }
 286
 287 m_isConnected = true;
 288#if PLATFORM(QT)
 289 m_socketNotifier = m_connectionQueue.registerSocketEventHandler(m_socketDescriptor, QSocketNotifier::Read, WorkItem::create(this, &Connection::readyReadHandler));
 290#elif PLATFORM(GTK)
 291 m_connectionQueue.registerEventSourceHandler(m_socketDescriptor, (G_IO_HUP | G_IO_ERR), WorkItem::create(this, &Connection::connectionDidClose));
 292 m_connectionQueue.registerEventSourceHandler(m_socketDescriptor, G_IO_IN, WorkItem::create(this, &Connection::readyReadHandler));
 293#endif
 294
 295 // Schedule a call to readyReadHandler. Data may have arrived before installation of the signal
 296 // handler.
 297 m_connectionQueue.scheduleWork(WorkItem::create(this, &Connection::readyReadHandler));
 298
 299 return true;
 300}
 301
 302bool Connection::platformCanSendOutgoingMessages() const
 303{
 304 return m_isConnected;
 305}
 306
 307bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<ArgumentEncoder> arguments)
 308{
 309#if PLATFORM(QT)
 310 ASSERT(m_socketNotifier);
 311#endif
 312
 313 COMPILE_ASSERT(sizeof(MessageInfo) + attachmentMaxAmount * sizeof(size_t) <= messageMaxSize, AttachmentsFitToMessageInline);
 314
 315 Vector<Attachment> attachments = arguments->releaseAttachments();
 316 AttachmentResourceGuard<Vector<Attachment>, Vector<Attachment>::iterator> attachementDisposer(attachments);
 317
 318 if (attachments.size() > (attachmentMaxAmount - 1)) {
 319 ASSERT_NOT_REACHED();
 320 return false;
 321 }
 322
 323 MessageInfo messageInfo(messageID, arguments->bufferSize(), attachments.size());
 324 size_t messageSizeWithBodyInline = sizeof(messageInfo) + (attachments.size() * sizeof(size_t)) + arguments->bufferSize();
 325 if (messageSizeWithBodyInline > messageMaxSize && arguments->bufferSize()) {
 326 RefPtr<WebKit::SharedMemory> oolMessageBody = WebKit::SharedMemory::create(arguments->bufferSize());
 327 if (!oolMessageBody)
 328 return false;
 329
 330 WebKit::SharedMemory::Handle handle;
 331 if (!oolMessageBody->createHandle(handle, WebKit::SharedMemory::ReadOnly))
 332 return false;
 333
 334 messageInfo.setMessageBodyOOL();
 335
 336 memcpy(oolMessageBody->data(), arguments->buffer(), arguments->bufferSize());
 337
 338 attachments.append(handle.releaseToAttachment());
 339 }
 340
 341 struct msghdr message;
 342 memset(&message, 0, sizeof(message));
 343
 344 struct iovec iov[3];
 345 memset(&iov, 0, sizeof(iov));
 346
 347 message.msg_iov = iov;
 348 int iovLength = 1;
 349
 350 iov[0].iov_base = reinterpret_cast<void*>(&messageInfo);
 351 iov[0].iov_len = sizeof(messageInfo);
 352
 353 char attachmentFDBuffer[CMSG_SPACE(sizeof(int) * (attachments.size()))];
 354 size_t attachmentSizes[attachments.size()];
 355
 356 if (!attachments.isEmpty()) {
 357 message.msg_control = attachmentFDBuffer;
 358 message.msg_controllen = sizeof(attachmentFDBuffer);
 359
 360 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&message);
 361 cmsg->cmsg_level = SOL_SOCKET;
 362 cmsg->cmsg_type = SCM_RIGHTS;
 363 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * attachments.size());
 364
 365 int* fdptr = reinterpret_cast<int*>(CMSG_DATA(cmsg));
 366 for (size_t i = 0; i < attachments.size(); ++i) {
 367 attachmentSizes[i] = attachments[i].size();
 368 fdptr[i] = attachments[i].fileDescriptor();
 369 }
 370
 371 message.msg_controllen = cmsg->cmsg_len;
 372
 373 iov[iovLength].iov_base = attachmentSizes;
 374 iov[iovLength].iov_len = sizeof(attachmentSizes);
 375 ++iovLength;
 376 }
 377
 378 if (!messageInfo.isMessageBodyOOL() && arguments->bufferSize()) {
 379 iov[iovLength].iov_base = reinterpret_cast<void*>(arguments->buffer());
 380 iov[iovLength].iov_len = arguments->bufferSize();
 381 ++iovLength;
 382 }
 383
 384 message.msg_iovlen = iovLength;
 385
 386 int bytesSent = 0;
 387 while ((bytesSent = sendmsg(m_socketDescriptor, &message, 0)) == -1) {
 388 if (errno != EINTR)
 389 return false;
 390 }
 391 return true;
 392}
 393
 394#if PLATFORM(QT)
 395void Connection::setShouldCloseConnectionOnProcessTermination(WebKit::PlatformProcessIdentifier process)
 396{
 397 m_connectionQueue.scheduleWorkOnTermination(process, WorkItem::create(this, &Connection::connectionDidClose));
 398}
 399#endif
 400
 401} // namespace CoreIPC

Source/WebKit2/Platform/SharedMemory.h

3030#include <wtf/PassRefPtr.h>
3131#include <wtf/RefCounted.h>
3232
33 #if PLATFORM(QT)
 33#if PLATFORM(QT) || PLATFORM(GTK)
3434#include "Attachment.h"
3535#include <wtf/text/WTFString.h>
3636#endif

@@public:
6060 void encode(CoreIPC::ArgumentEncoder*) const;
6161 static bool decode(CoreIPC::ArgumentDecoder*, Handle&);
6262
63 #if PLATFORM(QT)
 63#if PLATFORM(QT) || PLATFORM(GTK)
6464 CoreIPC::Attachment releaseToAttachment() const;
6565 void adoptFromAttachment(int fileDescriptor, size_t);
6666#endif

@@public:
7070 mutable mach_port_t m_port;
7171#elif PLATFORM(WIN)
7272 mutable HANDLE m_handle;
73 #elif PLATFORM(QT)
 73#elif PLATFORM(QT) || PLATFORM(GTK)
7474 mutable int m_fileDescriptor;
7575#endif
7676 size_t m_size;

@@private:
9999 mach_port_t m_port;
100100#elif PLATFORM(WIN)
101101 HANDLE m_handle;
102 #elif PLATFORM(QT)
 102#elif PLATFORM(QT) || PLATFORM(GTK)
103103 int m_fileDescriptor;
104104#endif
105105};

Source/WebKit2/Platform/posix/SharedMemoryPOSIX.cpp

 1/*
 2 * Copyright (C) 2010 Apple Inc. All rights reserved.
 3 * Copyright (c) 2010 University of Szeged
 4 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
 5 *
 6 * Redistribution and use in source and binary forms, with or without
 7 * modification, are permitted provided that the following conditions
 8 * are met:
 9 * 1. Redistributions of source code must retain the above copyright
 10 * notice, this list of conditions and the following disclaimer.
 11 * 2. Redistributions in binary form must reproduce the above copyright
 12 * notice, this list of conditions and the following disclaimer in the
 13 * documentation and/or other materials provided with the distribution.
 14 *
 15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 25 * THE POSSIBILITY OF SUCH DAMAGE.
 26 */
 27
 28#include "config.h"
 29#include "SharedMemory.h"
 30
 31#include "ArgumentDecoder.h"
 32#include "ArgumentEncoder.h"
 33#include "WebCoreArgumentCoders.h"
 34#include <errno.h>
 35#include <fcntl.h>
 36#include <stdlib.h>
 37#include <sys/mman.h>
 38#include <sys/stat.h>
 39#include <sys/types.h>
 40#include <unistd.h>
 41#include <wtf/Assertions.h>
 42#include <wtf/CurrentTime.h>
 43
 44#if PLATFORM(QT)
 45#include <QDir>
 46#elif PLATFORM(GTK)
 47#include <wtf/gobject/GOwnPtr.h>
 48#endif
 49
 50namespace WebKit {
 51
 52SharedMemory::Handle::Handle()
 53 : m_fileDescriptor(-1)
 54 , m_size(0)
 55{
 56}
 57
 58SharedMemory::Handle::~Handle()
 59{
 60 if (!isNull())
 61 while (close(m_fileDescriptor) == -1 && errno == EINTR) { }
 62}
 63
 64bool SharedMemory::Handle::isNull() const
 65{
 66 return m_fileDescriptor == -1;
 67}
 68
 69void SharedMemory::Handle::encode(CoreIPC::ArgumentEncoder* encoder) const
 70{
 71 ASSERT(!isNull());
 72
 73 encoder->encode(releaseToAttachment());
 74}
 75
 76bool SharedMemory::Handle::decode(CoreIPC::ArgumentDecoder* decoder, Handle& handle)
 77{
 78 ASSERT_ARG(handle, !handle.m_size);
 79 ASSERT_ARG(handle, handle.isNull());
 80
 81 CoreIPC::Attachment attachment;
 82 if (!decoder->decode(attachment))
 83 return false;
 84
 85 handle.adoptFromAttachment(attachment.releaseFileDescriptor(), attachment.size());
 86 return true;
 87}
 88
 89CoreIPC::Attachment SharedMemory::Handle::releaseToAttachment() const
 90{
 91 ASSERT(!isNull());
 92
 93 int temp = m_fileDescriptor;
 94 m_fileDescriptor = -1;
 95 return CoreIPC::Attachment(temp, m_size);
 96}
 97
 98void SharedMemory::Handle::adoptFromAttachment(int fileDescriptor, size_t size)
 99{
 100 ASSERT(!m_size);
 101 ASSERT(isNull());
 102
 103 m_fileDescriptor = fileDescriptor;
 104 m_size = size;
 105}
 106
 107PassRefPtr<SharedMemory> SharedMemory::create(size_t size)
 108{
 109#if PLATFORM(QT)
 110 QString tempName = QDir::temp().filePath(QLatin1String("qwkshm.XXXXXX"));
 111 QByteArray tempNameCSTR = tempName.toLocal8Bit();
 112 char* tempNameC = tempNameCSTR.data();
 113#elif PLATFORM(GTK)
 114 GOwnPtr<gchar> tempName(g_build_filename(g_get_tmp_dir(), "WK2SharedMemoryXXXXXX", NULL));
 115 gchar* tempNameC = tempName.get();
 116#endif
 117
 118 int fileDescriptor;
 119 while ((fileDescriptor = mkstemp(tempNameC)) == -1) {
 120 if (errno != EINTR)
 121 return 0;
 122 }
 123 while (fcntl(fileDescriptor, F_SETFD, FD_CLOEXEC) == -1) {
 124 if (errno != EINTR) {
 125 while (close(fileDescriptor) == -1 && errno == EINTR) { }
 126 unlink(tempNameC);
 127 return 0;
 128 }
 129 }
 130
 131 while (ftruncate(fileDescriptor, size) == -1) {
 132 if (errno != EINTR) {
 133 while (close(fileDescriptor) == -1 && errno == EINTR) { }
 134 unlink(tempNameC);
 135 return 0;
 136 }
 137 }
 138
 139 void* data = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor, 0);
 140 if (data == MAP_FAILED) {
 141 while (close(fileDescriptor) == -1 && errno == EINTR) { }
 142 unlink(tempNameC);
 143 return 0;
 144 }
 145
 146 unlink(tempNameC);
 147
 148 RefPtr<SharedMemory> instance = adoptRef(new SharedMemory());
 149 instance->m_data = data;
 150 instance->m_fileDescriptor = fileDescriptor;
 151 instance->m_size = size;
 152 return instance.release();
 153}
 154
 155static inline int accessModeMMap(SharedMemory::Protection protection)
 156{
 157 switch (protection) {
 158 case SharedMemory::ReadOnly:
 159 return PROT_READ;
 160 case SharedMemory::ReadWrite:
 161 return PROT_READ | PROT_WRITE;
 162 }
 163
 164 ASSERT_NOT_REACHED();
 165 return PROT_READ | PROT_WRITE;
 166}
 167
 168PassRefPtr<SharedMemory> SharedMemory::create(const Handle& handle, Protection protection)
 169{
 170 ASSERT(!handle.isNull());
 171
 172 void* data = mmap(0, handle.m_size, accessModeMMap(protection), MAP_SHARED, handle.m_fileDescriptor, 0);
 173 if (data == MAP_FAILED)
 174 return 0;
 175
 176 RefPtr<SharedMemory> instance = adoptRef(new SharedMemory());
 177 instance->m_data = data;
 178 instance->m_fileDescriptor = handle.m_fileDescriptor;
 179 instance->m_size = handle.m_size;
 180 handle.m_fileDescriptor = -1;
 181 return instance;
 182}
 183
 184SharedMemory::~SharedMemory()
 185{
 186 munmap(m_data, m_size);
 187 while (close(m_fileDescriptor) == -1 && errno == EINTR) { }
 188}
 189
 190static inline int accessModeFile(SharedMemory::Protection protection)
 191{
 192 switch (protection) {
 193 case SharedMemory::ReadOnly:
 194 return O_RDONLY;
 195 case SharedMemory::ReadWrite:
 196 return O_RDWR;
 197 }
 198
 199 ASSERT_NOT_REACHED();
 200 return O_RDWR;
 201}
 202
 203bool SharedMemory::createHandle(Handle& handle, Protection protection)
 204{
 205 ASSERT_ARG(handle, !handle.m_size);
 206 ASSERT_ARG(handle, handle.isNull());
 207
 208 int duplicatedHandle;
 209 while ((duplicatedHandle = dup(m_fileDescriptor)) == -1) {
 210 if (errno != EINTR) {
 211 ASSERT_NOT_REACHED();
 212 return false;
 213 }
 214 }
 215
 216 while ((fcntl(duplicatedHandle, F_SETFD, FD_CLOEXEC | accessModeFile(protection)) == -1)) {
 217 if (errno != EINTR) {
 218 ASSERT_NOT_REACHED();
 219 while (close(duplicatedHandle) == -1 && errno == EINTR) { }
 220 return false;
 221 }
 222 }
 223 handle.m_fileDescriptor = duplicatedHandle;
 224 handle.m_size = m_size;
 225 return true;
 226}
 227
 228unsigned SharedMemory::systemPageSize()
 229{
 230 static unsigned pageSize = 0;
 231
 232 if (!pageSize)
 233 pageSize = getpagesize();
 234
 235 return pageSize;
 236}
 237
 238} // namespace WebKit

Source/WebKit2/Platform/qt/SharedMemoryQt.cpp

1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Copyright (c) 2010 University of Szeged
4  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25  * THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "config.h"
29 #include "SharedMemory.h"
30 
31 #include "ArgumentDecoder.h"
32 #include "ArgumentEncoder.h"
33 #include "WebCoreArgumentCoders.h"
34 #include <QDir>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #include <sys/mman.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42 #include <wtf/Assertions.h>
43 #include <wtf/CurrentTime.h>
44 
45 namespace WebKit {
46 
47 SharedMemory::Handle::Handle()
48  : m_fileDescriptor(-1)
49  , m_size(0)
50 {
51 }
52 
53 SharedMemory::Handle::~Handle()
54 {
55  if (!isNull())
56  while (close(m_fileDescriptor) == -1 && errno == EINTR) { }
57 }
58 
59 bool SharedMemory::Handle::isNull() const
60 {
61  return m_fileDescriptor == -1;
62 }
63 
64 void SharedMemory::Handle::encode(CoreIPC::ArgumentEncoder* encoder) const
65 {
66  ASSERT(!isNull());
67 
68  encoder->encode(releaseToAttachment());
69 }
70 
71 bool SharedMemory::Handle::decode(CoreIPC::ArgumentDecoder* decoder, Handle& handle)
72 {
73  ASSERT_ARG(handle, !handle.m_size);
74  ASSERT_ARG(handle, handle.isNull());
75 
76  CoreIPC::Attachment attachment;
77  if (!decoder->decode(attachment))
78  return false;
79 
80  handle.adoptFromAttachment(attachment.releaseFileDescriptor(), attachment.size());
81  return true;
82 }
83 
84 CoreIPC::Attachment SharedMemory::Handle::releaseToAttachment() const
85 {
86  ASSERT(!isNull());
87 
88  int temp = m_fileDescriptor;
89  m_fileDescriptor = -1;
90  return CoreIPC::Attachment(temp, m_size);
91 }
92 
93 void SharedMemory::Handle::adoptFromAttachment(int fileDescriptor, size_t size)
94 {
95  ASSERT(!m_size);
96  ASSERT(isNull());
97 
98  m_fileDescriptor = fileDescriptor;
99  m_size = size;
100 }
101 
102 PassRefPtr<SharedMemory> SharedMemory::create(size_t size)
103 {
104  QString tempName = QDir::temp().filePath(QLatin1String("qwkshm.XXXXXX"));
105  QByteArray tempNameCSTR = tempName.toLocal8Bit();
106  char* tempNameC = tempNameCSTR.data();
107 
108  int fileDescriptor;
109  while ((fileDescriptor = mkstemp(tempNameC)) == -1) {
110  if (errno != EINTR)
111  return 0;
112  }
113  while (fcntl(fileDescriptor, F_SETFD, FD_CLOEXEC) == -1) {
114  if (errno != EINTR) {
115  while (close(fileDescriptor) == -1 && errno == EINTR) { }
116  unlink(tempNameC);
117  return 0;
118  }
119  }
120 
121  while (ftruncate(fileDescriptor, size) == -1) {
122  if (errno != EINTR) {
123  while (close(fileDescriptor) == -1 && errno == EINTR) { }
124  unlink(tempNameC);
125  return 0;
126  }
127  }
128 
129  void* data = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor, 0);
130  if (data == MAP_FAILED) {
131  while (close(fileDescriptor) == -1 && errno == EINTR) { }
132  unlink(tempNameC);
133  return 0;
134  }
135 
136  unlink(tempNameC);
137 
138  RefPtr<SharedMemory> instance = adoptRef(new SharedMemory());
139  instance->m_data = data;
140  instance->m_fileDescriptor = fileDescriptor;
141  instance->m_size = size;
142  return instance.release();
143 }
144 
145 static inline int accessModeMMap(SharedMemory::Protection protection)
146 {
147  switch (protection) {
148  case SharedMemory::ReadOnly:
149  return PROT_READ;
150  case SharedMemory::ReadWrite:
151  return PROT_READ | PROT_WRITE;
152  }
153 
154  ASSERT_NOT_REACHED();
155  return PROT_READ | PROT_WRITE;
156 }
157 
158 PassRefPtr<SharedMemory> SharedMemory::create(const Handle& handle, Protection protection)
159 {
160  ASSERT(!handle.isNull());
161 
162  void* data = mmap(0, handle.m_size, accessModeMMap(protection), MAP_SHARED, handle.m_fileDescriptor, 0);
163  if (data == MAP_FAILED)
164  return 0;
165 
166  RefPtr<SharedMemory> instance = adoptRef(new SharedMemory());
167  instance->m_data = data;
168  instance->m_fileDescriptor = handle.m_fileDescriptor;
169  instance->m_size = handle.m_size;
170  handle.m_fileDescriptor = -1;
171  return instance;
172 }
173 
174 SharedMemory::~SharedMemory()
175 {
176  munmap(m_data, m_size);
177  while (close(m_fileDescriptor) == -1 && errno == EINTR) { }
178 }
179 
180 static inline int accessModeFile(SharedMemory::Protection protection)
181 {
182  switch (protection) {
183  case SharedMemory::ReadOnly:
184  return O_RDONLY;
185  case SharedMemory::ReadWrite:
186  return O_RDWR;
187  }
188 
189  ASSERT_NOT_REACHED();
190  return O_RDWR;
191 }
192 
193 bool SharedMemory::createHandle(Handle& handle, Protection protection)
194 {
195  ASSERT_ARG(handle, !handle.m_size);
196  ASSERT_ARG(handle, handle.isNull());
197 
198  int duplicatedHandle;
199  while ((duplicatedHandle = dup(m_fileDescriptor)) == -1) {
200  if (errno != EINTR) {
201  ASSERT_NOT_REACHED();
202  return false;
203  }
204  }
205 
206  while ((fcntl(duplicatedHandle, F_SETFD, FD_CLOEXEC | accessModeFile(protection)) == -1)) {
207  if (errno != EINTR) {
208  ASSERT_NOT_REACHED();
209  while (close(duplicatedHandle) == -1 && errno == EINTR) { }
210  return false;
211  }
212  }
213  handle.m_fileDescriptor = duplicatedHandle;
214  handle.m_size = m_size;
215  return true;
216 }
217 
218 unsigned SharedMemory::systemPageSize()
219 {
220  static unsigned pageSize = 0;
221 
222  if (!pageSize)
223  pageSize = getpagesize();
224 
225  return pageSize;
226 }
227 
228 } // namespace WebKit

Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp

@@void ProcessLauncher::launchProcess()
4949 pid_t pid = 0;
5050
5151 int sockets[2];
52  if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
 52 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) {
5353 fprintf(stderr, "Creation of socket failed with errno %d.\n", errno);
5454 ASSERT_NOT_REACHED();
5555 return;

Source/WebKit2/WebKit2.pro

@@SOURCES += \
297297 Platform/CoreIPC/BinarySemaphore.cpp \
298298 Platform/CoreIPC/Connection.cpp \
299299 Platform/CoreIPC/DataReference.cpp \
300  Platform/CoreIPC/qt/AttachmentQt.cpp \
301  Platform/CoreIPC/qt/ConnectionQt.cpp \
 300 Platform/CoreIPC/posix/AttachmentPOSIX.cpp \
 301 Platform/CoreIPC/unix/ConnectionUnix.cpp \
302302 Platform/Logging.cpp \
303303 Platform/Module.cpp \
304304 Platform/RunLoop.cpp \
305305 Platform/WorkQueue.cpp \
 306 Platform/posix/SharedMemoryPOSIX.cpp \
306307 Platform/qt/ModuleQt.cpp \
307308 Platform/qt/RunLoopQt.cpp \
308  Platform/qt/SharedMemoryQt.cpp \
309309 Platform/qt/WorkQueueQt.cpp \
310310 Shared/Plugins/Netscape/NetscapePluginModule.cpp \
311311 Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp \