1
0

retire old cat

This commit is contained in:
dtb
2024-01-15 14:26:40 -07:00
parent cb3dac04e9
commit 9915563241
3 changed files with 0 additions and 0 deletions

2
Retired/cat/Makefile Normal file
View File

@@ -0,0 +1,2 @@
cat: cat.c
$(CC) -g -o cat cat.c

44
Retired/cat/cat.1 Normal file
View File

@@ -0,0 +1,44 @@
.TH CAT 1
.SH NAME
cat \(en catenate files
.SH SYNOPSIS
cat
.RB ( -hu )
.RB ( file... )
.SH DESCRIPTION
Cat prints the contents of file arguments, one after the other.
.PP
The
.B -h
option prints the usage synopsis.
.SH BUFFERING
Output is not buffered.
.PP
The
.B -u
option that typically guarantees that output is not buffered is a no-op within this program,
and is included for compatibility with other implementations of cat(1) as well as the POSIX.1 standard.
.SH DIAGNOSTICS
Cat prints an error message and exits with the appropriate status from sysexits(3) if it encounters an error.
.SH BUGS
"Catenate" and "concatenate" mean the same thing in the English language.
.SH STANDARDS
Cat functions as described in POSIX.1-2017.
.SH COPYRIGHT
Public domain.

94
Retired/cat/cat.c Normal file
View File

@@ -0,0 +1,94 @@
#include <errno.h> /* errno, EBADF, EFAULT, EINVAL, ELOOP, ENAMETOOLONG,
* 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];
int main(int argc, char *argv[]){
char *argv0;
int c;
struct stat fi; /* info */
char *fn; /* name */
FILE *fo; /* object */
setvbuf(stdout, (char *)buf, _IOFBF, (sizeof buf)/(sizeof *buf));
if(argc < 2){
argv0 = argc > 0
? argv[0]
: program_name;
argv -= argv[0] == NULL;
goto simple;
}
while((c = getopt(argc, argv, "hu")) != -1)
switch(c){
case 'u':
setvbuf(stdout, NULL, _IONBF, 0);
continue;
default:
fprintf(stderr, "Usage: %s (-h) (file...)\n",
argv[0]);
return EX_USAGE;
}
argv0 = argv[0];
argv += optind;
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:
return EX_NOINPUT;
case EBADF: case EINVAL: case ENOMEM:
case EOVERFLOW:
return EX_OSERR;
case ELOOP: case ENAMETOOLONG:
return EX_DATAERR;
}
}
if(S_ISDIR(fi.st_mode)){
fprintf(stderr, "%s: %s: Is a directory\n",
argv[0], fn);
return EX_DATAERR;
}
if((fo = fopen(fn, "r")) == NULL){
fprintf(stderr,
"%s: %s: %s\n",
argv0, fn, strerror(errno));
return EX_OSERR;
}
}
while((c = getc(fo)) != EOF)
if(putc(c, stdout) == EOF){
fprintf(stderr,
"%s: Exiting due to error writing to"
" output...\n",
argv0);
fclose(fo);
return EX_UNAVAILABLE;
}
if(fo != stdin)
fclose(fo);
++argv;
}
return EX_OK;
}