(wrong string) ée

From: <git_AT_suckless.org>
Date: Sun, 9 Apr 2017 23:53:57 +0200 (CEST)

commit dac6950d9e556d5521ad7913d27a6cf83e2a90a1
Author: Mattias Andrée <maandree_AT_kth.se>
AuthorDate: Sun Apr 9 23:46:17 2017 +0200
Commit: Mattias Andrée <maandree_AT_kth.se>
CommitDate: Sun Apr 9 23:46:17 2017 +0200

    Clean up
    
    Signed-off-by: Mattias Andrée <maandree_AT_kth.se>

diff --git a/Makefile b/Makefile
index 377adb9..3bdd7cd 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -61,6 +61,7 @@ HDR =\
         util/colour.h\
         util/io.h\
         util/efflush.h\
+ util/efunc.h\
         util/eprintf.h\
         util/fshut.h
 
diff --git a/man/blind-reverse.1 b/man/blind-reverse.1
index 3b2ad69..c36758c 100644
--- a/man/blind-reverse.1
+++ b/man/blind-reverse.1
_AT_@ -17,6 +17,12 @@ must be a regular file.
 .B -i
 Reverse the file in place rather than printing
 it to stdout.
+.SH REQUIREMENTS
+.B blind-reverse
+requires enough free memory to load two full frames into
+memory if
+.B -i
+is used. A frame requires 32 bytes per pixel it contains.
 .SH SEE ALSO
 .BR blind (7),
 .BR blind-split (1),
diff --git a/src/blind-arithm.c b/src/blind-arithm.c
index 613783e..e8c1f95 100644
--- a/src/blind-arithm.c
+++ b/src/blind-arithm.c
_AT_@ -83,13 +83,8 @@ main(int argc, char *argv[])
         if (argc != 2)
                 usage();
 
- left.file = "<stdin>";
- left.fd = STDIN_FILENO;
- einit_stream(&left);
-
- right.file = argv[1];
- right.fd = eopen(right.file, O_RDONLY);
- einit_stream(&right);
+ eopen_stream(&left, NULL);
+ eopen_stream(&right, argv[1]);
 
         if (!strcmp(left.pixfmt, "xyza"))
                 process = get_lf_process(argv[0]);
diff --git a/src/blind-colour-ciexyz.c b/src/blind-colour-ciexyz.c
index 018ef54..5be6068 100644
--- a/src/blind-colour-ciexyz.c
+++ b/src/blind-colour-ciexyz.c
_AT_@ -6,10 +6,7 @@ USAGE("(X Y Z | Y)")
 int
 main(int argc, char *argv[])
 {
- ARGBEGIN {
- default:
- usage();
- } ARGEND;
+ UNOFLAGS(0);
 
         if (argc == 1)
                 printf("%s\n", argv[0]);
diff --git a/src/blind-colour-srgb.c b/src/blind-colour-srgb.c
index 5e6c0db..26ff59b 100644
--- a/src/blind-colour-srgb.c
+++ b/src/blind-colour-srgb.c
_AT_@ -37,7 +37,6 @@ main(int argc, char *argv[])
 
         srgb_to_ciexyz(red, green, blue, &X, &Y, &Z);
         printf("%lf %lf %lf\n", X, Y, Z);
-
         efshut(stdout, "<stdout>");
         return 0;
 }
diff --git a/src/blind-compress.c b/src/blind-compress.c
index 7d41f23..7669227 100644
--- a/src/blind-compress.c
+++ b/src/blind-compress.c
_AT_@ -40,9 +40,7 @@ main(int argc, char *argv[])
 
         UNOFLAGS(argc);
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
         fprint_stream_head(stdout, &stream);
         efflush(stdout, "<stdout>");
 
diff --git a/src/blind-concat.c b/src/blind-concat.c
index f59bee5..53707e7 100644
--- a/src/blind-concat.c
+++ b/src/blind-concat.c
_AT_@ -7,7 +7,6 @@
 #endif
 #include <sys/mman.h>
 #include <errno.h>
-#include <fcntl.h>
 #include <inttypes.h>
 #include <limits.h>
 #include <string.h>
