diff options
author | Jakob Kaivo <jkk@ung.org> | 2019-07-27 15:39:35 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2019-07-27 15:39:35 -0400 |
commit | 3cbf2fe6e6f9afdf580b1cf6522a950ef898e459 (patch) | |
tree | ffd0a71515f6ce9b66782896f31e8ca2a25777bb | |
parent | 373069f95c79a353b014f9da635d9b1bdddac6a3 (diff) |
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | pp.c | 58 |
3 files changed, 66 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c0d72fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +pp +*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2c04586 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +.POSIX: + +pp: pp.c + +clean: + rm pp *.o @@ -0,0 +1,58 @@ +#define _XOPEN_SOURCE 700 + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +int main(int argc, char *argv[]) +{ + if (argc != 3) { + fprintf(stderr, "Usage: %s source destinations\n", argv[0]); + return 1; + } + + int source = open(argv[1], O_RDONLY); + if (source == -1) { + fprintf(stderr, "%s:%s\n", argv[1], strerror(errno)); + return 1; + } + + int dest = open(argv[2], O_WRONLY | O_CREAT, 0644); + if (dest == -1) { + fprintf(stderr, "%s:%s\n", argv[2], strerror(errno)); + return 1; + } + + struct stat st; + if (fstat(source, &st) == -1) { + perror("stat"); + return 1; + } + + setvbuf(stdout, NULL, _IONBF, 0); + unsigned long long i = 0; + do { + char buf[BUFSIZ]; + + ssize_t n = read(source, buf, sizeof(buf)); + if (n < 0) { + perror("read"); + return 1; + } + + if (write(dest, buf, n) < n) { + perror("write"); + return 1; + } + + + i += n; + printf("\r%llu/%llu bytes (%llu%%)", i, (unsigned long long)st.st_size, i * 100 / (unsigned long long)st.st_size); + } while (i < (unsigned long long)st.st_size); + + printf("\n"); + return 0; +} |