On Fri, May 18, 2012 at 04:58:38PM +0200, Jann Horn wrote:
> Hello,
> what would you think about letting "tee" exit immediately when the output 
> pipe was closed? It
> should be pretty straightforward to implement using select/epoll, right?
> 
>  -- Jann

Here's a patch that works for me.
From 7e86dabc0a88f2f69ea54a373fb6dba4b3e4cbdd Mon Sep 17 00:00:00 2001
From: Jann Horn <[email protected]>
Date: Fri, 18 May 2012 20:52:55 +0200
Subject: [PATCH] tee: use poll() to exit immediately when an output closes

---
 src/tee.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/src/tee.c b/src/tee.c
index 2d82577..a45002e 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 #include <signal.h>
 #include <getopt.h>
+#include <poll.h>
 
 #include "system.h"
 #include "error.h"
@@ -179,8 +180,25 @@ tee_files (int nfiles, const char **files)
         setvbuf (descriptors[i], NULL, _IONBF, 0);
     }
 
+  struct pollfd pollfds[nfiles + 2];
+  for (i = 0; i <= nfiles; i++)
+    {
+      pollfds[i].fd = fileno(descriptors[i]);
+      pollfds[i].events = POLLERR | POLLHUP | POLLNVAL;
+    }
+  pollfds[i].fd = 0;
+  pollfds[i].events = POLLIN;
+
   while (1)
     {
+      poll(pollfds, nfiles + 2, -1);
+      if ((pollfds[nfiles + 1].revents & POLLIN) == 0)
+        {
+          /* If there's no incoming data, it means
+             an output was closed or so. */
+          exit(141);
+        }
+
       bytes_read = read (0, buffer, sizeof buffer);
       if (bytes_read < 0 && errno == EINTR)
         continue;
-- 
1.7.6.5

Attachment: pgpp6hbo7FXHZ.pgp
Description: PGP signature

Reply via email to