diff options
author | Peter Wu <lekensteyn@gmail.com> | 2013-07-08 22:01:21 +0200 |
---|---|---|
committer | Peter Wu <lekensteyn@gmail.com> | 2013-07-08 22:01:21 +0200 |
commit | 348aa301fda1ad1c8d7840e72c103e4453cc322d (patch) | |
tree | c0c7bd0f3c42c2880717d919c6b14e4938e5ed42 | |
parent | 3b68c1ec836681ed032b3150e81d896011d71cb0 (diff) | |
download | c-files-348aa301fda1ad1c8d7840e72c103e4453cc322d.tar.gz |
revb: reverse all stdin (bufferred)
-rw-r--r-- | revb.c | 52 |
1 files changed, 52 insertions, 0 deletions
@@ -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; +} |