commit 19ad368f68164b99a2cfedb11747d7ca2d040ee0
parent 6b998b5ed066aeece1146fe245b35965319b3cbd
Author: Mattias Andrée <maandree@kth.se>
Date: Wed, 10 May 2017 21:29:46 +0200
Cleaner code
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
24 files changed, 206 insertions(+), 203 deletions(-)
diff --git a/man/blind-transpose.1 b/man/blind-transpose.1
@@ -15,9 +15,6 @@ X and Y coordinates.
requires enough free memory to load one full frames and
one input column into memory. A frame requires 32 bytes
per pixel it contains.
-.B blind-transpose
-has not been optimised for memory usage, but instead
-for code simplicity.
.SH SEE ALSO
.BR blind (7),
.BR blind-flip (1),
diff --git a/src/blind-arithm.c b/src/blind-arithm.c
@@ -74,7 +74,7 @@ int
main(int argc, char *argv[])
{
struct stream left, right;
- process_func process = NULL;
+ process_func process;
ARGBEGIN {
case 'a':
diff --git a/src/blind-compress.c b/src/blind-compress.c
@@ -17,7 +17,7 @@ compare(const char *restrict new, const char *restrict old, size_t n, size_t **c
(*cmp)[ptr - 1] += same + diff;
} else {
if (ptr + 2 > *cmpsize)
- *cmp = erealloc(*cmp, (*cmpsize += 128) * sizeof(size_t));
+ *cmp = erealloc2(*cmp, *cmpsize += 128, sizeof(size_t));
(*cmp)[ptr++] = same;
(*cmp)[ptr++] = diff;
}
diff --git a/src/blind-concat.c b/src/blind-concat.c
@@ -17,7 +17,7 @@ concat_to_stdout(int argc, char *argv[], const char *fname)
size_t frames = 0;
int i;
- streams = emalloc((size_t)argc * sizeof(*streams));
+ streams = emalloc2((size_t)argc, sizeof(*streams));
for (i = 0; i < argc; i++) {
eopen_stream(streams + i, argv[i]);
@@ -33,10 +33,7 @@ concat_to_stdout(int argc, char *argv[], const char *fname)
efflush(stdout, fname);
for (i = 0; i < argc; i++) {
- do {
- ewriteall(STDOUT_FILENO, streams[i].buf, streams[i].ptr, fname);
- streams[i].ptr = 0;
- } while (eread_stream(streams + i, SIZE_MAX));
+ esend_stream(streams + i, STDOUT_FILENO, fname);
close(streams[i].fd);
}
@@ -50,7 +47,9 @@ concat_to_file(int argc, char *argv[], char *output_file)
int first = 1;
int fd = eopen(output_file, O_RDWR | O_CREAT | O_TRUNC, 0666);
char head[STREAM_HEAD_MAX];
- ssize_t headlen, size = 0;
+ ssize_t headlen;
+ size_t size = 0;
+ off_t pos;
char *data;
for (; argc--; argv++) {
@@ -66,23 +65,23 @@ concat_to_file(int argc, char *argv[], char *output_file)
echeck_compat(&stream, &refstream);
}
- do {
- ewriteall(fd, stream.buf, stream.ptr, output_file);
- size += stream.ptr;
- stream.ptr = 0;
- } while (eread_stream(&stream, SIZE_MAX));
+ esend_stream(&stream, fd, output_file);
close(stream.fd);
}
SPRINTF_HEAD_ZN(head, stream.frames, stream.width, stream.height, stream.pixfmt, &headlen);
ewriteall(fd, head, (size_t)headlen, output_file);
- data = mmap(0, size + (size_t)headlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if ((pos = elseek(fd, 0, SEEK_CUR, output_file)) > SIZE_MAX)
+ eprintf("%s\n", strerror(EFBIG));
+ size = pos;
+
+ data = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED)
eprintf("mmap %s:", output_file);
- memmove(data + headlen, data, size);
+ memmove(data + headlen, data, size - (size_t)headlen);
memcpy(data, head, (size_t)headlen);
- munmap(data, size + (size_t)headlen);
+ munmap(data, size);
close(fd);
}
@@ -108,9 +107,9 @@ concat_to_file_parallel(int argc, char *argv[], char *output_file, size_t jobs)
jobs = (size_t)argc;
fd = eopen(output_file, O_RDWR | O_CREAT | O_TRUNC, 0666);
- events = emalloc(jobs * sizeof(*events));
- streams = emalloc((size_t)argc * sizeof(*streams));
- ptrs = emalloc((size_t)argc * sizeof(*ptrs));
+ events = emalloc2(jobs, sizeof(*events));
+ streams = emalloc2((size_t)argc, sizeof(*streams));
+ ptrs = emalloc2((size_t)argc, sizeof(*ptrs));
for (i = 0; i < argc; i++) {
eopen_stream(streams + i, argv[i]);
diff --git a/src/blind-cut.c b/src/blind-cut.c
@@ -10,9 +10,7 @@ int
main(int argc, char *argv[])
{
struct stream stream;
- size_t start = 0, end = 0, ptr, max;
- ssize_t r;
- char buf[BUFSIZ];
+ size_t start = 0, end = 0;
int to_end = 0;
UNOFLAGS(argc != 3);
@@ -32,26 +30,16 @@ main(int argc, char *argv[])
end = stream.frames;
else if (end > stream.frames)
eprintf("end point is after end of video\n");
- stream.frames = end - start;
- echeck_dimensions(&stream, WIDTH | HEIGHT | LENGTH, NULL);
- fprint_stream_head(stdout, &stream);
- efflush(stdout, "<stdout>");
-
if (start >= end)
eprintf("%s\n", start > end ?
"start point is after end point" :
"refusing to create video with zero frames");
- end = end * stream.frame_size + stream.headlen;
- start = start * stream.frame_size + stream.headlen;
-
- fadvise_sequential(stream.fd, start, end - start);
- for (ptr = start; ptr < end; ptr += (size_t)r) {
- max = end - ptr;
- max = MIN(max, sizeof(buf));
- 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>");
- }
+ stream.frames = end - start;
+ fprint_stream_head(stdout, &stream);
+ efflush(stdout, "<stdout>");
+
+ esend_frames(&stream, -1, start, NULL);
+ esend_frames(&stream, STDOUT_FILENO, start - end, "<stdout>");
close(stream.fd);
return 0;
diff --git a/src/blind-dissolve.c b/src/blind-dissolve.c
@@ -31,7 +31,7 @@ main(int argc, char *argv[])
{
struct stream stream;
int reverse = 0;
- void (*process)(struct stream *stream, size_t n, size_t f) = NULL;
+ void (*process)(struct stream *stream, size_t n, size_t f);
ARGBEGIN {
case 'r':
diff --git a/src/blind-from-text.c b/src/blind-from-text.c
@@ -33,7 +33,7 @@ main(int argc, char *argv[])
size_t size = 0;
char *line = NULL;
ssize_t len;
- void (*process)(void) = NULL;
+ void (*process)(void);
UNOFLAGS(argc);
diff --git a/src/blind-invert-luma.c b/src/blind-invert-luma.c
@@ -58,7 +58,7 @@ main(int argc, char *argv[])
{
int invert = 0, whitepoint = 0;
struct stream colour, mask;
- void (*process)(struct stream *colour, struct stream *mask, size_t n) = NULL;
+ void (*process)(struct stream *colour, struct stream *mask, size_t n);
ARGBEGIN {
case 'i':
diff --git a/src/blind-next-frame.c b/src/blind-next-frame.c
@@ -10,15 +10,15 @@ int
main(int argc, char *argv[])
{
struct stream stream;
- size_t n, w, h = 0;
- int i, anything = 0;
+ size_t n;
+ int i;
char *p;
stream.frames = 1;
ARGBEGIN {
case 'f':
- stream.frames = etozu_flag('f', UARGF(), 1, SIZE_MAX);
+ stream.frames = entozu_flag(2, 'f', UARGF(), 1, SIZE_MAX);
break;
default:
usage();
@@ -51,21 +51,10 @@ main(int argc, char *argv[])
fprint_stream_head(stdout, &stream);
enfflush(2, stdout, "<stdout>");
- w = stream.width * stream.pixel_size;
- for (; stream.frames; stream.frames--) {
- for (h = stream.height; h; h--) {
- for (n = w; n; n -= stream.ptr, stream.ptr = 0) {
- if (!stream.ptr && !enread_stream(2, &stream, n))
- goto done;
- anything = 1;
- enwriteall(2, STDOUT_FILENO, stream.buf, stream.ptr, "<stdout>");
- }
- }
- }
-done:
-
- if (anything && stream.frames)
+ n = ensend_frames(2, &stream, STDOUT_FILENO, stream.frames, "<stdout>");
+ if (!n)
+ return 1;
+ else if (n < stream.frames)
enprintf(2, "%s: is shorter than expected\n", stream.file);
-
- return !anything;
+ return 0;
}
diff --git a/src/blind-repeat.c b/src/blind-repeat.c
@@ -6,96 +6,56 @@
USAGE("(count | 'inf') file")
-static void
-repeat_regular_file(char *file, size_t count, int inf)
-{
- struct stream stream;
- char buf[BUFSIZ];
- size_t ptr;
- ssize_t r;
-
- eopen_stream(&stream, file);
- 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>");
+static size_t count = 0;
+static int inf;
+static struct stream stream;
+static int
+repeat_regular_file(void)
+{
while (inf || count--) {
fadvise_sequential(stream.fd, stream.headlen, 0);
- for (ptr = stream.headlen;; ptr += (size_t)r) {
- if (!(r = epread(stream.fd, buf, sizeof(buf), ptr, stream.file)))
- break;
- if (writeall(STDOUT_FILENO, buf, (size_t)r)) {
- if (!inf || errno != EPIPE)
- eprintf("write <stdout>:");
- return;
- }
- }
+ elseek(stream.fd, stream.headlen, SEEK_SET, stream.file);
+ if (esend_stream(&stream, STDOUT_FILENO, NULL))
+ return -1;
}
-
- close(stream.fd);
+ return 0;
}
-static void
-repeat_stdin(size_t count, int inf)
+static int
+repeat_stdin(void)
{
- struct stream stream;
- char *buf;
- size_t ptr, size;
- ssize_t r;
-
- eopen_stream(&stream, NULL);
- 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 = MAX(ptr, BUFSIZ);
- buf = emalloc(size);
- memcpy(buf, stream.buf, ptr);
-
- for (;;) {
- if (ptr == size)
- buf = erealloc(buf, size <<= 1);
- if (!(r = eread(STDIN_FILENO, buf + ptr, size - ptr, "<stdout>")))
- break;
- ptr += (size_t)r;
- }
-
- while (inf || count--) {
- if (writeall(STDOUT_FILENO, buf, ptr)) {
- if (!inf || errno != EPIPE)
- eprintf("write <stdout>:");
- return;
- }
- }
-
- free(buf);
+ size_t ptr = stream.ptr;
+ size_t size = MAX(ptr, BUFSIZ);
+ char *buf = memcpy(emalloc(size), stream.buf, ptr);
+ egetfile(STDIN_FILENO, &buf, &ptr, &size, "<stdout>");
+ while (inf || count--)
+ if (writeall(STDOUT_FILENO, buf, ptr))
+ return free(buf), -1;
+ return free(buf), 0;
}
int
main(int argc, char *argv[])
{
- size_t count = 0;
- int inf = 0;
-
UNOFLAGS(argc != 2);
- if (!strcmp(argv[0], "inf"))
- inf = 1;
+ if ((inf = !strcmp(argv[0], "inf")))
+ einf_check_fd(STDOUT_FILENO, "<stdout>");
else
count = etozu_arg("the count", argv[0], 0, SIZE_MAX);
- if (inf)
- einf_check_fd(STDOUT_FILENO, "<stdout>");
+ eopen_stream(&stream, !strcmp(argv[1], "-") ? NULL : argv[1]);
+ 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>");
- if (!strcmp(argv[1], "-"))
- repeat_stdin(count, inf);
- else
- repeat_regular_file(argv[1], count, inf);
+ if (!strcmp(argv[1], "-") ? repeat_stdin() : repeat_regular_file())
+ if (!inf || errno != EPIPE)
+ eprintf("write <stdout>:");
+ close(stream.fd);
return 0;
}
diff --git a/src/blind-set-alpha.c b/src/blind-set-alpha.c
@@ -27,7 +27,7 @@ main(int argc, char *argv[])
{
int invert = 0;
struct stream colour, alpha;
- void (*process)(struct stream *colour, struct stream *alpha, size_t n) = NULL;
+ void (*process)(struct stream *colour, struct stream *alpha, size_t n);
ARGBEGIN {
case 'i':
diff --git a/src/blind-set-saturation.c b/src/blind-set-saturation.c
@@ -54,7 +54,7 @@ main(int argc, char *argv[])
{
struct stream colour, satur;
int whitepoint = 0;
- void (*process)(struct stream *colour, struct stream *satur, size_t n) = NULL;
+ void (*process)(struct stream *colour, struct stream *satur, size_t n);
ARGBEGIN {
case 'w':
diff --git a/src/blind-single-colour.c b/src/blind-single-colour.c
@@ -39,7 +39,7 @@ main(int argc, char *argv[])
{
char *arg;
const char *pixfmt = "xyza";
- void (*process)(void) = NULL;
+ void (*process)(void);
ARGBEGIN {
case 'f':
diff --git a/src/blind-skip-pattern.c b/src/blind-skip-pattern.c
@@ -6,35 +6,11 @@
USAGE("(skipped-frames | +included-frames) ...")
-static int
-process_frame(struct stream *stream, int include)
-{
- size_t h, n, m;
- int anything = 0;
-
- for (h = stream->height; h; h--) {
- for (n = stream->row_size; n; n -= m, anything = 1) {
- if (!stream->ptr && !eread_stream(stream, n))
- goto done;
- m = MIN(stream->ptr, n);
- if (include)
- ewriteall(STDOUT_FILENO, stream->buf, m, "<stdout>");
- memmove(stream->buf, stream->buf + m, stream->ptr -= m);
- }
- }
-done:
-
- if (anything && h)
- eprintf("%s: is shorter than expected\n", stream->file);
-
- return anything;
-}
-
int
main(int argc, char *argv[])
{
struct stream stream;
- int i, include;
+ int i, include, outfd;
size_t f, n, total = 0;
char *includes;
size_t *ns;
@@ -68,13 +44,11 @@ main(int argc, char *argv[])
efflush(stdout, "<stdout>");
for (i = 0;; i = (i + 1) % argc) {
- include = (int)includes[i];
- for (n = ns[i]; n--;)
- if (!process_frame(&stream, include))
- goto done;
+ outfd = includes[i] ? STDOUT_FILENO : -1;
+ if (!esend_frames(&stream, outfd, ns[i], "<stdout>"))
+ break;
}
-done:
free(includes);
free(ns);
return 0;
diff --git a/src/blind-split.c b/src/blind-split.c
@@ -11,7 +11,7 @@ int
main(int argc, char *argv[])
{
struct stream stream;
- size_t *ends, i, parts, ptr, end, n;
+ size_t *ends, i, parts, n;
char *to_end;
FILE *fp;
int fd, unknown_length = 0;
@@ -28,54 +28,37 @@ main(int argc, char *argv[])
usage();
eopen_stream(&stream, NULL);
- echeck_dimensions(&stream, WIDTH | HEIGHT | LENGTH, NULL);
+ echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
parts = (size_t)argc / 2;
ends = alloca(parts * sizeof(*ends));
to_end = alloca(parts);
for (i = 0; i < parts; i++) {
- to_end[i] = 0;
- if (!strcmp(argv[i * 2 + 1], "end")) {
+ if ((to_end[i] = !strcmp(argv[i * 2 + 1], "end")))
ends[i] = unknown_length ? SIZE_MAX : stream.frames;
- to_end[i] = 1;
- } else if (tozu(argv[i * 2 + 1], 0, SIZE_MAX, ends + i)) {
+ else if (tozu(argv[i * 2 + 1], 0, SIZE_MAX, ends + i))
eprintf("the end point must be an integer in [0, %zu]\n", SIZE_MAX);
- }
+
if (i && ends[i] <= ends[i - 1])
eprintf("the end points must be in strictly ascending order\n");
if (!unknown_length && ends[i] > stream.frames)
eprintf("frame %zu is beyond the end of the video\n", ends[i]);
}
- ptr = 0;
for (i = 0; i < parts; i++) {
fd = eopen(argv[i * 2], O_WRONLY | O_CREAT | O_TRUNC, 0666);
- fp = fdopen(fd, "wb");
- if (!fp)
+ if (!(fp = fdopen(fd, "wb")))
eprintf("fdopen %s:", argv[i * 2]);
- stream.frames = ends[i] - (i ? ends[i - 1] : 0);
+ n = ends[i] - (i ? ends[i - 1] : 0);
+ stream.frames = (to_end[i] && unknown_length) ? 0 : n;
fprint_stream_head(fp, &stream);
efflush(fp, argv[i * 2]);
- for (end = to_end[i] ? SIZE_MAX : ends[i] * stream.frame_size; ptr < end; ptr += n) {
- n = end - ptr;
- if (stream.ptr) {
- n = MIN(stream.ptr, n);
- ewriteall(fd, stream.buf, n, argv[i * 2]);
- memmove(stream.buf, stream.buf + n, stream.ptr -= n);
- } else if ((n = eread_stream(&stream, n))) {
- ewriteall(fd, stream.buf, n, argv[i * 2]);
- stream.ptr = 0;
- } else if (ptr % stream.frame_size) {
- eprintf("%s: incomplete frame\n", stream.file);
- } else if (!unknown_length || !to_end[i]) {
+ if (esend_frames(&stream, fd, n, argv[i * 2]) != n)
+ if (!unknown_length || !to_end[i])
eprintf("%s: file is shorter than expected\n", stream.file);
- } else {
- break;
- }
- }
if (fclose(fp))
eprintf("%s:", argv[i * 2]);
diff --git a/src/blind-stack.c b/src/blind-stack.c
@@ -46,7 +46,7 @@ main(int argc, char *argv[])
struct stream *streams;
size_t n_streams, i, frames = 0, tmp;
int blend = 0;
- void (*process)(struct stream *streams, size_t n_streams, size_t n) = NULL;
+ void (*process)(struct stream *streams, size_t n_streams, size_t n);
ARGBEGIN {
case 'b':
diff --git a/src/blind-to-text.c b/src/blind-to-text.c
@@ -24,7 +24,7 @@ int
main(int argc, char *argv[])
{
struct stream stream;
- void (*process)(struct stream *stream, size_t n) = NULL;
+ void (*process)(struct stream *stream, size_t n);
UNOFLAGS(argc);
diff --git a/src/blind-to-video.c b/src/blind-to-video.c
@@ -72,7 +72,7 @@ main(int argc, char *argv[])
size_t n = 0;
int status, pipe_rw[2];
pid_t pid;
- void (*process)(struct stream *stream, size_t n) = NULL;
+ void (*process)(struct stream *stream, size_t n);
ARGBEGIN {
case 'd':
diff --git a/src/stream.c b/src/stream.c
@@ -276,6 +276,48 @@ enread_segment(int status, struct stream *stream, void *buf, size_t n)
}
+size_t
+ensend_frames(int status, struct stream *stream, int outfd, size_t frames, const char *outfname)
+{
+ size_t h, w, p;
+ size_t ret = 0;
+
+ for (ret = 0; ret < frames; ret++) {
+ for (p = stream->pixel_size; p; p--) {
+ for (h = stream->height; h; h--) {
+ for (w = stream->width; w; w -= stream->ptr, stream->ptr = 0) {
+ if (!stream->ptr && !enread_stream(status, stream, w))
+ goto done;
+ if (outfd >= 0)
+ enwriteall(status, outfd, stream->buf, stream->ptr, outfname);
+ }
+ }
+ }
+ }
+
+ return ret;
+done:
+ if (p != stream->pixel_size || h != stream->height || w != stream->width)
+ enprintf(status, "%s: incomplete frame", stream->file);
+ return ret;
+}
+
+
+int
+ensend_stream(int status, struct stream *stream, int outfd, const char *outfname)
+{
+ do {
+ if (writeall(outfd, stream->buf, stream->ptr)) {
+ if (outfname)
+ eprintf("write %s:", outfname);
+ return -1;
+ }
+ stream->ptr = 0;
+ } while (enread_stream(status, stream, SIZE_MAX));
+ return 0;
+}
+
+
void
nprocess_stream(int status, struct stream *stream, void (*process)(struct stream *stream, size_t n))
{
diff --git a/src/stream.h b/src/stream.h
@@ -32,6 +32,8 @@
#define eread_segment(...) enread_segment(1, __VA_ARGS__)
#define eread_frame(...) enread_frame(1, __VA_ARGS__)
#define eread_row(...) enread_row(1, __VA_ARGS__)
+#define esend_frames(...) ensend_frames(1, __VA_ARGS__)
+#define esend_stream(...) ensend_stream(1, __VA_ARGS__)
#define process_stream(...) nprocess_stream(1, __VA_ARGS__)
#define process_each_frame_segmented(...) nprocess_each_frame_segmented(1, __VA_ARGS__)
@@ -76,6 +78,8 @@ void encheck_dimensions(int status, const struct stream *stream, enum dimension
void encheck_compat(int status, const struct stream *a, const struct stream *b);
const char *get_pixel_format(const char *specified, const char *current);
int enread_segment(int status, struct stream *stream, void *buf, size_t n);
+size_t ensend_frames(int status, struct stream *stream, int outfd, size_t frames, const char *outfname);
+int ensend_stream(int status, struct stream *stream, int outfd, const char *outfname);
void nprocess_stream(int status, struct stream *stream, void (*process)(struct stream *stream, size_t n));
diff --git a/src/util.c b/src/util.c
@@ -166,6 +166,34 @@ writezeroes(int fd, void *buf, size_t bufsize, size_t n)
return 0;
}
+int
+getfile(int fd, void *buffer, size_t *restrict ptr, size_t *restrict size)
+{
+ char *restrict *restrict buf = buffer;
+ void *new;
+ size_t r;
+
+ for (;;) {
+ if (*ptr == *size) {
+ if (!(new = realloc(*buf, *size << 1))) {
+ errno = ENOMEM;
+ return -1;
+ }
+ *buf = new;
+ *size <<= 1;
+ }
+ r = read(fd, *buf + *ptr, *size - *ptr);
+ if (r <= 0) {
+ if (r)
+ return -1;
+ break;
+ }
+ *ptr += (size_t)r;
+ }
+
+ return 0;
+}
+
static inline pid_t
enfork(int status)
@@ -193,7 +221,7 @@ enfork_jobs(int status, size_t *start, size_t *end, size_t jobs, pid_t **pids)
return 1;
}
*end = n / jobs + s;
- *pids = enmalloc(status, jobs * sizeof(**pids));
+ *pids = enmalloc2(status, jobs, sizeof(**pids));
for (j = 1; j < jobs; j++) {
pid = enfork(status);
if (!pid) {
diff --git a/src/util.h b/src/util.h
@@ -6,7 +6,7 @@
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define CLIP(A, B, C) ((B) < (A) ? (A) : (B) > (C) ? (C) : (B))
#define STRLEN(STR) (sizeof(STR) - 1)
-#define INTSTRLEN(TYPE) ((sizeof(TYPE) == 1 ? 3 : (5 * sizeof(TYPE) / 2)) + (TYPE)-1 < 0)
+#define INTSTRLEN(TYPE) ((sizeof(TYPE) == 1 ? 3 : (5 * sizeof(TYPE) / 2)) + ((TYPE)-1 < 0))
#define USAGE(SYNOPSIS)\
static void usage(void)\
diff --git a/src/util/emalloc.h b/src/util/emalloc.h
@@ -1,9 +1,15 @@
/* See LICENSE file for copyright and license details. */
#include <stdlib.h>
+#include <stdint.h>
-#define emalloc(...) enmalloc(1, __VA_ARGS__)
-#define ecalloc(...) encalloc(1, __VA_ARGS__)
-#define erealloc(...) enrealloc(1, __VA_ARGS__)
+#define emalloc(...) enmalloc(1, __VA_ARGS__)
+#define emalloc2(...) enmalloc2(1, __VA_ARGS__)
+#define ecalloc(...) encalloc(1, __VA_ARGS__)
+#define erealloc(...) enrealloc(1, __VA_ARGS__)
+#define erealloc2(...) enrealloc2(1, __VA_ARGS__)
+
+#define malloc2(n, m) malloc(n * m);
+#define realloc3(p, n, m) realloc(p, n * m);
static inline void *
enmalloc(int status, size_t n)
@@ -15,6 +21,15 @@ enmalloc(int status, size_t n)
}
static inline void *
+enmalloc2(int status, size_t n, size_t m)
+{
+ void *ptr;
+ if (n > SIZE_MAX / m || !(ptr = malloc(n * m)))
+ enprintf(status, "malloc: out of memory\n");
+ return ptr;
+}
+
+static inline void *
encalloc(int status, size_t n, size_t m)
{
void *ptr = calloc(n, m);
@@ -31,3 +46,11 @@ enrealloc(int status, void *ptr, size_t n)
enprintf(status, "realloc: out of memory\n");
return ptr;
}
+
+static inline void *
+enrealloc2(int status, void *ptr, size_t n, size_t m)
+{
+ if (n > SIZE_MAX / m || !(ptr = realloc(ptr, n * m)))
+ enprintf(status, "realloc: out of memory\n");
+ return ptr;
+}
diff --git a/src/util/io.h b/src/util/io.h
@@ -1,5 +1,6 @@
/* See LICENSE file for copyright and license details. */
#include <fcntl.h>
+#include <errno.h>
#if defined(POSIX_FADV_SEQUENTIAL)
# define fadvise_sequential(...) posix_fadvise(__VA_ARGS__, POSIX_FADV_SEQUENTIAL)
@@ -17,6 +18,7 @@
#define ereadall(...) enreadall(1, __VA_ARGS__)
#define epwriteall(...) enpwriteall(1, __VA_ARGS__)
#define ewritezeroes(...) enwritezeroes(1, __VA_ARGS__)
+#define egetfile(...) engetfile(1, __VA_ARGS__)
int writeall(int fd, void *buf, size_t n);
@@ -55,3 +57,17 @@ enwritezeroes(int status, int fd, void *buf, size_t bufsize, size_t n, const cha
if (writezeroes(fd, buf, bufsize, n))
enprintf(status, "write %s:", fname);
}
+
+int getfile(int fd, void *bufp, size_t *restrict ptrp, size_t *restrict sizep);
+
+static inline void
+engetfile(int status, int fd, void *bufp, size_t *restrict ptrp,
+ size_t *restrict sizep, const char *fname)
+{
+ if (getfile(fd, bufp, ptrp, sizep)) {
+ if (errno == ENOMEM)
+ enprintf(status, "realloc:");
+ else
+ enprintf(status, "read %s:", fname);
+ }
+}