From 02d288d89683e99fd18fe9f54d4e731a6c474a4f Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Thu, 12 Apr 2012 01:38:35 -0400 Subject: initial check-in --- src/cat.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/cat.c (limited to 'src/cat.c') diff --git a/src/cat.c b/src/cat.c new file mode 100644 index 0000000..7901a89 --- /dev/null +++ b/src/cat.c @@ -0,0 +1,82 @@ +/* + * cat.c + * Implementation of SUSv3 XCU cat utility + * Copyright © 2007 Rich Felker + * Licensed under the terms of the GNU General Public License, v2 or later + */ + +#include +#include +#include +#include +#include +#include + +static int my_write(int fd, const char *s, size_t l) +{ + while (l) { + ssize_t n = write(fd, s, l); + if (n<0) return -1; + s += n; l -= n; + } + return 0; +} + +static void my_perror(char *prog, char *msg) +{ + char *err = strerror(errno); + write(2, prog, strlen(prog)); + write(2, ": ", 2); + write(2, msg, strlen(msg)); + write(2, ": ", 2); + write(2, err, strlen(err)); + write(2, "\n", 1); +} + +int main(int argc, char *argv[]) +{ + char buf[4096]; + char **v = argv+1; + int n = argc-1; + ssize_t i, k, l; + int err = 0; + int fd; + + signal(SIGPIPE, SIG_IGN); + + for (; n && v[0][0] == '-' && v[0][1]; v++, n--) { + if (v[0][1]=='-' && !v[0][2]) { /* -- */ + v++; n--; + break; + } + if (v[0][1]!='u' || v[0][2]) { /* not -u */ + errno = EINVAL; + my_perror(argv[0], v[0]); + exit(1); + } + } + if (!n) { + n = 1; + v = (char *[]){ "-", NULL }; + } + for (; n; v++, n--) { + if (v[0][0] == '-' && !v[0][1]) fd = 0; + else if ((fd = open(v[0], O_RDONLY)) < 0) { + my_perror(argv[0], v[0]); + err = 1; + continue; + } + while ((l = read(fd, buf, sizeof buf)) > 0) { + if (my_write(1, buf, l) < 0) { + my_perror(argv[0], "write error"); + exit(1); + } + } + if (l) { + my_perror(argv[0], v[0]); + err = 1; + } + if (fd) close(fd); + } + return err; +} -- cgit v1.2.1