diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2017-03-13T13·56+0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2017-03-15T15·49+0100 |
commit | fbbc4d8dda4d347351c0667d1d9a571b201256cf (patch) | |
tree | 7d4d752e408708d04d92ff19b7191b491c2a8933 | |
parent | e8186085e07104d4b844208613c2d704b5b57dec (diff) |
Fix deadlock in runProgram() when input is larger than the pipe buffer size
-rw-r--r-- | src/libutil/util.cc | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 0a5f796e4eaa..bc66b0c53223 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; } |