aboutsummaryrefslogtreecommitdiffstats
path: root/src/blind-tee.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2017-05-25 19:16:08 +0200
committerMattias Andrée <maandree@kth.se>2017-05-25 19:16:08 +0200
commitd5f9bf804180f50d1a025b3cf70e12238c79cfb3 (patch)
tree4d136d99570c8a80a25f6797bb3d9c55cff9b849 /src/blind-tee.c
parentFix blind-from-named (diff)
downloadblind-d5f9bf804180f50d1a025b3cf70e12238c79cfb3.tar.gz
blind-d5f9bf804180f50d1a025b3cf70e12238c79cfb3.tar.bz2
blind-d5f9bf804180f50d1a025b3cf70e12238c79cfb3.tar.xz
Add blind-tee
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--src/blind-tee.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/blind-tee.c b/src/blind-tee.c
new file mode 100644
index 0000000..9699d8c
--- /dev/null
+++ b/src/blind-tee.c
@@ -0,0 +1,52 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("[file ...]")
+
+#if !defined(PIPE_BUF)
+# define PIPE_BUF BUFSIZ
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ char buf[PIPE_BUF];
+ int *fds = alloca(argc * sizeof(*fds));
+ size_t i, n = 0, done;
+ ssize_t r, w, *ps;
+
+ UNOFLAGS(0);
+
+ fds[n++] = STDOUT_FILENO;
+ while (argc--)
+ fds[n++] = eopen(*argv++, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+
+ ps = alloca(n * sizeof(*ps));
+
+ while (n) {
+ memset(ps, 0, n * sizeof(*ps));
+ r = read(STDIN_FILENO, buf, sizeof(buf));
+ if (r < 0)
+ eprintf("read <stdin>:");
+ if (!r)
+ break;
+ for (done = 0; done < n;) {
+ for (i = 0; i < n; i++) {
+ if (ps[i] == r)
+ continue;
+ w = write(fds[i], buf + ps[i], r - ps[i]);
+ if (w < 0) {
+ close(fds[i]);
+ n--;
+ memmove(fds + i, fds + i + 1, (n - i) * sizeof(*fds));
+ memmove(ps + i, ps + i + 1, (n - i) * sizeof(*ps));
+ }
+ ps[i] += w;
+ if (ps[i] == r)
+ done++;
+ }
+ }
+ }
+
+ return 0;
+}