/* * 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; }