printf("failed %d\n", i);
sys_execve(p, v, retval)	register struct proc *p;	void *v;	register_t *retval;{	register struct sys_execve_args /* {		syscallarg(char *) path;		syscallarg(char * *) argp;		syscallarg(char * *) envp;	} */ *uap = v;	int error, i;	struct exec_package pack;	struct nameidata nid;	struct vattr attr;	struct ucred *cred = p->p_ucred;	char *argp;	char * const *cpp, *dp, *sp;	long argc, envc;	size_t len;	char *stack;	struct ps_strings arginfo;	struct vmspace *vm = p->p_vmspace;	char **tmpfap;	int szsigcode;	extern struct emul emul_native;	/*	 * figure out the maximum size of an exec header, if necessary.	 * XXX should be able to keep LKM code from modifying exec switch	 * when we're still using it, but...	 */	if (exec_maxhdrsz == 0) {		for (i = 0; i < nexecs; i++)			if (execsw[i].es_check != NULL			    && execsw[i].es_hdrsz > exec_maxhdrsz)				exec_maxhdrsz = execsw[i].es_hdrsz;	}	/* init the namei data to point the file user's program name */	NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);	/*	 * initialize the fields of the exec package.	 */	pack.ep_name = (char *)SCARG(uap, path);	MALLOC(pack.ep_hdr, void *, exec_maxhdrsz, M_EXEC, M_WAITOK);	pack.ep_hdrlen = exec_maxhdrsz;	pack.ep_hdrvalid = 0;	pack.ep_ndp = &nid;	pack.ep_emul_arg = NULL;	pack.ep_vmcmds.evs_cnt = 0;	pack.ep_vmcmds.evs_used = 0;	pack.ep_vap = &attr;	pack.ep_emul = &emul_native;	pack.ep_flags = 0;	/* see if we can run it. */	if ((error = check_exec(p, &pack)) != 0) {		goto freehdr;	}	/* XXX -- THE FOLLOWING SECTION NEEDS MAJOR CLEANUP */	/* allocate an argument buffer */	argp = (char *)kmem_alloc_wait(exec_map, NCARGS);#ifdef DIAGNOSTIC	if (argp == (vm_offset_t) 0)		panic("execve: argp == NULL");#endif	dp = argp;	argc = 0;	/* copy the fake args list, if there's one, freeing it as we go */	if (pack.ep_flags & EXEC_HASARGL) {		tmpfap = pack.ep_fa;		while (*tmpfap != NULL) {			char *cp;			cp = *tmpfap;			while (*cp)				*dp++ = *cp++;			dp++;			FREE(*tmpfap, M_EXEC);			tmpfap++; argc++;		}		FREE(pack.ep_fa, M_EXEC);		pack.ep_flags &= ~EXEC_HASARGL;	}	/* Now get argv & environment */	if (!(cpp = SCARG(uap, argp))) {		error = EINVAL;		goto bad;	}	if (pack.ep_flags & EXEC_SKIPARG)		cpp++;	while (1) {		len = argp + ARG_MAX - dp;		if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)			goto bad;		if (!sp)			break;		if ((error = copyinstr(sp, dp, len, &len)) != 0) {			if (error == ENAMETOOLONG)				error = E2BIG;			goto bad;		}		dp += len;		cpp++;		argc++;	}	envc = 0;	/* environment need not be there */	if ((cpp = SCARG(uap, envp)) != NULL ) {		while (1) {			len = argp + ARG_MAX - dp;			if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)				goto bad;			if (!sp)				break;			if ((error = copyinstr(sp, dp, len, &len)) != 0) {				if (error == ENAMETOOLONG)					error = E2BIG;				goto bad;			}			dp += len;			cpp++;			envc++;		}	}	dp = (char *)ALIGN(dp);	szsigcode = pack.ep_emul->e_esigcode - pack.ep_emul->e_sigcode;	/* Now check if args & environ fit into new stack */	len = ((argc + envc + 2 + pack.ep_emul->e_arglen) * sizeof(char *) +	    sizeof(long) + dp + STACKGAPLEN + szsigcode +	    sizeof(struct ps_strings)) - argp;	len = ALIGN(len);	/* make the stack "safely" aligned */	if (len > pack.ep_ssize) { /* in effect, compare to initial limit */		error = ENOMEM;		goto bad;	}	/* adjust "active stack depth" for process VSZ */	pack.ep_ssize = len;	/* maybe should go elsewhere, but... */	/* Unmap old program */#ifdef sparc	kill_user_windows(p);		/* before stack addresses go away */#endif	/* Kill shared memory and unmap old program */#ifdef SYSVSHM	if (vm->vm_shm)		shmexit(p);#endif	vm_deallocate(&vm->vm_map, VM_MIN_ADDRESS,	    VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS);	/* Now map address space */	vm->vm_taddr = (char *)pack.ep_taddr;	vm->vm_tsize = btoc(pack.ep_tsize);	vm->vm_daddr = (char *)pack.ep_daddr;	vm->vm_dsize = btoc(pack.ep_dsize);	vm->vm_ssize = btoc(pack.ep_ssize);	vm->vm_maxsaddr = (char *)pack.ep_maxsaddr;	/* create the new process's VM space by running the vmcmds */#ifdef DIAGNOSTIC	if (pack.ep_vmcmds.evs_used == 0)		panic("execve: no vmcmds");#endif	for (i = 0; i < pack.ep_vmcmds.evs_used && !error; i++) {		struct exec_vmcmd *vcp;		vcp = &pack.ep_vmcmds.evs_cmds[i];		error = (*vcp->ev_proc)(p, vcp);	}	/* free the vmspace-creation commands, and release their references */	kill_vmcmds(&pack.ep_vmcmds);	/* if an error happened, deallocate and punt */	if (error)		goto exec_abort;	/* remember information about the process */	arginfo.ps_nargvstr = argc;	arginfo.ps_nenvstr = envc;	stack = (char *)(USRSTACK - len);	/* Now copy argc, args & environ to new stack */	if (!(*pack.ep_emul->e_copyargs)(&pack, &arginfo, stack, argp))		goto exec_abort;	/* copy out the process's ps_strings structure */	if (copyout(&arginfo, (char *)PS_STRINGS, sizeof(arginfo)))		goto exec_abort;	/* copy out the process's signal trapoline code */	if (szsigcode && copyout((char *)pack.ep_emul->e_sigcode,	    ((char *)PS_STRINGS) - szsigcode, szsigcode))		goto exec_abort;	fdcloseexec(p);		/* handle close on exec */	execsigs(p);		/* reset catched signals */	/* set command name & other accounting info */	len = min(nid.ni_cnd.cn_namelen, MAXCOMLEN);	bcopy(nid.ni_cnd.cn_nameptr, p->p_comm, len);	p->p_comm[len] = 0;	p->p_acflag &= ~AFORK;	/* record proc's vnode, for use by procfs and others */        if (p->p_textvp)                vrele(p->p_textvp);	VREF(pack.ep_vp);	p->p_textvp = pack.ep_vp;	p->p_flag |= P_EXEC;	if (p->p_flag & P_PPWAIT) {		p->p_flag &= ~P_PPWAIT;		wakeup((caddr_t)p->p_pptr);	}	/*	 * If process does execve() while it has euid/uid or egid/gid	 * which are mismatched, it remains P_SUGIDEXEC.	 */	if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&	    p->p_ucred->cr_gid == p->p_cred->p_rgid)		p->p_flag &= ~P_SUGIDEXEC;	/*	 * deal with set[ug]id.	 * MNT_NOEXEC and P_TRACED have already been used to disable s[ug]id.	 */	if ((attr.va_mode & (VSUID | VSGID))) {		int i;#ifdef KTRACE		/*		 * If process is being ktraced, turn off - unless		 * root set it.		 */		if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) {			p->p_traceflag = 0;			vrele(p->p_tracep);			p->p_tracep = NULL;		}#endif		p->p_ucred = crcopy(cred);		if (attr.va_mode & VSUID)			p->p_ucred->cr_uid = attr.va_uid;		if (attr.va_mode & VSGID)			p->p_ucred->cr_gid = attr.va_gid;		p->p_flag |= P_SUGID;		p->p_flag |= P_SUGIDEXEC;		/*		 * XXX For setuid processes, attempt to ensure that		 * stdin, stdout, and stderr are already allocated.		 * We do not want userland to accidentally allocate		 * descriptors in this range which has implied meaning		 * to libc.		 */		for (i = 0; i < 3; i++) {			extern struct fileops vnops;			struct nameidata nd;			struct file *fp;			int indx;			if (p->p_fd->fd_ofiles[i] == NULL) {				printf("need %d\n", i);				if ((error = falloc(p, &fp, &indx)) != 0)					continue;				NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE,				    "/dev/null", p);				if ((error = vn_open(&nd, FREAD, 0)) != 0) {					printf("failed %d\n", i);					ffree(fp);					p->p_fd->fd_ofiles[indx] = NULL;					break;				}				printf("got %d\n", i);				fp->f_flag = FREAD;				fp->f_type = DTYPE_VNODE;				fp->f_ops = &vnops;				fp->f_data = (caddr_t)nd.ni_vp;				VOP_UNLOCK(nd.ni_vp, 0, p);			}		}	} else		p->p_flag &= ~P_SUGID;	p->p_cred->p_svuid = p->p_ucred->cr_uid;	p->p_cred->p_svgid = p->p_ucred->cr_gid;	if (p->p_flag & P_SUGIDEXEC) {		int i, s = splclock();		untimeout(realitexpire, (void *)p);		timerclear(&p->p_realtimer.it_interval);		timerclear(&p->p_realtimer.it_value);		for (i = 0; i < sizeof(p->p_stats->p_timer) /		    sizeof(p->p_stats->p_timer[0]); i++) {			timerclear(&p->p_stats->p_timer[i].it_interval);			timerclear(&p->p_stats->p_timer[i].it_value);		}		splx(s);	}	kmem_free_wakeup(exec_map, (vm_offset_t)argp, NCARGS);	FREE(nid.ni_cnd.cn_pnbuf, M_NAMEI);	VOP_CLOSE(pack.ep_vp, FREAD, cred, p);	vput(pack.ep_vp);	/* setup new registers and do misc. setup. */	if(pack.ep_emul->e_fixup != NULL) {		if((*pack.ep_emul->e_fixup)(p, &pack) != 0)			goto free_pack_abort;	}	(*pack.ep_emul->e_setregs)(p, &pack, (u_long)stack, retval);	if (p->p_flag & P_TRACED)		psignal(p, SIGTRAP);	p->p_emul = pack.ep_emul;	FREE(pack.ep_hdr, M_EXEC);#ifdef KTRACE	if (KTRPOINT(p, KTR_EMUL))		ktremul(p->p_tracep, p->p_emul->e_name);#endif	return (0);bad:	/* free the vmspace-creation commands, and release their references */	kill_vmcmds(&pack.ep_vmcmds);	/* kill any opened file descriptor, if necessary */	if (pack.ep_flags & EXEC_HASFD) {		pack.ep_flags &= ~EXEC_HASFD;		(void) fdrelease(p, pack.ep_fd);	}	/* close and put the exec'd file */	VOP_CLOSE(pack.ep_vp, FREAD, cred, p);	vput(pack.ep_vp);	FREE(nid.ni_cnd.cn_pnbuf, M_NAMEI);	kmem_free_wakeup(exec_map, (vm_offset_t) argp, NCARGS);freehdr:	FREE(pack.ep_hdr, M_EXEC);	return (error);exec_abort:	/*	 * the old process doesn't exist anymore.  exit gracefully.	 * get rid of the (new) address space we have created, if any, get rid	 * of our namei data and vnode, and exit noting failure	 */	vm_deallocate(&vm->vm_map, VM_MIN_ADDRESS,		VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS);	if (pack.ep_emul_arg)		FREE(pack.ep_emul_arg, M_TEMP);	FREE(nid.ni_cnd.cn_pnbuf, M_NAMEI);	VOP_CLOSE(pack.ep_vp, FREAD, cred, p);	vput(pack.ep_vp);	kmem_free_wakeup(exec_map, (vm_offset_t) argp, NCARGS);free_pack_abort:	FREE(pack.ep_hdr, M_EXEC);	exit1(p, W_EXITCODE(0, SIGABRT));	exit1(p, -1);	/* NOTREACHED */	return (0);}