headpats
This commit is contained in:
parent
dba3120da6
commit
182720118a
@ -1,7 +1,2 @@
|
||||
cat: cat.c
|
||||
$(CC) -g -o cat cat.c
|
||||
|
||||
clean:
|
||||
rm -f cat
|
||||
|
||||
.PHONY: clean
|
||||
|
57
cat/cat.c
57
cat/cat.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user