Name: Anonymous 2011-09-26 2:54
Tell me about your cat(s), /prog/.
cats you want.cat:/* @cat.c */
/* NOTE: GNU's cat will not cat a file into itself. Should we check for this?
Possibility of infinite loop here. POSIX doesn't specify what happens if
standard input happens to be standard output (cat to temp. file and then
write that to the output? don't write what was already written?) */
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define CATBUF_SIZE 65536 /* increase this if you want OMG MOAR SPEED! */
char catbuf[CATBUF_SIZE];
int main(int argc, char** argv) {
int uflag = 0, retval = 0, i = 1, c;
FILE *input;
while((c=getopt(argc,argv,"u"))!=-1)
if(c=='u') {
uflag=1;
retval=setvbuf(stdout,NULL,_IONBF,0);
} else {
fprintf(stderr,"usage: %s [-u] file...\n",argv[0]);
return 1;
}
if(optind>=argc) { /* catting stdin */
input=stdin;
goto cat_stdin;
}
i=optind;
while(argv[i]) {
int l;
if(strcmp(argv[i],"-")) {
if(!(input=fopen(argv[i++],"rb"))) {
fprintf(stderr,"%s: could not open %s: %s\n",argv[0],argv[i-1],strerror(errno));
retval=1;
continue;
}
} else {
input=stdin;
i++;
}
cat_stdin:
if(uflag)
retval|=setvbuf(input, NULL, _IONBF, 0);
while(l=fread(catbuf,1,CATBUF_SIZE,input)) {
if(fwrite(catbuf,1,l,stdout)!=l) {
fprintf(stderr,"%s: error writing to stdout: %s\n",argv[0],strerror(errno));
retval=1;
break;
}
}
if(ferror(input))
fprintf(stderr,"%s: error reading %s: %s\n",argv[0],argv[i-1],strerror(errno));
if(input!=stdin)
retval|=fclose(input);
}
return retval;
}