/*
* 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 <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
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;
}