Bourne | Ash |  #!  | find | ARG_MAX | Shells | portability | permissions | UUOC | ancient | - | ../Various | HOME
"$@" | echo/printf | set -e | test | tty defs | tty chars | $() vs ) | IFS | using siginfo | nanosleep | line charset | locale


I am glad to have found the following in the TUHS Archive.

I suppose the following was released under the BSD license.

Here are extracts from 2.8BSD /usr/kernel/sys/sys/sys1.c (see PDP-11/Distributions/ucb/ at TUHS archive)

The parts activated by MENLO_* macros are apparently additions from the U.S. Geological Survey in Menlo Park.
(See also /usr/kernel/src/cmd/standalone/tapes/instructions.)
2.8BSD was a v7 kernel with lots of adds+fixes activated by macros. I don't know if #! was taken from Berkeley or from Bell Labs.
MENLO_SCRIPT is not present in any makefile or header and apparently had to be activated manually.



[...]

static	char sccs_id[] = "@(#)sys1.c	3.3";

[...]

exece()
{
	register nc;
	register char *cp;
	register struct buf *bp;
	register struct execa *uap;
	int na, ne, bno, ucp, ap, c;
	struct inode *ip;
# ifdef MENLO_SCRIPT
# define SCRMAG '#!'
	extern int schar();
	int uid,gid,indir;
# endif

	if ((ip = namei(uchar, 0)) == NULL)
		return;
	bno = 0;
	bp = 0;
# ifdef MENLO_SCRIPT
	indir = 0;
	uid = u.u_uid;
	gid = u.u_gid;
	/*formerly if(uid!=0) ...?*/
	if( ip->i_mode&ISUID )
	    uid = ip->i_uid;
	if( ip->i_mode&ISGID )
	    gid = ip->i_gid;
again:
# endif
	if(access(ip, IEXEC))
		goto bad;
	if((ip->i_mode & IFMT) != IFREG ||
	   (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) {
		u.u_error = EACCES;
		goto bad;
	}
# ifdef MENLO_SCRIPT
	/*moved this from getxfile()*/
	u.u_base = (caddr_t)&u.u_exdata;
	u.u_count = sizeof u.u_exdata;
	u.u_offset = 0;
	u.u_segflg = 1;
	readi(ip);
	u.u_segflg = 0;
	if( u.u_error )
	    goto bad;
	/*check if script.  one lvl only*/
	if( indir==0
	 && u.u_exdata.ux_mag==SCRMAG
	 && u.u_count<sizeof u.u_exdata-sizeof u.u_exdata.ux_mag )
	{
	    indir++;
	    cp = (char*)&u.u_exdata+sizeof u.u_exdata.ux_mag;
	    while( *cp==' ' && cp<(char*)&u.u_exdata+sizeof u.u_exdata-1 )
		cp++;
	    u.u_dirp = cp;
	    while( cp<(char*)&u.u_exdata+sizeof u.u_exdata-1
	     && *cp!='\n' )
		cp++;
	    *cp = 000;
	    iput(ip);
	    if( (ip = namei(schar,0))==NULL )
		return;
	    goto again;
	}
	/*other magic numbers are described in getxfile()*/
# endif
	
	/*
	 * Collect arguments on "file" in swap space.
	 */
	na = 0;
	ne = 0;
	nc = 0;
	uap = (struct execa *)u.u_ap;
#ifndef UCB_NKB
	if ((bno = malloc(swapmap, (unsigned) ((NCARGS+BSIZE-1)/BSIZE))) == 0)
		panic("Out of swap");
#else
	if ((bno = malloc(swapmap, (unsigned) ctod((int) btoc(NCARGS+BSIZE)))) == 0)
		panic("Out of swap");
#endif
	if (uap->argp) for (;;) {
		ap = NULL;
# ifdef MENLO_SCRIPT
		/*insert script path name as 1th arg*/
		if( indir && na==1 )
		    ap = uap->fname;
		else
# endif

		[...]



# ifndef MENLO_SCRIPT
	if (getxfile(ip, nc) || u.u_error)
		goto bad;
# else
	if( getxfile(ip,nc,uid,gid) || u.u_error )
	    goto bad;
# endif 

	/*
	 * copy back arglist
	 */

	[...]