123371Smckusick /* 229091Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323371Smckusick * All rights reserved. The Berkeley software License Agreement 423371Smckusick * specifies the terms and conditions for redistribution. 523371Smckusick * 6*35810Smarc * @(#)kern_proc.c 7.3 (Berkeley) 10/18/88 723371Smckusick */ 836Sbill 99753Ssam #include "../machine/reg.h" 109753Ssam #include "../machine/pte.h" 119753Ssam #include "../machine/psl.h" 129753Ssam 1317091Sbloom #include "param.h" 1417091Sbloom #include "systm.h" 1517091Sbloom #include "map.h" 1617091Sbloom #include "dir.h" 1717091Sbloom #include "user.h" 1817091Sbloom #include "kernel.h" 1917091Sbloom #include "proc.h" 2017091Sbloom #include "buf.h" 2117091Sbloom #include "seg.h" 2217091Sbloom #include "acct.h" 2317091Sbloom #include "wait.h" 2417091Sbloom #include "vm.h" 2517091Sbloom #include "text.h" 2617091Sbloom #include "file.h" 2717091Sbloom #include "quota.h" 2817091Sbloom #include "uio.h" 29*35810Smarc #include "malloc.h" 3017091Sbloom #include "mbuf.h" 31*35810Smarc #include "tty.h" 3236Sbill 3317540Skarels /* 3425385Skarels * Clear any pending stops for top and all descendents. 3517540Skarels */ 3625385Skarels spgrp(top) 3717540Skarels struct proc *top; 387497Sroot { 3917540Skarels register struct proc *p; 407497Sroot int f = 0; 417497Sroot 4217540Skarels p = top; 4317540Skarels for (;;) { 4425385Skarels p->p_sig &= 4517540Skarels ~(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU)); 467497Sroot f++; 477497Sroot /* 4817540Skarels * If this process has children, descend to them next, 4917540Skarels * otherwise do any siblings, and if done with this level, 5017540Skarels * follow back up the tree (but not past top). 517497Sroot */ 5217540Skarels if (p->p_cptr) 5317540Skarels p = p->p_cptr; 5417540Skarels else if (p == top) 5517540Skarels return (f); 5617540Skarels else if (p->p_osptr) 5717540Skarels p = p->p_osptr; 5817540Skarels else for (;;) { 5917540Skarels p = p->p_pptr; 6017540Skarels if (p == top) 6117540Skarels return (f); 6217540Skarels if (p->p_osptr) { 6317540Skarels p = p->p_osptr; 6417540Skarels break; 6517540Skarels } 6617540Skarels } 677497Sroot } 687497Sroot } 697497Sroot 7036Sbill /* 717497Sroot * Is p an inferior of the current process? 7236Sbill */ 737497Sroot inferior(p) 747816Sroot register struct proc *p; 7536Sbill { 767497Sroot for (; p != u.u_procp; p = p->p_pptr) 777497Sroot if (p->p_ppid == 0) 787497Sroot return (0); 797497Sroot return (1); 8036Sbill } 817816Sroot 827816Sroot struct proc * 837816Sroot pfind(pid) 84*35810Smarc register pid; 857816Sroot { 867816Sroot register struct proc *p; 877816Sroot 88*35810Smarc for (p = &proc[pidhash[PIDHASH(pid)]] ; 89*35810Smarc p != &proc[0]; p = &proc[p->p_idhash]) 907816Sroot if (p->p_pid == pid) 917816Sroot return (p); 927816Sroot return ((struct proc *)0); 937816Sroot } 9416529Skarels 9516529Skarels /* 96*35810Smarc * Locate a process group by number 97*35810Smarc */ 98*35810Smarc struct pgrp * 99*35810Smarc pgfind(pgid) 100*35810Smarc register pid_t pgid; 101*35810Smarc { 102*35810Smarc register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; 103*35810Smarc 104*35810Smarc for (; pgrp; pgrp = pgrp->pg_hforw) 105*35810Smarc if (pgrp->pg_id == pgid) 106*35810Smarc return(pgrp); 107*35810Smarc return ((struct pgrp *)0); 108*35810Smarc } 109*35810Smarc 110*35810Smarc /* 111*35810Smarc * Move p to a new or existing process group (and session) 112*35810Smarc */ 113*35810Smarc pgmv(p, pgid, mksess) 114*35810Smarc register struct proc *p; 115*35810Smarc pid_t pgid; 116*35810Smarc { 117*35810Smarc register struct pgrp *pgrp = pgfind(pgid); 118*35810Smarc register struct proc **pp = &p->p_pgrp->pg_mem; 119*35810Smarc register struct proc *cp; 120*35810Smarc register n; 121*35810Smarc 122*35810Smarc if (pgrp && mksess) /* firewalls */ 123*35810Smarc panic("pgmv: setsid into non-empty pgrp %d\n", pgid); 124*35810Smarc if (SESS_LEADER(p)) 125*35810Smarc panic("pgmv: session leader attempted setpgrp\n"); 126*35810Smarc if (!pgrp) { 127*35810Smarc /* 128*35810Smarc * new process group 129*35810Smarc */ 130*35810Smarc if (p->p_pid != pgid) 131*35810Smarc panic("pgmv: new pgrp and pid != pgid\n"); 132*35810Smarc MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 133*35810Smarc M_WAITOK); 134*35810Smarc if (mksess) { 135*35810Smarc register struct session *sess; 136*35810Smarc /* 137*35810Smarc * new session 138*35810Smarc */ 139*35810Smarc MALLOC(sess, struct session *, sizeof(struct session), 140*35810Smarc M_SESSION, M_WAITOK); 141*35810Smarc sess->s_leader = p; 142*35810Smarc sess->s_count = 1; 143*35810Smarc pgrp->pg_session = sess; 144*35810Smarc if (p != u.u_procp) 145*35810Smarc panic("pgmv: mksession and p != u.u_procp"); 146*35810Smarc u.u_ttyp = 0; 147*35810Smarc u.u_ttyd = 0; 148*35810Smarc } else { 149*35810Smarc pgrp->pg_session = p->p_session; 150*35810Smarc pgrp->pg_session->s_count++; 151*35810Smarc } 152*35810Smarc pgrp->pg_id = pgid; 153*35810Smarc pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)]; 154*35810Smarc pgrphash[n] = pgrp; 155*35810Smarc pgrp->pg_jobc = 0; 156*35810Smarc pgrp->pg_mem = 0; 157*35810Smarc } 158*35810Smarc /* 159*35810Smarc * adjust eligibility of affected pgrps to participate in job control 160*35810Smarc */ 161*35810Smarc if (PGRP_JOBC(p)) 162*35810Smarc p->p_pgrp->pg_jobc--; 163*35810Smarc for (cp = p->p_cptr; cp; cp = cp->p_osptr) 164*35810Smarc if (PGRP_JOBC(cp)) 165*35810Smarc cp->p_pgrp->pg_jobc--; 166*35810Smarc /* 167*35810Smarc * unlink p from old process group 168*35810Smarc */ 169*35810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 170*35810Smarc if (*pp == p) { 171*35810Smarc *pp = p->p_pgrpnxt; 172*35810Smarc goto done; 173*35810Smarc } 174*35810Smarc panic("pgmv: can't find p on old pgrp\n"); 175*35810Smarc done: 176*35810Smarc /* 177*35810Smarc * link into new one 178*35810Smarc */ 179*35810Smarc p->p_pgrpnxt = pgrp->pg_mem; 180*35810Smarc pgrp->pg_mem = p; 181*35810Smarc p->p_pgrp = pgrp; 182*35810Smarc /* 183*35810Smarc * adjust eligibility of affected pgrps to participate in job control 184*35810Smarc */ 185*35810Smarc if (PGRP_JOBC(p)) 186*35810Smarc p->p_pgrp->pg_jobc++; 187*35810Smarc for (cp = p->p_cptr; cp; cp = cp->p_osptr) 188*35810Smarc if (PGRP_JOBC(cp)) 189*35810Smarc cp->p_pgrp->pg_jobc++; 190*35810Smarc /* 191*35810Smarc * old pgrp empty? 192*35810Smarc */ 193*35810Smarc if (!p->p_pgrp->pg_mem) 194*35810Smarc pgdelete(p->p_pgrp); 195*35810Smarc } 196*35810Smarc 197*35810Smarc /* 198*35810Smarc * remove process from process group 199*35810Smarc */ 200*35810Smarc pgrm(p) 201*35810Smarc register struct proc *p; 202*35810Smarc { 203*35810Smarc register struct proc **pp = &p->p_pgrp->pg_mem; 204*35810Smarc register struct proc *cp; 205*35810Smarc 206*35810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 207*35810Smarc if (*pp == p) { 208*35810Smarc *pp = p->p_pgrpnxt; 209*35810Smarc goto done; 210*35810Smarc } 211*35810Smarc panic("pgrm: can't find p in pgrp\n"); 212*35810Smarc done: 213*35810Smarc if (!p->p_pgrp->pg_mem) 214*35810Smarc pgdelete(p->p_pgrp); 215*35810Smarc p->p_pgrp = 0; 216*35810Smarc } 217*35810Smarc 218*35810Smarc /* 219*35810Smarc * delete a process group 220*35810Smarc */ 221*35810Smarc pgdelete(pgrp) 222*35810Smarc register struct pgrp *pgrp; 223*35810Smarc { 224*35810Smarc register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 225*35810Smarc 226*35810Smarc for (; *pgp; pgp = &(*pgp)->pg_hforw) 227*35810Smarc if (*pgp == pgrp) { 228*35810Smarc *pgp = pgrp->pg_hforw; 229*35810Smarc goto done; 230*35810Smarc } 231*35810Smarc panic("pgdelete: can't find pgrp on hash chain\n"); 232*35810Smarc done: 233*35810Smarc if (--pgrp->pg_session->s_count == 0) 234*35810Smarc FREE(pgrp->pg_session, M_SESSION); 235*35810Smarc FREE(pgrp, M_PGRP); 236*35810Smarc } 237*35810Smarc 238*35810Smarc /* 23916529Skarels * init the process queues 24016529Skarels */ 24116529Skarels pqinit() 24216529Skarels { 24316529Skarels register struct proc *p; 24416529Skarels 24516529Skarels /* 24616529Skarels * most procs are initially on freequeue 24716529Skarels * nb: we place them there in their "natural" order. 24816529Skarels */ 24916529Skarels 25016529Skarels freeproc = NULL; 25116529Skarels for (p = procNPROC; --p > proc; freeproc = p) 25216529Skarels p->p_nxt = freeproc; 25316529Skarels 25416529Skarels /* 25516529Skarels * but proc[0] is special ... 25616529Skarels */ 25716529Skarels 25816529Skarels allproc = p; 25916529Skarels p->p_nxt = NULL; 26016529Skarels p->p_prev = &allproc; 26116529Skarels 26216529Skarels zombproc = NULL; 26316529Skarels } 264*35810Smarc 265*35810Smarc /* DEBUG */ 266*35810Smarc pgrpdump() 267*35810Smarc { 268*35810Smarc register struct pgrp *pgrp; 269*35810Smarc register struct proc *p; 270*35810Smarc register i; 271*35810Smarc 272*35810Smarc for (i=0; i<PIDHSZ; i++) { 273*35810Smarc if (pgrphash[i]) { 274*35810Smarc printf("\tindx %d\n", i); 275*35810Smarc for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 276*35810Smarc printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 277*35810Smarc pgrp, pgrp->pg_id, pgrp->pg_session, 278*35810Smarc pgrp->pg_session->s_count, pgrp->pg_mem); 279*35810Smarc for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 280*35810Smarc printf("\t\tpid %d addr %x pgrp %x\n", 281*35810Smarc p->p_pid, p, p->p_pgrp); 282*35810Smarc } 283*35810Smarc } 284*35810Smarc 285*35810Smarc } 286*35810Smarc } 287*35810Smarc } 288