about summary refs log tree commit diff
path: root/src/libutil/util.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2018-03-20T14·17+0100
committerEelco Dolstra <edolstra@gmail.com>2018-03-20T14·25+0100
commit1aca195e52d4fbf76908e6588b55ed8b5b25cfc8 (patch)
tree54c34371afebf63b886d3f5a9e747d5d237e0ab7 /src/libutil/util.cc
parent78d0c72b52835161fd15058b111aa05d69ce062b (diff)
Hack to get SSH error messages from build-remote
E.g.

  cannot build on 'ssh://mac1': cannot connect to 'mac1': bash: nix-store: command not found
  cannot build on 'ssh://mac2': cannot connect to 'mac2': Host key verification failed.
  cannot build on 'ssh://mac3': cannot connect to 'mac3': Received disconnect from 213... port 6001:2: Too many authentication failures
  Authentication failed.
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r--src/libutil/util.cc23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 764b4e4420..ab2d097f8b 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -567,21 +567,38 @@ void writeFull(int fd, const string & s, bool allowInterrupts)
 }
 
 
-string drainFD(int fd)
+string drainFD(int fd, bool block)
 {
     StringSink sink;
-    drainFD(fd, sink);
+    drainFD(fd, sink, block);
     return std::move(*sink.s);
 }
 
 
-void drainFD(int fd, Sink & sink)
+void drainFD(int fd, Sink & sink, bool block)
 {
+    int saved;
+
+    Finally finally([&]() {
+        if (!block) {
+            if (fcntl(fd, F_SETFL, saved) == -1)
+                throw SysError("making file descriptor blocking");
+        }
+    });
+
+    if (!block) {
+        saved = fcntl(fd, F_GETFL);
+        if (fcntl(fd, F_SETFL, saved | O_NONBLOCK) == -1)
+            throw SysError("making file descriptor non-blocking");
+    }
+
     std::vector<unsigned char> buf(4096);
     while (1) {
         checkInterrupt();
         ssize_t rd = read(fd, buf.data(), buf.size());
         if (rd == -1) {
+            if (!block && (errno == EAGAIN || errno == EWOULDBLOCK))
+                break;
             if (errno != EINTR)
                 throw SysError("reading from file");
         }