示例#1
0
/*
 * set process group (setpgid/old setpgrp)
 *
 * caller does setpgid(targpid, targpgid)
 *
 * pid must be caller or child of caller (ESRCH)
 * if a child
 *	pid must be in same session (EPERM)
 *	pid can't have done an exec (EACCES)
 * if pgid != pid
 * 	there must exist some pid in same session having pgid (EPERM)
 * pid must not be session leader (EPERM)
 */
int
sys_setpgid(struct setpgid_args *uap)
{
	struct proc *curp = curproc;
	struct proc *targp;		/* target process */
	struct pgrp *pgrp = NULL;	/* target pgrp */
	int error;

	if (uap->pgid < 0)
		return (EINVAL);

	if (uap->pid != 0 && uap->pid != curp->p_pid) {
		if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) {
			if (targp)
				PRELE(targp);
			error = ESRCH;
			targp = NULL;
			goto done;
		}
		lwkt_gettoken(&targp->p_token);
		/* targp now referenced and its token is held */

		if (targp->p_pgrp == NULL ||
		    targp->p_session != curp->p_session) {
			error = EPERM;
			goto done;
		}
		if (targp->p_flags & P_EXEC) {
			error = EACCES;
			goto done;
		}
	} else {
		targp = curp;
		PHOLD(targp);
		lwkt_gettoken(&targp->p_token);
	}
	if (SESS_LEADER(targp)) {
		error = EPERM;
		goto done;
	}
	if (uap->pgid == 0) {
		uap->pgid = targp->p_pid;
	} else if (uap->pgid != targp->p_pid) {
		if ((pgrp = pgfind(uap->pgid)) == NULL ||
	            pgrp->pg_session != curp->p_session) {
			error = EPERM;
			goto done;
		}
	}
	error = enterpgrp(targp, uap->pgid, 0);
done:
	if (pgrp)
		pgrel(pgrp);
	if (targp) {
		lwkt_reltoken(&targp->p_token);
		PRELE(targp);
	}
	return (error);
}
示例#2
0
/* ARGSUSED */
int
sys_setpgid(struct proc *curp, void *v, register_t *retval)
{
	struct sys_setpgid_args /* {
		syscallarg(pid_t) pid;
		syscallarg(int) pgid;
	} */ *uap = v;
	struct process *curpr = curp->p_p;
	struct process *targpr;		/* target process */
	struct pgrp *pgrp, *newpgrp;	/* target pgrp */
	pid_t pid;
	int pgid, error;

	pid = SCARG(uap, pid);
	pgid = SCARG(uap, pgid);

	if (pgid < 0)
		return (EINVAL);

	newpgrp = pool_get(&pgrp_pool, PR_WAITOK);

	if (pid != 0 && pid != curpr->ps_pid) {
		if ((targpr = prfind(pid)) == 0 || !inferior(targpr, curpr)) {
			error = ESRCH;
			goto out;
		}
		if (targpr->ps_session != curpr->ps_session) {
			error = EPERM;
			goto out;
		}
		if (targpr->ps_flags & PS_EXEC) {
			error = EACCES;
			goto out;
		}
	} else
		targpr = curpr;
	if (SESS_LEADER(targpr)) {
		error = EPERM;
		goto out;
	}
	if (pgid == 0)
		pgid = targpr->ps_pid;
	else if (pgid != targpr->ps_pid)
		if ((pgrp = pgfind(pgid)) == 0 ||
		    pgrp->pg_session != curpr->ps_session) {
			error = EPERM;
			goto out;
		}
	return (enterpgrp(targpr, pgid, newpgrp, NULL));
out:
	pool_put(&pgrp_pool, newpgrp);
	return (error);
}
示例#3
0
int
sys_setsid(struct setsid_args *uap)
{
	struct proc *p = curproc;
	struct pgrp *pg = NULL;
	int error;

	lwkt_gettoken(&p->p_token);
	if (p->p_pgid == p->p_pid || (pg = pgfind(p->p_pid)) != NULL) {
		error = EPERM;
		if (pg)
			pgrel(pg);
	} else {
		enterpgrp(p, p->p_pid, 1);
		uap->sysmsg_result = p->p_pid;
		error = 0;
	}
	lwkt_reltoken(&p->p_token);
	return (error);
}
示例#4
0
/*
 * setpgid - set process group ID for job control.
 *
 * If the specified pid is equal to 0, the process ID of
 * the calling process is used. Also, if pgid is 0, the process
 * ID of the indicated process is used.
 */
int
sys_setpgid(pid_t pid, pid_t pgid)
{
	struct proc *p;

	DPRINTF(("proc: setpgid pid=%d pgid=%d\n", pid, pgid));

	if (pid == 0)
		p = curproc;
	else {
		if ((p = p_find(pid)) == NULL)
			return ESRCH;
	}
	if (pgid < 0)
		return EINVAL;
	if (pgid == 0)
		pgid = p->p_pid;
	if (p->p_pgrp->pg_pgid == pgid)	/* already leader */
		return 0;
	return (enterpgrp(p, pgid));
}
示例#5
0
/* ARGSUSED */
int
sys_setsid(struct proc *p, void *v, register_t *retval)
{
	struct session *newsess;
	struct pgrp *newpgrp;
	struct process *pr = p->p_p;
	pid_t pid = pr->ps_pid;

	newsess = pool_get(&session_pool, PR_WAITOK);
	newpgrp = pool_get(&pgrp_pool, PR_WAITOK);

	if (pr->ps_pgid == pid || pgfind(pid)) {
		pool_put(&pgrp_pool, newpgrp);
		pool_put(&session_pool, newsess);
		return (EPERM);
	} else {
		(void) enterpgrp(pr, pid, newpgrp, newsess);
		*retval = pid;
		return (0);
	}
}
示例#6
0
/*
 * setsid - create session and set process group ID.
 */
int
sys_setsid(pid_t *retval)
{
	struct proc *p;
	struct pgrp *pgrp;
	struct session *sess;
	int error;

	DPRINTF(("proc: setsid sid=%d\n", curproc->p_pid));

	p = curproc;
	if (p->p_pid == p->p_pgrp->pg_pgid)	/* already leader */
		return EPERM;

	if ((sess = malloc(sizeof(struct session))) == NULL)
		return ENOMEM;
	memset(sess, 0, sizeof(*sess));

	/*
	 * Create a new process group.
	 */
	if ((error = enterpgrp(p, p->p_pid)) != 0) {
		free(sess);
		return error;
	}
	pgrp = p->p_pgrp;

	/*
	 * Create a new session.
	 */
	sess->s_refcnt = 1;
	sess->s_leader = p;
	sess->s_ttyhold = 0;
	pgrp->pg_session = sess;

	*retval = p->p_pid;
	return 0;
}