summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2013-07-08 22:01:21 +0200
committerPeter Wu <lekensteyn@gmail.com>2013-07-08 22:01:21 +0200
commit348aa301fda1ad1c8d7840e72c103e4453cc322d (patch)
treec0c7bd0f3c42c2880717d919c6b14e4938e5ed42
parent3b68c1ec836681ed032b3150e81d896011d71cb0 (diff)
downloadc-files-348aa301fda1ad1c8d7840e72c103e4453cc322d.tar.gz
revb: reverse all stdin (bufferred)
-rw-r--r--revb.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/revb.c b/revb.c
new file mode 100644
index 0000000..d4c47e4
--- /dev/null
+++ b/revb.c
@@ -0,0 +1,52 @@
+/*
+ * Print stdin fully reversed. Unlike util-linux rev(1), this program does not
+ * reverse lines, but buffers everything fully and then writes it on the end.
+ * Author: Peter Wu <lekensteyn@gmail.com>
+ * Date: 2012-11-07
+ */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define READ_BLOCK 1024
+#define SIZE_INC (4 * READ_BLOCK)
+
+int main(void) {
+ unsigned len = 0; /* length of data */
+ unsigned str_size = SIZE_INC; /* size of buffer */
+ char *str = malloc(str_size);
+ if (!str) {
+ perror("malloc");
+ return 1;
+ }
+ int n = 0;
+ do {
+ if (str_size - len < SIZE_INC) {
+ str_size += SIZE_INC;
+ str = realloc(str, str_size);
+ if (!str) {
+ fprintf(stderr, "Failed to enlarge buffer to %u: %s\n", str_size, strerror(errno));
+ abort();
+ }
+ }
+ n = read(STDIN_FILENO, str + len, READ_BLOCK);
+ if (n < 0) {
+ perror("read");
+ goto free_str;
+ } else if (n) {
+ len += n;
+ }
+ } while (n);
+
+ /* print in reverse */
+ while (len)
+ putchar(str[--len]);
+
+ free(str);
+ return 0;
+free_str:
+ free(str);
+ return 1;
+}