summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorcracauer <cracauer@FreeBSD.org>2012-02-10 22:16:17 +0000
committercracauer <cracauer@FreeBSD.org>2012-02-10 22:16:17 +0000
commite278c3bff09ee6207fa5f822cd64ede7b6083189 (patch)
tree4a532a5243c9df623882b873cda0cbe54b6385df /usr.bin
parent290f0204ae95d6dc92ba9c15fafe090e9d4338af (diff)
downloadFreeBSD-src-e278c3bff09ee6207fa5f822cd64ede7b6083189.zip
FreeBSD-src-e278c3bff09ee6207fa5f822cd64ede7b6083189.tar.gz
Fix bin/164947: tee looses data when writing to non-blocking file descriptors
tee was not handling EAGAIN patch submitted by Diomidis Spinellis <dds@aueb.gr>. Thanks so much reproduced and re-tested locally
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/tee/tee.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/usr.bin/tee/tee.c b/usr.bin/tee/tee.c
index 6b5c00c..61d7f76 100644
--- a/usr.bin/tee/tee.c
+++ b/usr.bin/tee/tee.c
@@ -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");
+}
OpenPOWER on IntegriCloud