Beispiel #1
0
void
post_execve(struct thread *td, int error, struct vmspace *oldvmspace)
{
	struct proc *p;

	KASSERT(td == curthread, ("non-current thread %p", td));
	p = td->td_proc;
	if ((p->p_flag & P_HADTHREADS) != 0) {
		PROC_LOCK(p);
		/*
		 * If success, we upgrade to SINGLE_EXIT state to
		 * force other threads to suicide.
		 */
		if (error == 0)
			thread_single(p, SINGLE_EXIT);
		else
			thread_single_end(p, SINGLE_BOUNDARY);
		PROC_UNLOCK(p);
	}
	if ((td->td_pflags & TDP_EXECVMSPC) != 0) {
		KASSERT(p->p_vmspace != oldvmspace,
		    ("oldvmspace still used"));
		vmspace_free(oldvmspace);
		td->td_pflags &= ~TDP_EXECVMSPC;
	}
}
Beispiel #2
0
static int
fork_norfproc(struct thread *td, int flags)
{
	int error;
	struct proc *p1;

	KASSERT((flags & RFPROC) == 0,
	    ("fork_norfproc called with RFPROC set"));
	p1 = td->td_proc;

	if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) &&
	    (flags & (RFCFDG | RFFDG))) {
		PROC_LOCK(p1);
		if (thread_single(p1, SINGLE_BOUNDARY)) {
			PROC_UNLOCK(p1);
			return (ERESTART);
		}
		PROC_UNLOCK(p1);
	}

	error = vm_forkproc(td, NULL, NULL, NULL, flags);
	if (error)
		goto fail;

	/*
	 * Close all file descriptors.
	 */
	if (flags & RFCFDG) {
		struct filedesc *fdtmp;
		fdtmp = fdinit(td->td_proc->p_fd, false);
		fdescfree(td);
		p1->p_fd = fdtmp;
	}

	/*
	 * Unshare file descriptors (from parent).
	 */
	if (flags & RFFDG)
		fdunshare(td);

fail:
	if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) &&
	    (flags & (RFCFDG | RFFDG))) {
		PROC_LOCK(p1);
		thread_single_end(p1, SINGLE_BOUNDARY);
		PROC_UNLOCK(p1);
	}
	return (error);
}