diff --git a/cat/Makefile b/cat/Makefile index c8d9b90..441cb75 100644 --- a/cat/Makefile +++ b/cat/Makefile @@ -1,7 +1,2 @@ cat: cat.c $(CC) -g -o cat cat.c - -clean: - rm -f cat - -.PHONY: clean diff --git a/cat/cat.c b/cat/cat.c index ee58bb5..3e590c3 100644 --- a/cat/cat.c +++ b/cat/cat.c @@ -2,34 +2,31 @@ * ENOENT, ENOMEM, ENOTDIR, EOVERFLOW */ #include /* fprintf(3), getc(3), putc(3), setvbuf(3), stderr, stdin, * stdout */ +#include /* strerror(3) */ #include /* EX_DATAERR, EX_NOINPUT, EX_OK, EX_OSERR, * EX_UNAVAILABLE, EX_USAGE */ #include /* getopt(3) */ #include /* stat(2), struct stat, S_ISDIR */ +static char *program_name = "cat"; + /* NetBSD's default size according to an strace */ static unsigned char buf[4096]; -static char *default_argv[] = { - "cat", - "-", - (char *)NULL -}; -static char *stdin_name = "/dev/stdin"; int main(int argc, char *argv[]){ char *argv0; int c; - extern int errno; struct stat fi; /* info */ char *fn; /* name */ FILE *fo; /* object */ - setvbuf(stdout, buf, _IOFBF, (sizeof buf)/(sizeof *buf)); + setvbuf(stdout, (char *)buf, _IOFBF, (sizeof buf)/(sizeof *buf)); if(argc < 2){ - argc = 2; - if(argc > 0) - default_argv[0] = argv[0]; - argv = default_argv; + argv0 = argc > 0 + ? argv[0] + : program_name; + argv -= argv[0] == NULL; + goto simple; } while((c = getopt(argc, argv, "hu")) != -1) @@ -37,52 +34,42 @@ int main(int argc, char *argv[]){ case 'u': setvbuf(stdout, NULL, _IONBF, 0); continue; - case 'h': default: usage: + default: fprintf(stderr, "Usage: %s (-h) (file...)\n", argv[0]); return EX_USAGE; } + argv0 = argv[0]; - argc -= optind; argv += optind; - while(argc --> 0){ - if(argv[0][0] == '-' && argv[0][1] == '\0'){ /* "-" */ - fn = stdin_name; - fo = stdin; - }else{ + while(*argv != NULL){ + if(argv[0][0] == '-' && argv[0][1] == '\0') /* "-" */ +simple: fo = stdin; + else{ fn = argv[0]; if(stat(fn, &fi) == -1){ + fprintf(stderr, "%s: %s: %s\n", argv0, fn, + strerror(errno)); switch(errno){ case EFAULT: case ENOENT: case ENOTDIR: - fprintf(stderr, - "%s: %s: Unable to open file." - " Does it exist?\n", - argv[0], fn); return EX_NOINPUT; case EBADF: case EINVAL: case ENOMEM: case EOVERFLOW: - fprintf(stderr, - "%s: %s: System error" - " (errno=%d),\n", - argv[0], fn, errno); return EX_OSERR; case ELOOP: case ENAMETOOLONG: - fprintf(stderr, - "%s: %s: Unable to open file.", - argv[0], fn); return EX_DATAERR; } } if(S_ISDIR(fi.st_mode)){ - fprintf(stderr, "%s: %s: Is a directory.\n", + fprintf(stderr, "%s: %s: Is a directory\n", argv[0], fn); return EX_DATAERR; } if((fo = fopen(fn, "r")) == NULL){ fprintf(stderr, - "%s: %s: Error opening file.\n", - argv[0], fn); + "%s: %s: %s\n", + argv0, fn, strerror(errno)); return EX_OSERR; } } @@ -92,13 +79,15 @@ int main(int argc, char *argv[]){ fprintf(stderr, "%s: Exiting due to error writing to" " output...\n", - argv[0]); + argv0); fclose(fo); return EX_UNAVAILABLE; } if(fo != stdin) fclose(fo); + + ++argv; } return EX_OK;