1
0
This commit is contained in:
dtb 2023-10-08 12:11:44 -04:00
parent dba3120da6
commit 182720118a
2 changed files with 23 additions and 39 deletions

View File

@ -1,7 +1,2 @@
cat: cat.c
$(CC) -g -o cat cat.c
clean:
rm -f cat
.PHONY: clean

View File

@ -2,34 +2,31 @@
* ENOENT, ENOMEM, ENOTDIR, EOVERFLOW */
#include <stdio.h> /* fprintf(3), getc(3), putc(3), setvbuf(3), stderr, stdin,
* stdout */
#include <string.h> /* strerror(3) */
#include <sysexits.h> /* EX_DATAERR, EX_NOINPUT, EX_OK, EX_OSERR,
* EX_UNAVAILABLE, EX_USAGE */
#include <unistd.h> /* getopt(3) */
#include <sys/stat.h> /* 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;