@@ -208,21 +208,27 @@ internal struct PluginHostConnection: MessageConnection {
208
208
func waitForNextMessage< RX: Decodable > ( _ ty: RX . Type ) throws -> RX ? {
209
209
// Read the header (a 64-bit length field in little endian byte order).
210
210
let count = try _reading ( inputStream, count: 8 ) { buffer in
211
- UInt64 ( littleEndian: buffer. loadUnaligned ( as: UInt64 . self) )
211
+ return buffer . count == 8 ? UInt64 ( littleEndian: buffer. loadUnaligned ( as: UInt64 . self) ) : 0
212
212
}
213
213
guard count >= 2 else {
214
+ if count == 0 {
215
+ // input stream is closed.
216
+ return nil
217
+ }
214
218
throw PluginMessageError . invalidPayloadSize
215
219
}
216
220
217
221
// Read the JSON payload.
218
- return try _reading ( inputStream, count: Int ( count) ) { buffer in
222
+ return try _reading ( inputStream, count: Int ( count) ) { buffer -> RX in
223
+ if buffer. count != Int ( count) {
224
+ throw PluginMessageError . truncatedPayload
225
+ }
219
226
// Decode and return the message.
220
- try JSON . decode ( RX . self, from: buffer. bindMemory ( to: UInt8 . self) )
227
+ return try JSON . decode ( RX . self, from: buffer. bindMemory ( to: UInt8 . self) )
221
228
}
222
229
}
223
230
224
231
enum PluginMessageError : Swift . Error {
225
- case truncatedHeader
226
232
case invalidPayloadSize
227
233
case truncatedPayload
228
234
}
@@ -257,7 +263,8 @@ func _reading<T>(_ fd: CInt, count: Int, _ fn: (UnsafeRawBufferPointer) throws -
257
263
while remaining > 0 {
258
264
switch read ( fd, ptr, remaining) {
259
265
case 0 :
260
- throw CompilerPluginError ( message: " read(2) closed " )
266
+ // Input is closed.
267
+ return try fn ( UnsafeRawBufferPointer ( start: nil , count: 0 ) )
261
268
case - 1 :
262
269
let err = String ( cString: strerror ( errno) )
263
270
throw CompilerPluginError ( message: " read(2) failed: \( err) " )
0 commit comments