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); < } < < ----------------------------------------------------------------