1212
1313#include " swift/AST/PluginRegistry.h"
1414
15+ #include " swift/Basic/Defer.h"
1516#include " swift/Basic/LLVM.h"
1617#include " swift/Basic/Program.h"
1718#include " swift/Basic/Sandbox.h"
2122#include " llvm/Support/raw_ostream.h"
2223#include " llvm/Config/config.h"
2324
25+ #include < signal.h>
2426
2527#if defined(_WIN32)
2628#define WIN32_LEAN_AND_MEAN
@@ -119,7 +121,6 @@ LoadedExecutablePlugin::LoadedExecutablePlugin(
119121 outputFileDescriptor(outputFileDescriptor) {}
120122
121123LoadedExecutablePlugin::~LoadedExecutablePlugin () {
122- // Close the pipes.
123124 close (inputFileDescriptor);
124125 close (outputFileDescriptor);
125126
@@ -131,10 +132,18 @@ ssize_t LoadedExecutablePlugin::read(void *buf, size_t nbyte) const {
131132 ssize_t bytesToRead = nbyte;
132133 void *ptr = buf;
133134
135+ #if defined(SIGPIPE)
136+ // / Ignore SIGPIPE while reading.
137+ auto *old_handler = signal (SIGPIPE, SIG_IGN);
138+ SWIFT_DEFER { signal (SIGPIPE, old_handler); };
139+ #endif
140+
134141 while (bytesToRead > 0 ) {
135142 ssize_t readingSize = std::min (ssize_t (INT32_MAX), bytesToRead);
136143 ssize_t readSize = ::read (inputFileDescriptor, ptr, readingSize);
137- if (readSize == 0 ) {
144+ if (readSize <= 0 ) {
145+ // 0: EOF (the plugin exited?), -1: error (e.g. broken pipe.)
146+ // FIXME: Mark the plugin 'stale' and relaunch later.
138147 break ;
139148 }
140149 ptr = static_cast <char *>(ptr) + readSize;
@@ -148,10 +157,18 @@ ssize_t LoadedExecutablePlugin::write(const void *buf, size_t nbyte) const {
148157 ssize_t bytesToWrite = nbyte;
149158 const void *ptr = buf;
150159
160+ #if defined(SIGPIPE)
161+ // / Ignore SIGPIPE while writing.
162+ auto *old_handler = signal (SIGPIPE, SIG_IGN);
163+ SWIFT_DEFER { signal (SIGPIPE, old_handler); };
164+ #endif
165+
151166 while (bytesToWrite > 0 ) {
152167 ssize_t writingSize = std::min (ssize_t (INT32_MAX), bytesToWrite);
153168 ssize_t writtenSize = ::write (outputFileDescriptor, ptr, writingSize);
154- if (writtenSize == 0 ) {
169+ if (writtenSize <= 0 ) {
170+ // -1: error (e.g. broken pipe,)
171+ // FIXME: Mark the plugin 'stale' and relaunch later.
155172 break ;
156173 }
157174 ptr = static_cast <const char *>(ptr) + writtenSize;
@@ -170,12 +187,17 @@ llvm::Error LoadedExecutablePlugin::sendMessage(llvm::StringRef message) const {
170187 uint64_t header = llvm::support::endian::byte_swap (
171188 uint64_t (size), llvm::support::endianness::little);
172189 writtenSize = write (&header, sizeof (header));
173- assert (writtenSize == sizeof (header) &&
174- " failed to write plugin message header" );
190+ if (writtenSize != sizeof (header)) {
191+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
192+ " failed to write plugin message header" );
193+ }
175194
176195 // Write message.
177196 writtenSize = write (data, size);
178- assert (writtenSize == ssize_t (size) && " failed to write plugin message data" );
197+ if (writtenSize != ssize_t (size)) {
198+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
199+ " failed to write plugin message data" );
200+ }
179201
180202 return llvm::Error::success ();
181203}
@@ -187,8 +209,10 @@ llvm::Expected<std::string> LoadedExecutablePlugin::waitForNextMessage() const {
187209 uint64_t header;
188210 readSize = read (&header, sizeof (header));
189211
190- // FIXME: Error handling. Disconnection, etc.
191- assert (readSize == sizeof (header) && " failed to read plugin message header" );
212+ if (readSize != sizeof (header)) {
213+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
214+ " failed to read plugin message header" );
215+ }
192216
193217 size_t size = llvm::support::endian::read<uint64_t >(
194218 &header, llvm::support::endianness::little);
@@ -200,6 +224,10 @@ llvm::Expected<std::string> LoadedExecutablePlugin::waitForNextMessage() const {
200224 while (sizeToRead > 0 ) {
201225 char buffer[4096 ];
202226 readSize = read (buffer, std::min (sizeof (buffer), sizeToRead));
227+ if (readSize == 0 ) {
228+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
229+ " failed to read plugin message data" );
230+ }
203231 sizeToRead -= readSize;
204232 message.append (buffer, readSize);
205233 }
0 commit comments