From ea37ac04f4e4e9248fb361d65a3cd69f57bcaba1 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 19 Mar 2015 23:33:52 +0100 Subject: [PATCH] src: ignore ENOTCONN on shutdown race with child On AIX, OS X and the BSDs, calling shutdown() on one end of a pipe when the other end has closed the connection fails with ENOTCONN. The sequential/test-child-process-execsync test failed sporadically because of a race between the parent and the child where one closed its end of the pipe before the other got around to calling shutdown() on its end of the pipe. Libuv is not the right place to handle that because it can't tell if the ENOTCONN error is genuine but io.js can. Refs: https://github.com/libuv/libuv/pull/268 PR-URL: https://github.com/iojs/io.js/pull/1214 Reviewed-By: Bert Belder --- src/spawn_sync.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/spawn_sync.cc b/src/spawn_sync.cc index 8b0271f3d1ecfb..b014bae40dffc9 100644 --- a/src/spawn_sync.cc +++ b/src/spawn_sync.cc @@ -321,6 +321,14 @@ void SyncProcessStdioPipe::WriteCallback(uv_write_t* req, int result) { void SyncProcessStdioPipe::ShutdownCallback(uv_shutdown_t* req, int result) { SyncProcessStdioPipe* self = reinterpret_cast(req->handle->data); + + // On AIX, OS X and the BSDs, calling shutdown() on one end of a pipe + // when the other end has closed the connection fails with ENOTCONN. + // Libuv is not the right place to handle that because it can't tell + // if the error is genuine but we here can. + if (result == UV_ENOTCONN) + result = 0; + self->OnShutdownDone(result); }