summary refs log tree commit diff
path: root/filter.c
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2017-08-06 20:05:37 +0200
committerLeah Neukirchen <leah@vuxu.org>2017-08-06 20:05:37 +0200
commit13db67713f4f2f4dde8c8dfbf7b2432560ae9230 (patch)
tree2e18a30f1594f7f91564f2c2599ac6ecf89f6b74 /filter.c
parent6b5b42f5836388d467ab0c2adcca58bb2a6fb0f3 (diff)
downloadmblaze-13db67713f4f2f4dde8c8dfbf7b2432560ae9230.tar.gz
mblaze-13db67713f4f2f4dde8c8dfbf7b2432560ae9230.tar.xz
mblaze-13db67713f4f2f4dde8c8dfbf7b2432560ae9230.zip
filter: use a non-blocking write pipe
Diffstat (limited to 'filter.c')
-rw-r--r--filter.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/filter.c b/filter.c
index c0b1541..7b86106 100644
--- a/filter.c
+++ b/filter.c
@@ -1,5 +1,7 @@
 #include <sys/wait.h>
 
+#include <fcntl.h>
+#include <errno.h>
 #include <limits.h>
 #include <poll.h>	     
 #include <signal.h>
@@ -34,6 +36,10 @@ filter(char *input, size_t inlen, char *cmd, char **outputo, size_t *outleno)
 	if (pipe(pipe0) != 0 || pipe(pipe1) != 0)
 		goto fail;
 
+	int got = fcntl(pipe0[1], F_GETFL);
+	if (got > 0)
+		fcntl(pipe0[1], F_SETFL, got | O_NONBLOCK);
+
 	char *argv[] = { "/bin/sh", "-c", cmd, (char *)0 };
 
 	if (!(pid = fork())) {
@@ -85,13 +91,14 @@ filter(char *input, size_t inlen, char *cmd, char **outputo, size_t *outleno)
 		}
 		
 		if (fds[1].revents & POLLOUT) {
-			ssize_t ret = write(fds[1].fd, input,
-			    inlen > PIPE_BUF ? PIPE_BUF : inlen);
+			ssize_t ret = write(fds[1].fd, input, inlen);
 			if (ret > 0) {
 				input += ret;
 				inlen -= ret;
 			}
-			if (ret <= 0 || inlen == 0)
+			if (ret <= 0 && errno == EAGAIN) {
+				/* ignore */
+			} else if (ret <= 0 || inlen == 0)
 				close(fds[1].fd);
 		} else if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) {
 			fds[1].fd = -1;