Rebuttal to: Re: Flame Re: pussyfooting

David Herron, NPR Lover david at ukma.UUCP
Tue Mar 19 18:09:45 AEST 1985


[Oh line eater bug, don't remove the tongue from my cheek]

To all of you who hate the 4.2 cat program, here is a fix (at least
for all those with C compilers).  I, too, didn't care when I typed
cat -n and useful numbers appeared in the output.  What follows is
a *very* simplistic cat program.  It is also fast.  I believe I have
only seen it use less than a second of user time.  (and I haven't
tried it with huge buffers yet, just 1K buffers).  (This includes
catting a 800K file out /dev/null just for kicks).  If the file name
is '-' it reads standard input at that point.  Anything else starting
with a - is ignored (this made it like the program in <1084 at reed.UUCP>).
Also, when run with

	cat door

(and door doesn't exist) it responds with:

	cat: cannot open door

instead of the useful 4.2 cat that says:

	door: No such file or directory

----------------------------------------------------------------

Ok, now that I've got the parody (parity?...no) done.  I read this
article today titled "Re: Flame Re: pussyfooting" (<1084 at reed.UUCP>).
I thought, why would I want to have all my utility programs written
in assembler.  For that is where you are heading once you start doing
some in assembler.  But still his program ran rings around the 4.2
cat program.  So what gave?

So I looked at the source of Berkeley's cat(1) and found it was using
stdio, but in a very tight loop, like this:

	/* AT&T lawyers, please look the other way, thank you :-) */
	while((c=getchar()) != EOF)
		putc(c);

But Keith's program was using read() and write() with a HUGE buffer.
Not really a fair comparison, right?  At any rate, here's some
timings, generated with "time ?cat /src/3b2/text.shar":

	[ fcat == Keith's program
	  mycat == my program as listed below.
	  cat == /bin/cat.  that much maligned program.
	]

	Script started on Tue Mar 19 02:39:19 1985

	% ls -l src/3b2/text.shar
	-rw-r--r--  1 root       834184 Mar 13 19:04 /src/3b2/text.shar
	% time fcat /src/3b2/text.shar >/dev/null
	0.0u 1.7s 0:05 31% 0+90k 207+2io 0pf+0w
	% time mycat /src/3b2/text.shar >/dev/null
	0.1u 4.3s 0:10 43% 1+5k 209+2io 1pf+0w
	% time cat /src/3b2/text.shar >/dev/null
	18.2u 3.9s 0:54 41% 9+17k 208+1io 1pf+0w
	% ^D
	script done on Tue Mar 19 02:42:02 1985

The differences are:

	1. System time between fcat and mycat.  Mycat had a buffer
	   size of 1024 and fcat had one of 49152.  So I'm gonna do
	   quite a few more system calls than he does.
	2. User time between cat and mycat.  Cat uses stdio to copy
	   characters between two buffers.  This surely uses up a lot of
	   time, and isn't even necessary.  Mycat on the other hand 
	   doesn't copy the buffer because it knows better.

What does all this prove?  I dunno.  Other than one should think before coding.

At any rate here is something more portable than Keith's program.

One more thing and I'll leave.  Keith's article (which had a little
talk and a longish assembler program) was 146 lines long.
This one (w/o .signature file) is about 143 lines.  This is with
a copy of my program, a duplicate (almost) of his talk, and a talk
of my own.  The difference is in using C to write the program.

	(-- insert your favorite sermon on the benefits of C --)

--------------------------------------------------------
/*
 *	fcat.c
 *
 * A short program to prove how dorky some people *really* are... :-)
 *
 * To make me, type
 *
 * cc -o fcat fcat.c
 * (Don't have to say "chmod +x fcat").
 *
 * Usage: fcat [files]
 *
 * "files", if missing, is replaced by standard input.
 * If it is a "-", then standard input is inserted at that point.
 */

/*
 * Get values used for open()
 */
#include <sys/file.h>

#define BUFSIZ	1024

char buffer[BUFSIZ];


main(argc, argv)
int argc;
char **argv;
{
	register int fi;	/* For efficiency */
	register int fcount;
	register int nread;

	if (argc > 1) { /* Have lots of files */
		for (fcount=1; argv[fcount] != 0; fcount++) {
			if (argv[fcount][0]=='-' && argv[fcount][1]=='\0') {
				fi = 0;
			}
			else {
				fi = open(argv[fcount], O_RDONLY);
				if (fi < 0) {
					/* Avoid loading stdio */
					write(2, "cat: cannot open ", 17);
					write(2, argv[fcount], strlen(argv[fcount]));
					write(2, "\n", 1);
					continue;
				}
			}
			while ((nread=read(fi, buffer, BUFSIZ)) != 0) 
				write(1, buffer, nread);
			close(fi);
		}
	}
	else {
		while ((nread=read(0, buffer, BUFSIZ)) != 0)
			write(1, buffer, nread);
	}
}

-- 
--- David Herron
--- ARPA-> ukma!david<@ANL-MCS> or david%ukma.uucp at anl-mcs.arpa
---        Or even anlams!ukma!david at ucbvax.arpa
--- UUCP-> {ucbvax,unmvax,boulder,oddjob}!anlams!ukma!david
---        cbosgd!ukma!david

	"The home of poly-unsaturated thinking".



More information about the Comp.unix.wizards mailing list