-/* $OpenBSD: kern_proc.c,v 1.80 2018/02/10 10:32:51 mpi Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.81 2018/02/20 12:38:58 mpi Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
struct pool pgrp_pool;
struct pool session_pool;
+void pgdelete(struct pgrp *);
+void fixjobc(struct process *, struct pgrp *, int);
+
static void orphanpg(struct pgrp *);
#ifdef DEBUG
void pgrpdump(void);
}
/*
- * Move p to a new or existing process group (and session)
- * Caller provides a pre-allocated pgrp and session that should
- * be freed if they are not used.
- * XXX need proctree lock
+ * Move process to a new process group. If a session is provided
+ * then it's a new session to contain this process group; otherwise
+ * the process is staying within its existing session.
*/
-int
-enterpgrp(struct process *pr, pid_t pgid, struct pgrp *newpgrp,
- struct session *newsess)
+void
+enternewpgrp(struct process *pr, struct pgrp *pgrp, struct session *newsess)
{
- struct pgrp *pgrp = pgfind(pgid);
-
#ifdef DIAGNOSTIC
- if (pgrp != NULL && newsess) /* firewalls */
- panic("enterpgrp: setsid into non-empty pgrp");
if (SESS_LEADER(pr))
- panic("enterpgrp: session leader attempted setpgrp");
+ panic("%s: session leader attempted setpgrp", __func__);
#endif
- if (pgrp == NULL) {
+
+ if (newsess != NULL) {
/*
- * new process group
+ * New session. Initialize it completely
*/
+ timeout_set(&newsess->s_verauthto, zapverauth, newsess);
+ newsess->s_leader = pr;
+ newsess->s_count = 1;
+ newsess->s_ttyvp = NULL;
+ newsess->s_ttyp = NULL;
+ memcpy(newsess->s_login, pr->ps_session->s_login,
+ sizeof(newsess->s_login));
+ atomic_clearbits_int(&pr->ps_flags, PS_CONTROLT);
+ pgrp->pg_session = newsess;
#ifdef DIAGNOSTIC
- if (pr->ps_pid != pgid)
- panic("enterpgrp: new pgrp and pid != pgid");
-#endif
-
- pgrp = newpgrp;
- if (newsess) {
- /*
- * new session
- */
- newsess->s_leader = pr;
- newsess->s_count = 1;
- newsess->s_ttyvp = NULL;
- newsess->s_ttyp = NULL;
- memcpy(newsess->s_login, pr->ps_session->s_login,
- sizeof(newsess->s_login));
- atomic_clearbits_int(&pr->ps_flags, PS_CONTROLT);
- pgrp->pg_session = newsess;
-#ifdef DIAGNOSTIC
- if (pr != curproc->p_p)
- panic("enterpgrp: mksession but not curproc");
+ if (pr != curproc->p_p)
+ panic("%s: mksession but not curproc", __func__);
#endif
- } else {
- pgrp->pg_session = pr->ps_session;
- pgrp->pg_session->s_count++;
- }
- pgrp->pg_id = pgid;
- LIST_INIT(&pgrp->pg_members);
- LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
- pgrp->pg_jobc = 0;
- } else if (pgrp == pr->ps_pgrp) {
- if (newsess)
- pool_put(&session_pool, newsess);
- pool_put(&pgrp_pool, newpgrp);
- return (0);
} else {
- if (newsess)
- pool_put(&session_pool, newsess);
- pool_put(&pgrp_pool, newpgrp);
+ pgrp->pg_session = pr->ps_session;
+ pgrp->pg_session->s_count++;
}
+ pgrp->pg_id = pr->ps_pid;
+ LIST_INIT(&pgrp->pg_members);
+ LIST_INSERT_HEAD(PGRPHASH(pr->ps_pid), pgrp, pg_hash);
+ pgrp->pg_jobc = 0;
+
+ enterthispgrp(pr, pgrp);
+}
+
+/*
+ * move process to an existing process group
+ */
+void
+enterthispgrp(struct process *pr, struct pgrp *pgrp)
+{
+ struct pgrp *savepgrp = pr->ps_pgrp;
/*
* Adjust eligibility of affected pgrps to participate in job control.
* could reach 0 spuriously during the first call.
*/
fixjobc(pr, pgrp, 1);
- fixjobc(pr, pr->ps_pgrp, 0);
+ fixjobc(pr, savepgrp, 0);
LIST_REMOVE(pr, ps_pglist);
- if (LIST_EMPTY(&pr->ps_pgrp->pg_members))
- pgdelete(pr->ps_pgrp);
pr->ps_pgrp = pgrp;
LIST_INSERT_HEAD(&pgrp->pg_members, pr, ps_pglist);
- return (0);
+ if (LIST_EMPTY(&savepgrp->pg_members))
+ pgdelete(savepgrp);
}
/*
-/* $OpenBSD: kern_prot.c,v 1.72 2018/02/19 08:59:52 mpi Exp $ */
+/* $OpenBSD: kern_prot.c,v 1.73 2018/02/20 12:38:58 mpi Exp $ */
/* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */
/*
pid_t pid = pr->ps_pid;
newsess = pool_get(&session_pool, PR_WAITOK);
- timeout_set(&newsess->s_verauthto, zapverauth, newsess);
newpgrp = pool_get(&pgrp_pool, PR_WAITOK);
- if (pr->ps_pgid == pid || pgfind(pid)) {
+ if (pr->ps_pgid == pid || pgfind(pid) != NULL) {
pool_put(&pgrp_pool, newpgrp);
pool_put(&session_pool, newsess);
return (EPERM);
} else {
- (void) enterpgrp(pr, pid, newpgrp, newsess);
+ enternewpgrp(pr, newpgrp, newsess);
*retval = pid;
return (0);
}
}
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 = 0;
+ if ((pgrp = pgfind(pgid)) == NULL) {
+ /* can only create a new process group with pgid == pid */
+ if (pgid != targpr->ps_pid)
error = EPERM;
- goto out;
+ else {
+ enternewpgrp(targpr, newpgrp, NULL);
+ newpgrp = NULL;
}
- return (enterpgrp(targpr, pgid, newpgrp, NULL));
-out:
- pool_put(&pgrp_pool, newpgrp);
+ } else if (pgrp != targpr->ps_pgrp) { /* anything to do? */
+ if (pgid != targpr->ps_pid &&
+ pgrp->pg_session != curpr->ps_session)
+ error = EPERM;
+ else
+ enterthispgrp(targpr, pgrp);
+ }
+ out:
+ if (newpgrp != NULL)
+ pool_put(&pgrp_pool, newpgrp);
return (error);
}
-/* $OpenBSD: proc.h,v 1.245 2018/02/10 10:32:51 mpi Exp $ */
+/* $OpenBSD: proc.h,v 1.246 2018/02/20 12:38:58 mpi Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
int (*pr)(const char *, ...));
int chgproccnt(uid_t uid, int diff);
-int enterpgrp(struct process *, pid_t, struct pgrp *, struct session *);
-void fixjobc(struct process *, struct pgrp *, int);
+void enternewpgrp(struct process *, struct pgrp *, struct session *);
+void enterthispgrp(struct process *, struct pgrp *);
int inferior(struct process *, struct process *);
void leavepgrp(struct process *);
void killjobc(struct process *);
void preempt(void);
-void pgdelete(struct pgrp *);
void procinit(void);
void resetpriority(struct proc *);
void setrunnable(struct proc *);