[comp.lang.smalltalk] BS Notes: A file status primitive

rentsch@unc.UUCP (Tim Rentsch) (11/29/86)

For those who want to implement their own primitives in BS but
don't know where to start, here is an example.  The enclosed
differences from three BS source files show the changes we made
locally to implement a 'stat' primitive on files.  This code might
be used, for example, if you were writing a 'Unix File System
Browser' and wanted to duplicate information that 'ls' produces.

The differences are in 'primTable.h', 'primTable.c', and
'unixPrims.c'.  The first two changes are trivial, just enough to
make the primitive vector table point at the new primitive.  The
last file has the real code to implement the primitive.

The Xerox PS interpreter has a large complement of unix system calls
implemented as primitives.  If anyone is interested in continuing
the work of implementing primitives in BS, I would recommend that
you look at how this is done in PS, so that the two systems are
compatible.  (Xerox should consider this to be in their best interest,
and so might cooperate with your effort.  I don't speak for Xerox,
but it's probably worth giving them a call.)

The code given here is fairly straight-forward, I think.  I wrote the
primitive by copying parts of other primitives, and the result has
most of the stuff you will typically need when writing primitives.
(One exception to this is converting back and forth to small
integers.  Maybe someone could post a note on doing that.)  Note
that the primitive given was actually put into a BS system, was
tested, seems to work perfectly, etc.

The Smalltalk hook is in UnixDirectory class, but that is just for
logical consistency.  Since the receiver is ingored, the code could
be anywhere.  Here is sample Smalltalk code (hand supplied, not
checked on the system) to call the primitive:  

  (In UnixDirectory class...)

    primitiveStat: fileName into: statBuffer
	"Do a unix 'stat' system call on the given fileName
	<String> into statBuffer <ByteArray>"

	<primitive:223>
	self primitiveFailed

    statOn: fileName
	"Answer a unix 'stat' on the given fileName <String>"

	| stat |
	stat _ ByteArray new: 60.
	self primitiveStat: fileName into: stat.
	^stat

	"  UnixDirectory statOn: '/dev/null'.  "


Happy hacking.

cheers, 

-txr

----------------------------------------------------------------
% diff newsource/primTable.h oldsource/primTable.h
52c52
< 	StringSystemPrm(), UDStatPrm(),
---
> 	StringSystemPrm(),
----------------------------------------------------------------
% diff newsource/primTable.c oldsource/primTable.c
243c243
< 	UDStatPrm,	/* 223 */
---
> 	UnImplPrm,	/* 223 */
----------------------------------------------------------------
% diff newsource/unixPrims.st oldsource/unixPrims.st
491,536d490
< 
< 
< /*
<  *	UnixDirectory class primitiveStat: filename into: statBuffer.
<  *	Added this day April 15, 1986,  by Tim Rentsch at UNC
<  */
< 
< # include	<sys/stat.h>
< 
< rp_t
< UDStatPrm(rp, ac, nargs )
< oop_t *rp;
< rp_t ac;
< int nargs;
< {
< 	char	namebuf[BUFSIZ];
< 	register rp_t	oopStatBuf;
< 	register byte_t	*p;
< 
< 	int	i, j;
< 	char	*cp;
< 	struct	stat	statbuf, *statp;
< 	statp = &statbuf;
< 
< 	if(  nargs != 2  )  return( NullOop );
< 
< 	getString(rp[1], namebuf, NullOop);
< 
< 	oopStatBuf = (rp_t)rp[2];
< 	if (  	isIntegerObject((oop_t)oopStatBuf)  	||
< 		formatRp(oopStatBuf) != BYTES		||  
< 		lengthRp(oopStatBuf) < sizeof(statbuf)){
< 	    return (NullOop);
< 	}
< 
< 	stat( namebuf, statp );
< 
< 	p = byteFieldRp(oopStatBuf);	cp = (char *) statp;
< 
< 	for(  i = 0;  i < sizeof(statbuf);  i++  ){
< 		p[i] = *cp++;
< 	}
< 	return (ac);
< }
< 
< 
----------------------------------------------------------------