svn commit: r231449 - head/usr.bin/tee

Martin Cracauer cracauer at FreeBSD.org
Fri Feb 10 22:16:18 UTC 2012


Author: cracauer
Date: Fri Feb 10 22:16:17 2012
New Revision: 231449
URL: http://svn.freebsd.org/changeset/base/231449

Log:
  Fix bin/164947: tee looses data when writing to non-blocking file descriptors
  
  tee was not handling EAGAIN
  
  patch submitted by Diomidis Spinellis <dds at aueb.gr>. Thanks so much
  
  reproduced and re-tested locally

Modified:
  head/usr.bin/tee/tee.c

Modified: head/usr.bin/tee/tee.c
==============================================================================
--- head/usr.bin/tee/tee.c	Fri Feb 10 22:14:34 2012	(r231448)
+++ head/usr.bin/tee/tee.c	Fri Feb 10 22:16:17 2012	(r231449)
@@ -42,8 +42,10 @@ static const char rcsid[] =
 #endif /* not lint */
 
 #include <sys/types.h>
+#include <sys/select.h>
 #include <sys/stat.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <stdio.h>
@@ -60,6 +62,7 @@ static LIST *head;
 
 static void add(int, const char *);
 static void usage(void);
+static void waitfor(int fd);
 
 int
 main(int argc, char *argv[])
@@ -106,9 +109,14 @@ main(int argc, char *argv[])
 			bp = buf;
 			do {
 				if ((wval = write(p->fd, bp, n)) == -1) {
-					warn("%s", p->name);
-					exitval = 1;
-					break;
+					if (errno == EAGAIN) {
+						waitfor(p->fd);
+						wval = 0;
+					} else {
+						warn("%s", p->name);
+						exitval = 1;
+						break;
+					}
 				}
 				bp += wval;
 			} while (n -= wval);
@@ -137,3 +145,15 @@ add(int fd, const char *name)
 	p->next = head;
 	head = p;
 }
+
+/* Wait for the specified fd to be ready for writing */
+static void
+waitfor(int fd)
+{
+       fd_set writefds;
+
+       FD_ZERO(&writefds);
+       FD_SET(fd, &writefds);
+       if (select(fd + 1, NULL, &writefds, NULL, NULL) == -1)
+               err(1, "select");
+}


More information about the svn-src-all mailing list