aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2017-01-29 21:20:55 +0100
committerMattias Andrée <maandree@kth.se>2017-01-29 21:20:55 +0100
commit26837582379eed2a18350a448f51865f3cd86916 (patch)
tree0ff24b613cc8c1beb3a4bbad10db4cfda6b0721f /src
parentblind-crop: add -s and -S (diff)
downloadblind-26837582379eed2a18350a448f51865f3cd86916.tar.gz
blind-26837582379eed2a18350a448f51865f3cd86916.tar.bz2
blind-26837582379eed2a18350a448f51865f3cd86916.tar.xz
blind-repeat: add support for reading from stdin
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--src/blind-repeat.c90
1 files changed, 73 insertions, 17 deletions
diff --git a/src/blind-repeat.c b/src/blind-repeat.c
index 70b6096..82c924f 100644
--- a/src/blind-repeat.c
+++ b/src/blind-repeat.c
@@ -10,26 +10,15 @@
USAGE("(count | 'inf') file")
-int
-main(int argc, char *argv[])
+static void
+repeat_regular_file(char *file, size_t count, int inf)
{
struct stream stream;
- size_t count = 0, ptr;
- ssize_t r;
char buf[BUFSIZ];
- int inf = 0;
-
- ENOFLAGS(argc != 2);
-
- if (!strcmp(argv[0], "inf"))
- inf = 1;
- else
- count = etozu_arg("the count", argv[0], 0, SIZE_MAX);
-
- if (inf)
- einf_check_fd(STDOUT_FILENO, "<stdout>");
+ size_t ptr;
+ ssize_t r;
- stream.file = argv[1];
+ stream.file = file;
stream.fd = eopen(stream.file, O_RDONLY);
einit_stream(&stream);
if (count > SIZE_MAX / stream.frames)
@@ -51,11 +40,78 @@ main(int argc, char *argv[])
if (writeall(STDOUT_FILENO, buf, (size_t)r)) {
if (!inf || errno != EPIPE)
eprintf("write <stdout>:");
- return 0;
+ return;
}
}
}
close(stream.fd);
+}
+
+static void
+repeat_stdin(size_t count, int inf)
+{
+ struct stream stream;
+ char *buf;
+ size_t ptr, size;
+ ssize_t r;
+
+ stream.file = "<stdin>";
+ stream.fd = STDIN_FILENO;
+ einit_stream(&stream);
+ if (count > SIZE_MAX / stream.frames)
+ eprintf("%s: video is too long\n", stream.file);
+ stream.frames *= count;
+ fprint_stream_head(stdout, &stream);
+ efflush(stdout, "<stdout>");
+
+ ptr = stream.ptr;
+ size = ptr < BUFSIZ ? BUFSIZ : ptr;
+ buf = emalloc(size);
+ memcpy(buf, stream.buf, ptr);
+
+ for (;;) {
+ if (ptr == size)
+ buf = erealloc(buf, size <<= 1);
+ r = read(STDIN_FILENO, buf + ptr, size - ptr);
+ if (r < 0)
+ eprintf("read <stdout>:");
+ if (r == 0)
+ break;
+ ptr += (size_t)r;
+ }
+
+ while (inf || count--) {
+ if (writeall(STDOUT_FILENO, buf, ptr)) {
+ if (!inf || errno != EPIPE)
+ eprintf("write <stdout>:");
+ return;
+ }
+ }
+
+ free(buf);
+}
+
+int
+main(int argc, char *argv[])
+{
+ size_t count = 0;
+ int inf = 0;
+
+ ENOFLAGS(argc != 2);
+
+ if (!strcmp(argv[0], "inf"))
+ inf = 1;
+ else
+ count = etozu_arg("the count", argv[0], 0, SIZE_MAX);
+
+ if (inf)
+ einf_check_fd(STDOUT_FILENO, "<stdout>");
+
+ if (!strcmp(argv[1], "-"))
+ repeat_stdin(count, inf);
+ else
+ repeat_regular_file(argv[1], count, inf);
+
return 0;
}