blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | LICENSE

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:
MMakefile | 1+
MREADME | 3+++
Mman/blind-from-named.1 | 2+-
Aman/blind-tee.1 | 28++++++++++++++++++++++++++++
Mman/blind-to-named.1 | 2+-
Mman/blind.7 | 5+++++
Asrc/blind-tee.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
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; +}