_AT_@ -25,9 +24,7 @@ concat_to_stdout(int argc, char *argv[], const char *fname)
         streams = emalloc((size_t)argc * sizeof(*streams));
 
         for (i = 0; i < argc; i++) {
- streams[i].file = argv[i];
- streams[i].fd = eopen(streams[i].file, O_RDONLY);
- einit_stream(streams + i);
+ eopen_stream(streams + i, argv[i]);
                 if (i)
                         echeck_compat(streams + i, streams);
                 if (streams[i].frames > SIZE_MAX - frames)
_AT_@ -40,8 +37,10 @@ concat_to_stdout(int argc, char *argv[], const char *fname)
         efflush(stdout, fname);
 
         for (i = 0; i < argc; i++) {
- for (; eread_stream(streams + i, SIZE_MAX); streams[i].ptr = 0)
+ do {
                         ewriteall(STDOUT_FILENO, streams[i].buf, streams[i].ptr, fname);
+ streams[i].ptr = 0;
+ } while (eread_stream(streams + i, SIZE_MAX));
                 close(streams[i].fd);
         }
 
_AT_@ -59,9 +58,7 @@ concat_to_file(int argc, char *argv[], char *output_file)
         char *data;
 
         for (; argc--; argv++) {
- stream.file = *argv;
- stream.fd = eopen(stream.file, O_RDONLY);
- einit_stream(&stream);
+ eopen_stream(&stream, *argv);
 
                 if (first) {
                         refstream = stream;
_AT_@ -73,10 +70,11 @@ concat_to_file(int argc, char *argv[], char *output_file)
                         echeck_compat(&stream, &refstream);
                 }
 
- for (; eread_stream(&stream, SIZE_MAX); stream.ptr = 0) {
+ do {
                         ewriteall(fd, stream.buf, stream.ptr, output_file);
                         size += stream.ptr;
- }
+ stream.ptr = 0;
+ } while (eread_stream(&stream, SIZE_MAX));
                 close(stream.fd);
         }
 
_AT_@ -98,8 +96,8 @@ concat_to_file_parallel(int argc, char *argv[], char *output_file, size_t jobs)
 {
 #if !defined(HAVE_EPOLL)
         int fd = eopen(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (fd != STDOUT_FILENO && dup2(fd, STDOUT_FILENO) == -1)
- eprintf("dup2:");
+ if (fd != STDOUT_FILENO)
+ edup2(fd, STDOUT_FILENO);
         concat_to_stdout(argc, argv, output_file);
 #else
         struct epoll_event *events;
_AT_@ -119,9 +117,7 @@ concat_to_file_parallel(int argc, char *argv[], char *output_file, size_t jobs)
         ptrs = emalloc((size_t)argc * sizeof(*ptrs));
 
         for (i = 0; i < argc; i++) {
- streams[i].file = argv[i];
- streams[i].fd = eopen(streams[i].file, O_RDONLY);
- einit_stream(streams + i);
+ eopen_stream(streams + i, argv[i]);
                 if (i)
                         echeck_compat(streams + i, streams);
                 if (streams[i].frames > SIZE_MAX - frames)
_AT_@ -140,9 +136,7 @@ concat_to_file_parallel(int argc, char *argv[], char *output_file, size_t jobs)
         }
         if (ftruncate(fd, (off_t)ptr))
                 eprintf("ftruncate %s:", output_file);
-#if defined(POSIX_FADV_RANDOM)
- posix_fadvise(fd, (size_t)headlen, 0, POSIX_FADV_RANDOM);
-#endif
+ fadvise_random(fd, (size_t)headlen, 0);
 
         pollfd = epoll_create1(0);
         if (pollfd == -1)
_AT_@ -158,7 +152,7 @@ concat_to_file_parallel(int argc, char *argv[], char *output_file, size_t jobs)
         for (j = 0; j < jobs; j++, next++) {
                 events->events = EPOLLIN;
                 events->data.u64 = next;
- if (epoll_ctl(pollfd, EPOLL_CTL_ADD, streams[next].fd, events) == -1) {
+ if (epoll_ctl(pollfd, EPOLL_CTL_ADD, streams[next].fd, events)) {
                         if ((errno == ENOMEM || errno == ENOSPC) && j)
                                 break;
                         eprintf("epoll_ctl:");
_AT_@ -172,24 +166,25 @@ concat_to_file_parallel(int argc, char *argv[], char *output_file, size_t jobs)
                         eprintf("epoll_wait:");
                 for (i = 0; i < n; i++) {
                         j = events[i].data.u64;
- if (!eread_stream(streams + j, SIZE_MAX)) {
- close(streams[j].fd);
- if (next < (size_t)argc) {
- events->events = EPOLLIN;
- events->data.u64 = next;
- if (epoll_ctl(pollfd, EPOLL_CTL_ADD, streams[next].fd, events) == -1) {
- if ((errno == ENOMEM || errno == ENOSPC) && j)
- break;
- eprintf("epoll_ctl:");
- }
- next++;
- } else {
- jobs--;
- }
- } else {
+ if (streams[j].ptr || eread_stream(streams + j, SIZE_MAX)) {
                                 epwriteall(fd, streams[j].buf, streams[j].ptr, ptrs[j], output_file);
                                 ptrs[j] += streams[j].ptr;
                                 streams[j].ptr = 0;
+ continue;
+ }
+
+ close(streams[j].fd);
+ if (next < (size_t)argc) {
+ events->events = EPOLLIN;
+ events->data.u64 = next;
+ if (epoll_ctl(pollfd, EPOLL_CTL_ADD, streams[next].fd, events)) {
+ if ((errno == ENOMEM || errno == ENOSPC) && j)
+ break;
+ eprintf("epoll_ctl:");
+ }
+ next++;
+ } else {
+ jobs--;
                         }
                 }
         }
diff --git a/src/blind-crop.c b/src/blind-crop.c
index fa76762..1ad9a19 100644
--- a/src/blind-crop.c
+++ b/src/blind-crop.c
_AT_@ -41,9 +41,7 @@ main(int argc, char *argv[])
         left = etozu_arg("the left position", argv[2], 0, SIZE_MAX);
         top = etozu_arg("the top position", argv[3], 0, SIZE_MAX);
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
         if (left > SIZE_MAX - width || left + width > stream.width ||
             top > SIZE_MAX - height || top + height > stream.height)
                 eprintf("crop area extends beyond original image\n");
_AT_@ -72,10 +70,8 @@ main(int argc, char *argv[])
                 off = (orown - left % orown) % orown;
                 yoff = (height - top % height) % height;
         }
- bottom_start = top + height;
- bottom = stream.height - bottom_start;
- right_start = left + orown;
- right = irown - right_start;
+ bottom = stream.height - (bottom_start = top + height);
+ right = irown - (right_start = left + orown);
 
         while (eread_frame(&stream, buf, n)) {
                 if (tile) {
diff --git a/src/blind-cut.c b/src/blind-cut.c
index d9efacf..9f4357c 100644
--- a/src/blind-cut.c
+++ b/src/blind-cut.c
_AT_@ -2,7 +2,6 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
 #include <limits.h>
 #include <stdint.h>
 #include <string.h>
_AT_@ -31,9 +30,7 @@ main(int argc, char *argv[])
         else
                 end = etozu_arg("the end point", argv[1], 0, SIZE_MAX);
 
- stream.file = argv[2];
- stream.fd = eopen(stream.file, O_RDONLY);
- einit_stream(&stream);
+ eopen_stream(&stream, argv[2]);
         if (to_end)
                 end = stream.frames;
         else if (end > stream.frames)
_AT_@ -53,16 +50,11 @@ main(int argc, char *argv[])
         end = end * frame_size + stream.headlen;
         start = start * frame_size + stream.headlen;
 
-#if defined(POSIX_FADV_SEQUENTIAL)
- posix_fadvise(stream.fd, start, end - start, POSIX_FADV_SEQUENTIAL);
-#endif
+ fadvise_sequential(stream.fd, start, end - start);
         for (ptr = start; ptr < end; ptr += (size_t)r) {
                 max = end - ptr;
                 max = MIN(max, sizeof(buf));
- r = pread(stream.fd, buf, max, ptr);
- if (r < 0)
- eprintf("pread %s:", stream.file);
- if (r == 0)
+ if (!(r = epread(stream.fd, buf, max, ptr, stream.file)))
                         eprintf("%s: file is shorter than expected\n", stream.file);
                 ewriteall(STDOUT_FILENO, buf, (size_t)r, "<stdout>");
         }
diff --git a/src/blind-decompress.c b/src/blind-decompress.c
index 6636ee0..fd436f6 100644
--- a/src/blind-decompress.c
+++ b/src/blind-decompress.c
_AT_@ -16,9 +16,7 @@ main(int argc, char *argv[])
 
         UNOFLAGS(argc);
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
         fprint_stream_head(stdout, &stream);
         efflush(stdout, "<stdout>");
 
diff --git a/src/blind-dissolve.c b/src/blind-dissolve.c
index 980d6a6..719cd28 100644
--- a/src/blind-dissolve.c
+++ b/src/blind-dissolve.c
_AT_@ -52,9 +52,7 @@ main(int argc, char *argv[])
         if (argc)
                 usage();
 
- stream.fd = STDIN_FILENO;
- stream.file = "<stdin>";
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
 
         if (!strcmp(stream.pixfmt, "xyza"))
                 process = reverse ? process_xyza_r : process_xyza;
_AT_@ -65,6 +63,5 @@ main(int argc, char *argv[])
         efflush(stdout, "<stdout>");
         fmd = fm = stream.frames - 1;
         process_each_frame_segmented(&stream, STDOUT_FILENO, "<stdout>", process);
-
         return 0;
 }
diff --git a/src/blind-extend.c b/src/blind-extend.c
index 8b9e638..25b9e30 100644
--- a/src/blind-extend.c
+++ b/src/blind-extend.c
_AT_@ -42,9 +42,7 @@ main(int argc, char *argv[])
         if (argc)
                 usage();
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
 
         echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, stream.file);
         n = stream.height * stream.width * stream.pixel_size;
diff --git a/src/blind-flip.c b/src/blind-flip.c
index 3dd108d..18914ae 100644
--- a/src/blind-flip.c
+++ b/src/blind-flip.c
_AT_@ -16,9 +16,7 @@ main(int argc, char *argv[])
 
         UNOFLAGS(argc);
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
         fprint_stream_head(stdout, &stream);
         efflush(stdout, "<stdout>");
 
diff --git a/src/blind-flop.c b/src/blind-flop.c
index 39370a5..3401f7d 100644
--- a/src/blind-flop.c
+++ b/src/blind-flop.c
_AT_@ -17,14 +17,11 @@ main(int argc, char *argv[])
 
         UNOFLAGS(argc);
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
         fprint_stream_head(stdout, &stream);
         efflush(stdout, "<stdout>");
 
- if (stream.width > SIZE_MAX / stream.pixel_size)
- eprintf("<stdin>: video frame is too wide\n");
+ echeck_frame_size(stream.width, 1, stream.pixel_size, 0, stream.file);
         n = stream.width * stream.pixel_size;
         buf = emalloc(n);
         image = emalloc(n);
diff --git a/src/blind-from-image.c b/src/blind-from-image.c
index 83ed801..040e8a9 100644
--- a/src/blind-from-image.c
+++ b/src/blind-from-image.c
_AT_@ -102,10 +102,7 @@ pam_head(int fd, const char *fname)
         char *p;
         unsigned long long int maxval = UINT8_MAX;
         for (ptr = 0;;) {
- r = read(fd, buf + ptr, sizeof(buf) - 1);
- if (r < 0)
- eprintf("read %s:", fname);
- if (r == 0)
+ if (!(r = eread(fd, buf + ptr, sizeof(buf) - 1, fname)))
                         eprintf("%s\n", conv_fail_msg);
                 ptr += (size_t)r;
                 for (;;) {
_AT_@ -214,33 +211,25 @@ main(int argc, char *argv[])
                 goto after_fork;
         }
 
- if (pipe(pipe_rw))
- eprintf("pipe:");
+ epipe(pipe_rw);
         if (pipe_rw[0] == STDIN_FILENO || pipe_rw[1] == STDIN_FILENO)
                 eprintf("no stdin open\n");
         if (pipe_rw[0] == STDOUT_FILENO || pipe_rw[1] == STDOUT_FILENO)
                 eprintf("no stdout open\n");
         for (i = 0; i < 2; i++) {
                 if (pipe_rw[i] == STDERR_FILENO) {
- pipe_rw[i] = dup(old_fd = pipe_rw[i]);
- if (pipe_rw[i] < 0)
- eprintf("dup:");
+ pipe_rw[i] = edup(old_fd = pipe_rw[i]);
                         close(old_fd);
                 }
         }
 
- pid = fork();
- if (pid < 0)
- eprintf("fork:");
-
+ pid = efork();
         if (!pid) {
                 close(pipe_rw[0]);
- if (dup2(pipe_rw[1], STDOUT_FILENO) == -1)
- eprintf("dup2:");
+ edup2(pipe_rw[1], STDOUT_FILENO);
                 close(pipe_rw[1]);
                 /* XXX Is there a way to convert directly to raw XYZ? (Would avoid gamut truncation) */
- execlp("convert", "convert", "-", "-depth", "32", "-alpha", "activate", "pam:-", NULL);
- eprintf("exec convert:");
+ eexeclp("convert", "convert", "-", "-depth", "32", "-alpha", "activate", "pam:-", NULL);
         }
 
         close(pipe_rw[1]);
diff --git a/src/blind-from-video.c b/src/blind-from-video.c
index 7f3aa13..d34e2aa 100644
--- a/src/blind-from-video.c
+++ b/src/blind-from-video.c
_AT_@ -2,17 +2,12 @@
 #include "stream.h"
 #include "util.h"
 
-#if defined(HAVE_PRCTL)
-# include <sys/prctl.h>
-#endif
 #include <sys/mman.h>
 #include <sys/stat.h>
-#include <sys/wait.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-r frame-rate] [-w width -h height] [-dL] input-file output-file")
 
_AT_@ -55,28 +50,19 @@ get_metadata(char *file, size_t *width, size_t *height)
         pid_t pid;
         int status;
 
- if (pipe(pipe_rw))
- eprintf("pipe:");
-
- pid = fork();
- if (pid == -1)
- eprintf("fork:");
+ epipe(pipe_rw);
+ pid = efork();
 
         if (!pid) {
-#if defined(HAVE_PRCTL) && defined(PR_SET_PDEATHSIG)
- prctl(PR_SET_PDEATHSIG, SIGKILL);
-#endif
+ pdeath(SIGKILL);
                 fd = eopen(file, O_RDONLY);
- if (dup2(fd, STDIN_FILENO) == -1)
- eprintf("dup2:");
+ edup2(fd, STDIN_FILENO);
                 close(fd);
                 close(pipe_rw[0]);
- if (dup2(pipe_rw[1], STDOUT_FILENO) == -1)
- eprintf("dup2:");
+ edup2(pipe_rw[1], STDOUT_FILENO);
                 close(pipe_rw[1]);
- execlp("ffprobe", "ffprobe", "-v", "quiet", "-show_streams",
- "-select_streams", "v", "-", NULL);
- eprintf("exec ffprobe:");
+ eexeclp("ffprobe", "ffprobe", "-v", "quiet", "-show_streams",
+ "-select_streams", "v", "-", NULL);
         }
 
         close(pipe_rw[1]);
_AT_@ -87,8 +73,7 @@ get_metadata(char *file, size_t *width, size_t *height)
         fclose(fp);
         close(pipe_rw[0]);
 
- if (waitpid(pid, &status, 0) == -1)
- eprintf("waitpid:");
+ ewaitpid(pid, &status, 0);
         if (status)
                 exit(1);
 }
_AT_@ -157,32 +142,21 @@ convert(const char *infile, int outfd, const char *outfile, size_t width, size_t
         cmd[i++] = "-";
         cmd[i++] = NULL;
 
- if (pipe(pipe_rw))
- eprintf("pipe:");
-
- pid = fork();
- if (pid == -1)
- eprintf("fork:");
+ epipe(pipe_rw);
+ pid = efork();
 
         if (!pid) {
-#if defined(HAVE_PRCTL) && defined(PR_SET_PDEATHSIG)
- prctl(PR_SET_PDEATHSIG, SIGKILL);
-#endif
+ pdeath(SIGKILL);
                 close(pipe_rw[0]);
- if (dup2(pipe_rw[1], STDOUT_FILENO) == -1)
- eprintf("dup2:");
+ edup2(pipe_rw[1], STDOUT_FILENO);
                 close(pipe_rw[1]);
- execvp("ffmpeg", (char **)(void *)cmd);
- eprintf("exec ffmpeg:");
+ eexecvp("ffmpeg", (char **)(void *)cmd);
         }
 
         close(pipe_rw[1]);
 
         for (ptr = 0;;) {
- r = read(pipe_rw[0], buf + ptr, sizeof(buf) - ptr);
- if (r < 0)
- eprintf("read <subprocess>:");
- if (r == 0)
+ if (!(r = eread(pipe_rw[0], buf + ptr, sizeof(buf) - ptr, "<subprocess>")))
                         break;
                 ptr += (size_t)r;
                 n = ptr - (ptr % 8);
_AT_@ -193,8 +167,7 @@ convert(const char *infile, int outfd, const char *outfile, size_t width, size_t
                 eprintf("<subprocess>: incomplete frame\n");
 
         close(pipe_rw[0]);
- if (waitpid(pid, &status, 0) == -1)
- eprintf("waitpid:");
+ ewaitpid(pid, &status, 0);
         if (status)
                 exit(1);
 }
diff --git a/src/blind-gauss-blur.c b/src/blind-gauss-blur.c
index 542b44b..2dc6d08 100644
--- a/src/blind-gauss-blur.c
+++ b/src/blind-gauss-blur.c
_AT_@ -336,13 +336,8 @@ main(int argc, char *argv[])
         if (!vertical && !horizontal)
                 vertical = horizontal = 1;
 
- colour.file = "<stdin>";
- colour.fd = STDIN_FILENO;
- einit_stream(&colour);
-
- sigma.file = argv[0];
- sigma.fd = eopen(sigma.file, O_RDONLY);
- einit_stream(&sigma);
+ eopen_stream(&colour, NULL);
+ eopen_stream(&sigma, argv[0]);
 
         if (!strcmp(colour.pixfmt, "xyza"))
                 process = process_xyza;
diff --git a/src/blind-invert-luma.c b/src/blind-invert-luma.c
index c83b8dc..b876967 100644
--- a/src/blind-invert-luma.c
+++ b/src/blind-invert-luma.c
_AT_@ -108,13 +108,8 @@ main(int argc, char *argv[])
         if (argc != 1)
                 usage();
 
- colour.file = "<stdin>";
- colour.fd = STDIN_FILENO;
- einit_stream(&colour);
-
- mask.file = argv[0];
- mask.fd = eopen(mask.file, O_RDONLY);
- einit_stream(&mask);
+ eopen_stream(&colour, NULL);
+ eopen_stream(&mask, argv[0]);
 
         if (!strcmp(colour.pixfmt, "xyza"))
                 process = invert ? whitepoint ? process_xyza_iw : process_xyza_i
diff --git a/src/blind-read-head.c b/src/blind-read-head.c
index c31e2b0..00b6d61 100644
--- a/src/blind-read-head.c
+++ b/src/blind-read-head.c
_AT_@ -14,15 +14,11 @@ main(int argc, char *argv[])
         char magic[] = {'\0', 'u', 'i', 'v', 'f'};
         char b, *p;
         size_t i, ptr;
- ssize_t r;
 
         UNOFLAGS(argc);
 
         for (ptr = 0; ptr < sizeof(buf);) {
- r = read(STDIN_FILENO, buf + ptr, 1);
- if (r < 0)
- eprintf("read <stdin>:");
- if (r == 0)
+ if (!eread(STDIN_FILENO, buf + ptr, 1, "<stdin>"))
                         goto bad_format;
                 if (buf[ptr++] == '\n')
                         break;
_AT_@ -31,13 +27,9 @@ main(int argc, char *argv[])
                 goto bad_format;
 
         p = buf;
- for (i = 0; i < 5; i++) {
- r = read(STDIN_FILENO, &b, 1);
- if (r < 0)
- eprintf("read <stdin>:");
- if (r == 0 || b != magic[i])
+ for (i = 0; i < 5; i++)
+ if (!eread(STDIN_FILENO, &b, 1, "<stdin>") || b != magic[i])
                         goto bad_format;
- }
 
         for (i = 0; i < 3; i++) {
                 if (!isdigit(*p))
diff --git a/src/blind-repeat.c b/src/blind-repeat.c
index 29089c6..937536b 100644
--- a/src/blind-repeat.c
+++ b/src/blind-repeat.c
_AT_@ -3,7 +3,6 @@
 #include "util.h"
 
 #include <errno.h>
-#include <fcntl.h>
 #include <stdint.h>
 #include <string.h>
 #include <unistd.h>
_AT_@ -18,9 +17,7 @@ repeat_regular_file(char *file, size_t count, int inf)
         size_t ptr;
         ssize_t r;
 
- stream.file = file;
- stream.fd = eopen(stream.file, O_RDONLY);
- einit_stream(&stream);
+ eopen_stream(&stream, file);
         if (count > SIZE_MAX / stream.frames)
                 eprintf("%s: video is too long\n", stream.file);
         stream.frames *= count;
_AT_@ -28,14 +25,9 @@ repeat_regular_file(char *file, size_t count, int inf)
         efflush(stdout, "<stdout>");
 
         while (inf || count--) {
-#if defined(POSIX_FADV_SEQUENTIAL)
- posix_fadvise(stream.fd, stream.headlen, 0, POSIX_FADV_SEQUENTIAL);
-#endif
+ fadvise_sequential(stream.fd, stream.headlen, 0);
                 for (ptr = stream.headlen;; ptr += (size_t)r) {
- r = pread(stream.fd, buf, sizeof(buf), ptr);
- if (r < 0)
- eprintf("pread %s:", stream.file);
- if (r == 0)
+ if (!(r = epread(stream.fd, buf, sizeof(buf), ptr, stream.file)))
                                 break;
                         if (writeall(STDOUT_FILENO, buf, (size_t)r)) {
                                 if (!inf || errno != EPIPE)
_AT_@ -56,9 +48,7 @@ repeat_stdin(size_t count, int inf)
         size_t ptr, size;
         ssize_t r;
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
         if (count > SIZE_MAX / stream.frames)
                 eprintf("%s: video is too long\n", stream.file);
         stream.frames *= count;
_AT_@ -66,17 +56,14 @@ repeat_stdin(size_t count, int inf)
         efflush(stdout, "<stdout>");
 
         ptr = stream.ptr;
- size = ptr < BUFSIZ ? BUFSIZ : ptr;
+ size = MAX(ptr, BUFSIZ);
         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)
+ if (!(r = eread(STDIN_FILENO, buf + ptr, size - ptr, "<stdout>")))
                         break;
                 ptr += (size_t)r;
         }
diff --git a/src/blind-reverse.c b/src/blind-reverse.c
index 519fcf7..0bbe766 100644
--- a/src/blind-reverse.c
+++ b/src/blind-reverse.c
_AT_@ -18,10 +18,7 @@ to_stdout(struct stream *stream, size_t frame_size)
                 ptr = stream->frames * frame_size + stream->headlen;
                 end = ptr + frame_size;
                 while (ptr < end) {
- r = pread(stream->fd, buf, sizeof(buf), ptr);
- if (r < 0)
- eprintf("pread %s:", stream->file);
- else if (r == 0)
+ if (!(r = epread(stream->fd, buf, sizeof(buf), ptr, stream->file)))
                                 eprintf("%s: file is shorter than expected\n", stream->file);
                         ptr += n = (size_t)r;
                         ewriteall(STDOUT_FILENO, buf, n, "<stdout>");
_AT_@ -32,9 +29,7 @@ to_stdout(struct stream *stream, size_t frame_size)
 static void
 elseek_set(int fd, off_t offset, const char *fname)
 {
- off_t r = lseek(fd, offset, SEEK_SET);
- if (r < 0)
- eprintf("lseek %s:", fname);
+ off_t r = elseek(fd, offset, SEEK_SET, fname);
         if (r != offset)
                 eprintf("%s: file is shorter than expected\n", fname);
 }
_AT_@ -92,20 +87,15 @@ main(int argc, char *argv[])
         }
         echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, stream.file);
         frame_size = stream.width * stream.height * stream.pixel_size;
- if (stream.frames > (size_t)SSIZE_MAX / frame_size)
- eprintf("%s: video is too large\n", stream.file);
- if (stream.frames * frame_size > (size_t)SSIZE_MAX - stream.headlen)
+ if (stream.frames > (size_t)SSIZE_MAX / frame_size ||
+ stream.frames * frame_size > (size_t)SSIZE_MAX - stream.headlen)
                 eprintf("%s: video is too large\n", stream.file);
 
 #if defined(POSIX_FADV_RANDOM)
         posix_fadvise(stream.fd, 0, 0, POSIX_FADV_RANDOM);
 #endif
 
- if (inplace)
- in_place(&stream, frame_size);
- else
- to_stdout(&stream, frame_size);
-
+ (inplace ? in_place : to_stdout)(&stream, frame_size);
         close(stream.fd);
         return 0;
 }
diff --git a/src/blind-set-alpha.c b/src/blind-set-alpha.c
index a7d2404..23be8ab 100644
--- a/src/blind-set-alpha.c
+++ b/src/blind-set-alpha.c
_AT_@ -51,13 +51,8 @@ main(int argc, char *argv[])
         if (argc != 1)
                 usage();
 
- colour.file = "<stdin>";
- colour.fd = STDIN_FILENO;
- einit_stream(&colour);
-
- alpha.file = argv[0];
- alpha.fd = eopen(alpha.file, O_RDONLY);
- einit_stream(&alpha);
+ eopen_stream(&colour, NULL);
+ eopen_stream(&alpha, argv[0]);
 
         if (!strcmp(colour.pixfmt, "xyza"))
                 process = invert ? process_xyza_i : process_xyza;
diff --git a/src/blind-set-luma.c b/src/blind-set-luma.c
index f4bd3d5..751bc6b 100644
--- a/src/blind-set-luma.c
+++ b/src/blind-set-luma.c
_AT_@ -94,13 +94,8 @@ main(int argc, char *argv[])
 
         UNOFLAGS(argc != 1);
 
- colour.file = "<stdin>";
- colour.fd = STDIN_FILENO;
- einit_stream(&colour);
-
- luma.file = argv[0];
- luma.fd = eopen(luma.file, O_RDONLY);
- einit_stream(&luma);
+ eopen_stream(&colour, NULL);
+ eopen_stream(&luma, argv[0]);
 
         if (!strcmp(colour.pixfmt, "xyza"))
                 process = process_xyza;
diff --git a/src/blind-set-saturation.c b/src/blind-set-saturation.c
index 3dffff0..94e994c 100644
--- a/src/blind-set-saturation.c
+++ b/src/blind-set-saturation.c
_AT_@ -69,13 +69,8 @@ main(int argc, char *argv[])
         if (argc != 1)
                 usage();
 
- colour.file = "<stdin>";
- colour.fd = STDIN_FILENO;
- einit_stream(&colour);
-
- satur.file = argv[0];
- satur.fd = eopen(satur.file, O_RDONLY);
- einit_stream(&satur);
+ eopen_stream(&colour, NULL);
+ eopen_stream(&satur, argv[0]);
 
         if (!strcmp(colour.pixfmt, "xyza"))
                 process = whitepoint ? process_xyza_w : process_xyza;
diff --git a/src/blind-skip-pattern.c b/src/blind-skip-pattern.c
index 1debeca..8fdf570 100644
--- a/src/blind-skip-pattern.c
+++ b/src/blind-skip-pattern.c
_AT_@ -14,8 +14,7 @@ process_frame(struct stream *stream, int include, size_t rown)
         size_t h, n;
         int anything = 0;
 
- for (h = stream->height; h;) {
- h--;
+ for (h = stream->height; h; h--) {
                 for (n = rown; n; n -= stream->ptr) {
                         stream->ptr = 0;
                         if (!eread_stream(stream, n))
_AT_@ -27,7 +26,7 @@ process_frame(struct stream *stream, int include, size_t rown)
         }
 done:
 
- if (anything && (h || n || stream->frames))
+ if (anything && h)
                 eprintf("%s: is shorted than expected\n", stream->file);
 
         return !anything;
_AT_@ -44,9 +43,7 @@ main(int argc, char *argv[])
 
         UNOFLAGS(!argc);
 
- stream.fd = STDIN_FILENO;
- stream.file = "<stdin>";
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
 
         includes = emalloc((size_t)argc);
         ns = ecalloc((size_t)argc, sizeof(*ns));
_AT_@ -67,11 +64,12 @@ main(int argc, char *argv[])
                         total += (size_t)include;
         }
 
+ echeck_frame_size(stream.width, 1, stream.pixel_size, 0, stream.file);
+ rown = stream.width * stream.pixel_size;
         stream.frames = total;
         fprint_stream_head(stdout, &stream);
         efflush(stdout, "<stdout>");
 
- rown = stream.width * stream.pixel_size;
         for (i = 0;; i = (i + 1) % argc) {
                 include = (int)includes[i];
                 n = ns[i];
diff --git a/src/blind-split.c b/src/blind-split.c
index 78c569a..e92fced 100644
--- a/src/blind-split.c
+++ b/src/blind-split.c
_AT_@ -28,12 +28,10 @@ main(int argc, char *argv[])
                 usage();
         } ARGEND;
 
- if (argc < 2 || argc % 2)
+ if (argc % 2 || !argc)
                 usage();
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
         echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, stream.file);
         frame_size = stream.width * stream.height * stream.pixel_size;
         if (stream.frames > (size_t)SSIZE_MAX / frame_size)
diff --git a/src/blind-stack.c b/src/blind-stack.c
index 2bcc38c..d409cc6 100644
--- a/src/blind-stack.c
+++ b/src/blind-stack.c
_AT_@ -64,9 +64,7 @@ main(int argc, char *argv[])
         streams = ecalloc(n_streams, sizeof(*streams));
 
         for (i = 0; i < n_streams; i++) {
- streams[i].file = argv[i];
- streams[i].fd = eopen(streams[i].file, O_RDONLY);
- einit_stream(streams + i);
+ eopen_stream(streams + i, argv[i]);
                 if (streams[i].frames > frames)
                         frames = streams[i].frames;
         }
diff --git a/src/blind-time-blur.c b/src/blind-time-blur.c
index feb6102..c5d9ee5 100644
--- a/src/blind-time-blur.c
+++ b/src/blind-time-blur.c
_AT_@ -56,13 +56,8 @@ main(int argc, char *argv[])
         if (argc != 1)
                 usage();
 
- colour.file = "<stdin>";
- colour.fd = STDIN_FILENO;
- einit_stream(&colour);
-
- alpha.file = argv[0];
- alpha.fd = eopen(alpha.file, O_RDONLY);
- einit_stream(&alpha);
+ eopen_stream(&colour, NULL);
+ eopen_stream(&alpha, argv[0]);
 
         if (!strcmp(colour.pixfmt, "xyza"))
                 process = process_xyza;
_AT_@ -74,6 +69,5 @@ main(int argc, char *argv[])
         fprint_stream_head(stdout, &colour);
         efflush(stdout, "<stdout>");
         process_each_frame_two_streams(&colour, &alpha, STDOUT_FILENO, "<stdout>", process);
-
         return 0;
 }
diff --git a/src/blind-to-image.c b/src/blind-to-image.c
index 48cf625..7ea1586 100644
--- a/src/blind-to-image.c
+++ b/src/blind-to-image.c
_AT_@ -14,6 +14,8 @@ USAGE("[-d depth | -f]")
 static int luma_warning_triggered = 0;
 static int gamut_warning_triggered = 0;
 static int alpha_warning_triggered = 0;
+static unsigned long long int max;
+static int bytes;
 
 static void
 write_pixel(double R, double G, double B, double A, int bytes, unsigned long long int max)
_AT_@ -57,7 +59,7 @@ write_pixel(double R, double G, double B, double A, int bytes, unsigned long lon
 }
 
 static void
-process_xyza(struct stream *stream, size_t n, int bytes, unsigned long long int max)
+process_xyza(struct stream *stream, size_t n)
 {
         size_t i;
         double X, Y, Z, A, R, G, B;
_AT_@ -84,10 +86,8 @@ int
 main(int argc, char *argv[])
 {
         struct stream stream;
- int depth = 16, bytes, farbfeld = 0;
- unsigned long long int max;
- size_t n;
- void (*process)(struct stream *stream, size_t n, int bytes, unsigned long long int max);
+ int depth = 16, farbfeld = 0;
+ void (*process)(struct stream *stream, size_t n);
 
         ARGBEGIN {
         case 'd':
_AT_@ -103,9 +103,7 @@ main(int argc, char *argv[])
         if (argc || (farbfeld && depth != 16))
                 usage();
 
- stream.fd = STDIN_FILENO;
- stream.file = "<stdin.h>";
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
 
         max = 1ULL << (depth - 1);
         max |= max - 1;
_AT_@ -140,11 +138,6 @@ main(int argc, char *argv[])
         }
         efflush(stdout, "<stdout>");
 
- do {
- n = stream.ptr - (stream.ptr % stream.pixel_size);
- process(&stream, n, bytes, max);
- memmove(stream.buf, stream.buf + n, stream.ptr -= n);
- } while (eread_stream(&stream, SIZE_MAX));
-
+ process_stream(&stream, process);
         return 0;
 }
diff --git a/src/blind-to-text.c b/src/blind-to-text.c
index c196dcb..7fefbfc 100644
--- a/src/blind-to-text.c
+++ b/src/blind-to-text.c
_AT_@ -24,14 +24,11 @@ int
 main(int argc, char *argv[])
 {
         struct stream stream;
- size_t n;
         void (*process)(struct stream *stream, size_t n) = NULL;
 
         UNOFLAGS(argc);
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
 
         if (!strcmp(stream.pixfmt, "xyza"))
                 process = process_xyza;
_AT_@ -40,12 +37,7 @@ main(int argc, char *argv[])
 
         printf("%zu %zu %zu %s\n", stream.frames, stream.width, stream.height, stream.pixfmt);
 
- while ((n = eread_stream(&stream, SIZE_MAX))) {
- n = stream.ptr - (stream.ptr % stream.pixel_size);
- process(&stream, n);
- memmove(stream.buf, stream.buf + n, stream.ptr -= n);
- }
-
+ process_stream(&stream, process);
         efshut(stdout, "<stdout>");
         return 0;
 }
diff --git a/src/blind-to-video.c b/src/blind-to-video.c
index 4da9306..2bebe9b 100644
--- a/src/blind-to-video.c
+++ b/src/blind-to-video.c
_AT_@ -2,23 +2,20 @@
 #include "stream.h"
 #include "util.h"
 
-#if defined(HAVE_PRCTL)
-# include <sys/prctl.h>
-#endif
-#include <sys/wait.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-d] frame-rate ffmpeg-arguments ...")
 
 static int draft = 0;
+static int fd;
 
 static void
-process_xyza(char *buf, size_t n, int fd, const char *fname)
+process_xyza(struct stream *stream, size_t n)
 {
+ char *buf = stream->buf;
         double *pixel, r, g, b;
         uint16_t *pixels, *end;
         uint16_t pixbuf[1024];
_AT_@ -38,7 +35,7 @@ process_xyza(char *buf, size_t n, int fd, const char *fname)
                         *pixels++ = htole16((uint16_t)CLIP(0, u, 0xFFFFL));
                         *pixels++ = htole16((uint16_t)CLIP(0, v, 0xFFFFL));
                         if (pixels == end)
- ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), fname);
+ ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), "<subprocess>");
                 }
         } else {
                 for (ptr = 0; ptr < n; ptr += 4 * sizeof(double)) {
_AT_@ -57,11 +54,10 @@ process_xyza(char *buf, size_t n, int fd, const char *fname)
                         *pixels++ = htole16((uint16_t)CLIP(0, u, 0xFFFFL));
                         *pixels++ = htole16((uint16_t)CLIP(0, v, 0xFFFFL));
                         if (pixels == end)
- ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), fname);
+ ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), "<subprocess>");
                 }
         }
