commit d5f9bf804180f50d1a025b3cf70e12238c79cfb3
parent e55c9ce583efdd740da7458812d3253d9f4895ae
Author: Mattias Andrée <maandree@kth.se>
Date: Thu, 25 May 2017 19:16:08 +0200
Add blind-tee
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
7 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
@@ -35,6 +35,7 @@ BIN =\
blind-skip-pattern\
blind-split\
blind-stack\
+ blind-tee\
blind-time-blur\
blind-to-image\
blind-to-named\
diff --git a/README b/README
@@ -114,6 +114,9 @@ UTILITIES
blind-stack(1)
Overlay videos
+ blind-tee(1)
+ /dev/fd/ aware tee(1) implementation
+
blind-time-blur(1)
Draw new frames on top of old frames with partial alpha
diff --git a/man/blind-from-named.1 b/man/blind-from-named.1
@@ -58,7 +58,7 @@ input to the process, like inverse multiplexing.
.SH SEE ALSO
.BR blind (7),
.BR blind-to-named (1),
-.BR tee (1)
+.BR blind-tee (1)
.SH AUTHORS
Mattias Andrée
.RI < maandree@kth.se >
diff --git a/man/blind-tee.1 b/man/blind-tee.1
@@ -0,0 +1,28 @@
+.TH BLIND-TEE 1 blind
+.SH NAME
+blind-tee - /dev/fd/ aware tee(1) implementation
+.SH SYNOPSIS
+.B blind-tee
+.RI [ file \ ...]
+.SH DESCRIPTION
+.B blind-tee
+reads stdin and writes its input to stdout and to all
+.IR file s.
+.P
+Files are opened in truncate mode, file descriptors
+specified via their /dev/fd/ path are not reopened
+but used directly.
+.SH RATIONALE
+There are situations where opening files in /dev/fd/
+creates problems. Popular
+.BR tee (1),
+implementations do not treat files in /dev/fd/
+especially.
+.SH SEE ALSO
+.BR blind (7),
+.BR blind-to-named (1),
+.BR blind-from-named (1),
+.BR tee (1)
+.SH AUTHORS
+Mattias Andrée
+.RI < maandree@kth.se >
diff --git a/man/blind-to-named.1 b/man/blind-to-named.1
@@ -33,7 +33,7 @@ input to the process, like inverse multiplexing.
.SH SEE ALSO
.BR blind (7),
.BR blind-from-named (1),
-.BR tee (1)
+.BR blind-tee (1)
.SH AUTHORS
Mattias Andrée
.RI < maandree@kth.se >
diff --git a/man/blind.7 b/man/blind.7
@@ -127,6 +127,11 @@ Split a video, by frame, into multiple videos
.BR blind-stack (1)
Overlay videos
.TP
+.BR blind-tee (1)
+/dev/fd/ aware
+.BR tee (1)
+implementation
+.TP
.BR blind-time-blur (1)
Draw new frames on top of old frames with partial alpha
.TP
diff --git a/src/blind-tee.c 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;
+}