From fbbc4d8dda4d347351c0667d1d9a571b201256cf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Mar 2017 14:56:33 +0100 Subject: [PATCH] Fix deadlock in runProgram() when input is larger than the pipe buffer size --- src/libutil/util.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 0a5f796e4..bc66b0c53 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -870,11 +870,14 @@ string runProgram(Path program, bool searchPath, const Strings & args, out.writeSide = -1; - /* FIXME: This can deadlock if the input is too long. */ + std::thread writerThread; + if (!input.empty()) { in.readSide = -1; - writeFull(in.writeSide.get(), input); - in.writeSide = -1; + writerThread = std::thread([&]() { + writeFull(in.writeSide.get(), input); + in.writeSide = -1; + }); } string result = drainFD(out.readSide.get()); @@ -885,6 +888,9 @@ string runProgram(Path program, bool searchPath, const Strings & args, throw ExecError(status, format("program ‘%1%’ %2%") % program % statusToString(status)); + if (!input.empty()) + writerThread.join(); + return result; }