- if (pixels != pixbuf)
- ewriteall(fd, pixbuf, (size_t)(pixels - pixbuf) * sizeof(*pixels), fname);
+ ewriteall(fd, pixbuf, (size_t)(pixels - pixbuf) * sizeof(*pixels), "<subprocess>");
 }
 
 int
_AT_@ -74,7 +70,7 @@ main(int argc, char *argv[])
         size_t n = 0;
         int status, pipe_rw[2];
         pid_t pid;
- void (*process)(char *buf, size_t n, int fd, const char *fname) = NULL;
+ void (*process)(struct stream *stream, size_t n) = NULL;
 
         ARGBEGIN {
         case 'd':
_AT_@ -97,9 +93,7 @@ main(int argc, char *argv[])
         cmd[n++] = "-i", cmd[n++] = "-";
         memcpy(cmd + n, argv, (size_t)argc * sizeof(*cmd));
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
 
         sprintf(geometry, "%zux%zu", stream.width, stream.height);
 
_AT_@ -108,37 +102,24 @@ main(int argc, char *argv[])
         else
                 eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
 
- if (pipe(pipe_rw))
- eprintf("pipe:");
-
- pid = fork();
- if (pid < 0)
- eprintf("fork:");
+ epipe(pipe_rw);
+ pid = efork();
 
         if (!pid) {
-#if defined(HAVE_PRCTL) && defined(PR_SET_PDEATHSIG)
- prctl(PR_SET_PDEATHSIG, SIGKILL);
-#endif
+ pdeath(SIGKILL);
                 close(pipe_rw[1]);
- if (dup2(pipe_rw[0], STDIN_FILENO) == -1)
- eprintf("dup2:");
+ edup2(pipe_rw[0], STDIN_FILENO);
                 close(pipe_rw[0]);
- execvp("ffmpeg", (char **)(void *)cmd);
- eprintf("exec ffmpeg:");
+ eexecvp("ffmpeg", (char **)(void *)cmd);
         }
 
         free(cmd);
 
         close(pipe_rw[0]);
- while (eread_stream(&stream, SIZE_MAX)) {
- n = stream.ptr - (stream.ptr % stream.pixel_size);
- process(stream.buf, n, pipe_rw[1], "<subprocess>");
- memmove(stream.buf, stream.buf + n, stream.ptr -= n);
- }
- close(pipe_rw[1]);
-
- if (waitpid(pid, &status, 0) == -1)
- eprintf("waitpid:");
+ fd = pipe_rw[1];
+ process_stream(&stream, process);
+ close(fd);
 
+ ewaitpid(pid, &status, 0);
         return !!status;
 }
