summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2018-02-20 12:38:59 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2018-02-20 12:38:59 +0000
commita64adcfa8ca9301c43cce5fc1fc47952dd3fbd41 (patch)
tree80a7effaef28b4cc4f3ed75e1f095d8da6c38e0d /sys
parent9e4ef6b719132193bf380e12e17be5c45cea99a0 (diff)
Introduce enternewpgrp() & enterthispgrp(), from FreeBSD via guenther@.
This code shuffling will ease the introduction of the proctree lock in sys_setsid() and sys_setpgid(). Extracted from a larger diff from guenther@, ok visa@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_proc.c99
-rw-r--r--sys/kern/kern_prot.c32
-rw-r--r--sys/sys/proc.h7
3 files changed, 68 insertions, 70 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 7ca14325220..8ba12226f0d 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1,4 +1,4 @@
-/* $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 $ */
/*
@@ -73,6 +73,9 @@ struct pool ucred_pool;
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);
@@ -222,67 +225,54 @@ zombiefind(pid_t pid)
}
/*
- * 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.
@@ -290,14 +280,13 @@ enterpgrp(struct process *pr, pid_t pgid, struct pgrp *newpgrp,
* 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);
}
/*
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index c5d1a9f8082..ec7ac4d4f32 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1,4 +1,4 @@
-/* $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 $ */
/*
@@ -222,15 +222,14 @@ sys_setsid(struct proc *p, void *v, register_t *retval)
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);
}
@@ -291,15 +290,26 @@ sys_setpgid(struct proc *curp, void *v, register_t *retval)
}
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);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index e79adb5972e..fd0e46e5984 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $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 $ */
/*-
@@ -496,13 +496,12 @@ void proc_printit(struct proc *p, const char *modif,
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 *);