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


Here are extracts from Dynix/PTX 1.2.0 kern_exec.c:


/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

#ident	"$Header: kern_exec.c 1.49 90/05/03 $"

[...]

#define	SHSIZE		32
union exdata {
	char	ex_shell[SHSIZE];
	struct	hdr {
		struct filehdr exec_fhdr;
		struct aouthdr exec_aout;
	} ex_exec;
	struct exec_data ex_data;
};

[...]

exece()
{
[...]
	char	*execnamep;
[...]
	char	*sharg;
	union exdata exdata;
	char	cfarg[SHSIZE];
[...]

	/*
	 * If not a valid executable, see if it's a "#!" file. getxfile()
	 * checks format of the head further.
	 *
	 * Also an ASCII line beginning with #! is the file name of a ``shell''
	 * and arguments may be prepended to the argument list if given here.
	 *
	 * SHELL NAMES ARE LIMITED IN LENGTH.
	 *
	 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
	 * THE ASCII LINE.
	 */

	if (u.u_error == ENOEXEC) {
		if (exdata.ex_shell[0] != '#' || exdata.ex_shell[1] != '!' ||
		    indir) {
			goto bad;
		}
		u.u_error = 0;				/* need to clear */
		cp = &exdata.ex_shell[2];		/* skip "#!" */
		while (cp < &exdata.ex_shell[SHSIZE]) {
			if (*cp == '\t')
				*cp = ' ';
			else if (*cp == '\n') {
				*cp = '\0';
				break;
			}
			cp++;
		}
		if (*cp != '\0') {
			u.u_error = ENOEXEC;
			goto bad;
		}
		cp = &exdata.ex_shell[2];
		while (*cp == ' ')
			cp++;
		execnamep = cp;
		while (*cp && *cp != ' ')
			cp++;
		sharg = NULL;
		if (*cp) {
			*cp++ = '\0';
			while (*cp == ' ')
				cp++;
			if (*cp) {
				bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE);
				sharg = cfarg;
			}
		}
		indir = 1;
		VN_PUT(vp);
		u.u_error = lookupname(execnamep, UIOSEG_KERNEL, FOLLOW_LINK,
						(struct vnode **)0, &vp);
		if (u.u_error) {
			vp = (struct vnode *)0;
			goto bad;
		}
		if (u.u_error = exec_getattr(vp, &vattr))
			goto bad;
		uid = u.u_uid;	/* disallow setuid/setgid shell scripts */
		gid = u.u_gid;
		goto again;
	}
[...]