diff --git a/src/blind-translate.c b/src/blind-translate.c
index fc6cf6f..0ee4b93 100644
--- a/src/blind-translate.c
+++ b/src/blind-translate.c
_AT_@ -2,7 +2,6 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
 #include <inttypes.h>
 #include <math.h>
 #include <string.h>
_AT_@ -65,8 +64,6 @@ process_frame(struct stream *stream, char *buf, size_t n,
 eof:
         eprintf("%s: file is shorter than expected\n", stream->file);
         return 0;
-
-#undef ZEROES
 }
 
 static void
_AT_@ -80,8 +77,7 @@ process(struct stream *stream, struct stream *trstream)
 
         memset(zeroes, 0, sizeof(zeroes));
 
- if (!check_frame_size(stream->width, 1, stream->pixel_size))
- eprintf("%s: video frame is too wide\n", stream->file);
+ echeck_frame_size(stream->width, 1, stream->pixel_size, 0, stream->file);
         n = stream->width * stream->pixel_size;
         buf = emalloc(n);
 
_AT_@ -156,20 +152,15 @@ main(int argc, char *argv[])
         case 'p':
                 invtrans = 1;
                 break;
+ default:
+ usage();
         } ARGEND;
 
         if (argc != 1)
                 usage();
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
- fprint_stream_head(stdout, &stream);
- efflush(stdout, "<stdout>");
-
- trstream.file = argv[0];
- trstream.fd = eopen(trstream.file, O_RDONLY);
- einit_stream(&trstream);
+ eopen_stream(&stream, NULL);
+ eopen_stream(&trstream, argv[0]);
 
         if (trstream.width != 1 || trstream.height != 1)
                 eprintf("translation-stream does not have 1x1 geometry\n");
