summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
+}