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 3.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.
 */

#ifndef	lint
static	char	rcsid[] = "$Header: kern_exec.c 2.29 90/06/03 $";
#endif

[...]

execve()
{
	register nc;
	register char *cp;
	register struct buf *bp;
	register struct execa *uap;
	int	na, ne, ucp, ap, cc, len, error;
	int	indir, uid, gid;
	char	*execnamep;
	struct	vnode	*vp;
	struct	ofile_tab *oft = NULL;
	struct	exec_vattr vattr;
	daddr_t	bno;
	struct	pathname pn;
	char	*sharg;
	char	cfarg[SHSIZE];
	union {
		char	ex_shell[SHSIZE];
		struct	exec ex_exec;
	} exdata;
	int	resid;

[...]

	/*
	 * Read in first few bytes of file for segment sizes, ux_mag:
	 *	ZMAGIC = default zero at zero demand paged RO text
	 *	XMAGIC = invalid page at zero demand paged RO text
	 * 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 file header doesn't have a standard magic number, see if
	 * it's a "#!" file.  getxfile() checks format of header further.
	 */

	if (exdata.ex_exec.a_magic!=ZMAGIC && exdata.ex_exec.a_magic!=XMAGIC) {
		if (exdata.ex_shell[0] != '#' || exdata.ex_shell[1] != '!' ||
		    indir) {
			u.u_error = ENOEXEC;
			goto bad;
		}
		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;
		/*
		 * Disallow setuid/setgid on shell scripts.  They provide
		 * a well-known security hole, and were flagged for
		 * deletion in the 3.0.17 release notes.
		 */
		if (suid_script == 0) {
			uid = u.u_uid;
			gid = u.u_gid;
		}

		goto again;
	}

[...]