_AT_@ -178,6 +169,9 @@ main(int argc, char *argv[])
                 eprintf("pixel format of translation-stream %s "
                         "is not supported, try xyza\n", trstream.pixfmt);
 
+ fprint_stream_head(stdout, &stream);
+ efflush(stdout, "<stdout>");
+
         (wrap ? process_wrap : process)(&stream, &trstream);
         close(trstream.fd);
         return 0;
diff --git a/src/blind-transpose.c b/src/blind-transpose.c
index c640d36..d1b4e47 100644
--- a/src/blind-transpose.c
+++ b/src/blind-transpose.c
_AT_@ -18,16 +18,14 @@ main(int argc, char *argv[])
 
         UNOFLAGS(argc);
 
- stream.file = "<stdin>";
- stream.fd = STDIN_FILENO;
- einit_stream(&stream);
+ eopen_stream(&stream, NULL);
         imgw = srch = stream.height;
         stream.height = srcw = stream.width;
         stream.width = imgw;
         fprint_stream_head(stdout, &stream);
         efflush(stdout, "<stdout>");
 
- echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, "<stdin>");
+ echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, stream.file);
         n = stream.width * stream.height * (ps = stream.pixel_size);
         buf = emalloc(n);
         image = emalloc(n); /* TODO optimise to a frame row */
diff --git a/src/stream.c b/src/stream.c
index 483ca83..661e9e9 100644
--- a/src/stream.c
+++ b/src/stream.c
_AT_@ -94,6 +94,15 @@ bad_format:
 }
 
 
+void
+enopen_stream(int status, struct stream *stream, const char *file)
+{
+ stream->file = file ? file : "<stdin>";
+ stream->fd = file ? enopen(status, file, O_RDONLY) : STDIN_FILENO;
+ eninit_stream(status, stream);
+}
+
+
 int
 set_pixel_size(struct stream *stream)
 {
_AT_@ -146,21 +155,24 @@ eninf_check_fd(int status, int fd, const char *file)
 int
 check_frame_size(size_t width, size_t height, size_t pixel_size)
 {
- if (!width || !height || !pixel_size)
+ if (!height)
+ return !width || !pixel_size || !(width > SIZE_MAX / pixel_size);
+ if (!width)
+ return !height || !pixel_size || !(height > SIZE_MAX / pixel_size);
+ if (!pixel_size)
                 return 1;
         if (width > SIZE_MAX / height)
                 return 0;
- if (width * height > SIZE_MAX / pixel_size)
- return 0;
- return 1;
+ return !(width * height > SIZE_MAX / pixel_size);
 }
 
 void
 encheck_frame_size(int status, size_t width, size_t height, size_t pixel_size, const char *prefix, const char *fname)
 {
         if (!check_frame_size(width, height, pixel_size))
- enprintf(status, "%s: %s%svideo frame is too large\n",
- fname, prefix ? prefix : "", (prefix && *prefix) ? " " : "");
+ enprintf(status, "%s: %s%svideo frame is too %s\n",
+ fname, prefix ? prefix : "", (prefix && *prefix) ? " " : "",
+ width <= 1 ? "tall" : height <= 1 ? "wide" : "large");
 }
 
 
_AT_@ -207,6 +219,18 @@ enread_frame(int status, struct stream *stream, void *buf, size_t n)
 
 
 void
+nprocess_stream(int status, struct stream *stream, void (*process)(struct stream *stream, size_t n))
+{
+ size_t n;
+ do {
+ n = stream->ptr - (stream->ptr % stream->pixel_size);
+ process(stream, n);
+ memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+ } while (enread_stream(status, stream, SIZE_MAX));
+}
+
+
+void
 nprocess_each_frame_segmented(int status, struct stream *stream, int output_fd, const char* output_fname,
                               void (*process)(struct stream *stream, size_t n, size_t frame))
 {
_AT_@ -221,7 +245,7 @@ nprocess_each_frame_segmented(int status, struct stream *stream, int output_fd,
                                 enprintf(status, "%s: file is shorter than expected\n", stream->file);
                         r = stream->ptr - (stream->ptr % stream->pixel_size);
                         r = MIN(r, n);
- (process)(stream, r, frame);
+ process(stream, r, frame);
                         enwriteall(status, output_fd, stream->buf, r, output_fname);
                         memmove(stream->buf, stream->buf + r, stream->ptr -= r);
                 }
diff --git a/src/stream.h b/src/stream.h
index a5cebc6..41a1a7f 100644
--- a/src/stream.h
+++ b/src/stream.h
_AT_@ -21,6 +21,7 @@
                 FRAMES, WIDTH, HEIGHT, PIXFMT, 0)
 
 #define einit_stream(...) eninit_stream(1, __VA_ARGS__)
+#define eopen_stream(...) enopen_stream(1, __VA_ARGS__)
 #define eset_pixel_size(...) enset_pixel_size(1, __VA_ARGS__)
 #define eread_stream(...) enread_stream(1, __VA_ARGS__)
 #define einf_check_fd(...) eninf_check_fd(1, __VA_ARGS__)
_AT_@ -31,6 +32,7 @@
 #define enread_row(...) enread_frame(__VA_ARGS__)
 #define eread_row(...) eread_frame(__VA_ARGS__)
 
+#define process_stream(...) nprocess_stream(1, __VA_ARGS__)
 #define process_each_frame_segmented(...) nprocess_each_frame_segmented(1, __VA_ARGS__)
 #define process_two_streams(...) nprocess_two_streams(1, __VA_ARGS__)
 #define process_multiple_streams(...) nprocess_multiple_streams(1, __VA_ARGS__)
_AT_@ -51,6 +53,7 @@ struct stream {
 };
 
 void eninit_stream(int status, struct stream *stream);
+void enopen_stream(int status, struct stream *stream, const char *file);
 int set_pixel_size(struct stream *stream);
 void enset_pixel_size(int status, struct stream *stream);
 void fprint_stream_head(FILE *fp, struct stream *stream);
_AT_@ -61,6 +64,8 @@ void encheck_frame_size(int status, size_t width, size_t height, size_t pixel_si
 void encheck_compat(int status, const struct stream *a, const struct stream *b);
 int enread_frame(int status, struct stream *stream, void *buf, size_t n);
 
+void nprocess_stream(int status, struct stream *stream, void (*process)(struct stream *stream, size_t n));
+
 void nprocess_each_frame_segmented(int status, struct stream *stream, int output_fd, const char* output_fname,
                                    void (*process)(struct stream *stream, size_t n, size_t frame));
 
diff --git a/src/util.c b/src/util.c
index 21b2b69..b5aac6e 100644
--- a/src/util.c
+++ b/src/util.c
_AT_@ -1,9 +1,6 @@
 /* See LICENSE file for copyright and license details. */
 #include "util.h"
 
-#if defined(HAVE_PRCTL)
-# include <sys/prctl.h>
-#endif
 #include <sys/wait.h>
 #include <ctype.h>
 #include <errno.h>
_AT_@ -200,9 +197,7 @@ enfork_jobs(int status, size_t *start, size_t *end, size_t jobs, pid_t **pids)
         for (j = 1; j < jobs; j++) {
                 pid = enfork(status);
                 if (!pid) {
-#if defined(HAVE_PRCTL) && defined(PR_SET_PDEATHSIG)
- prctl(PR_SET_PDEATHSIG, SIGKILL);
-#endif
+ pdeath(SIGKILL);
                         *start = n * (j + 0) / jobs + s;
                         *end = n * (j + 1) / jobs + s;
                         return 0;
diff --git a/src/util.h b/src/util.h
index d948452..42b5df5 100644
--- a/src/util.h
+++ b/src/util.h
_AT_@ -20,3 +20,4 @@
 #include "util/io.h"
 #include "util/jobs.h"
 #include "util/endian.h"
+#include "util/efunc.h"
diff --git a/src/util/efunc.h b/src/util/efunc.h
new file mode 100644
index 0000000..03d1609
--- /dev/null
+++ b/src/util/efunc.h
_AT_@ -0,0 +1,74 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define eexecvp(F, ...) (execvp(F, __VA_ARGS__), eprintf("exec %s:", F))
+#define eexeclp(F, ...) (execlp(F, __VA_ARGS__), eprintf("exec %s:", F))
+
+static inline void
+epipe(int fds[2])
+{
+ if (pipe(fds))
+ eprintf("pipe:");
+}
+
+static inline pid_t
+efork(void)
+{
+ pid_t ret = fork();
+ if (ret < 0)
+ eprintf("fork:");
+ return ret;
+}
+
+static inline void
+edup2(int old, int new)
+{
+ if (dup2(old, new) < 0)
+ eprintf("dup2:");
+}
+
+static inline int
+edup(int fd)
+{
+ int ret = dup(fd);
+ if (ret < 0)
+ eprintf("dup:");
+ return ret;
+}
+
+static inline pid_t
+ewaitpid(pid_t pid, int *status, int flags)
+{
+ pid_t ret = waitpid(pid, status, flags);
+ if (ret < 0)
+ eprintf("waitpid:");
+ return ret;
+}
+
+static inline size_t
+eread(int fd, void *buf, size_t n, const char *fname)
+{
+ ssize_t ret = read(fd, buf, n);
+ if (ret < 0)
+ eprintf("read %s:", fname);
+ return (size_t)ret;
+}
+
+static inline size_t
+epread(int fd, void *buf, size_t n, off_t off, const char *fname)
+{
+ ssize_t ret = pread(fd, buf, n, off);
+ if (ret < 0)
+ eprintf("pread %s:", fname);
+ return (size_t)ret;
+}
+
+static inline off_t
+elseek(int fd, off_t offset, int whence, const char *fname)
+{
+ off_t ret = lseek(fd, offset, whence);
+ if (ret < 0)
+ eprintf("lseek %s:", fname);
+ return ret;
+}
diff --git a/src/util/io.h b/src/util/io.h
index 44e222d..8c646cb 100644
--- a/src/util/io.h
+++ b/src/util/io.h
_AT_@ -1,4 +1,17 @@
 /* See LICENSE file for copyright and license details. */
+#include <fcntl.h>
+
+#if defined(POSIX_FADV_SEQUENTIAL)
+# define fadvise_sequential(...) posix_fadvise(__VA_ARGS__, POSIX_FADV_SEQUENTIAL)
+#else
+# define fadvise_sequential(...)
+#endif
+
+#if defined(POSIX_FADV_RANDOM)
+# define fadvise_random(...) posix_fadvise(__VA_ARGS__, POSIX_FADV_RANDOM)
+#else
+# define fadvise_random(...)
+#endif
 
 #define ewriteall(...) enwriteall(1, __VA_ARGS__)
 #define ereadall(...) enreadall(1, __VA_ARGS__)
diff --git a/src/util/jobs.h b/src/util/jobs.h
index d45433c..9accf84 100644
--- a/src/util/jobs.h
+++ b/src/util/jobs.h
_AT_@ -1,4 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#if defined(HAVE_PRCTL)
+# include <sys/prctl.h>
+#endif
+
+#if defined(HAVE_PRCTL) && defined(PR_SET_PDEATHSIG)
+# define pdeath(SIGNAL) prctl(PR_SET_PDEATHSIG, SIGNAL);
+#else
+# define pdeath(SIGNAL)
+#endif
 
 #define efork_jobs(...) enfork_jobs(1, __VA_ARGS__)
 #define ejoin_jobs(...) enjoin_jobs(1, __VA_ARGS__)
Received on Sun Apr 09 2017 - 23:53:57 CEST

This archive was generated by hypermail 2.3.0 : Mon Apr 10 2017 - 00:01:04 CEST