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*37589Smarc * @(#)kern_proc.c 7.3 (Berkeley) 10/18/88 723371Smckusick */ 836Sbill 917091Sbloom #include "param.h" 1017091Sbloom #include "systm.h" 1117091Sbloom #include "map.h" 1217091Sbloom #include "dir.h" 1317091Sbloom #include "user.h" 1417091Sbloom #include "kernel.h" 1517091Sbloom #include "proc.h" 1617091Sbloom #include "buf.h" 1717091Sbloom #include "seg.h" 1817091Sbloom #include "acct.h" 1917091Sbloom #include "wait.h" 2017091Sbloom #include "vm.h" 2117091Sbloom #include "text.h" 2217091Sbloom #include "file.h" 2317091Sbloom #include "quota.h" 2417091Sbloom #include "uio.h" 2535810Smarc #include "malloc.h" 2617091Sbloom #include "mbuf.h" 2735810Smarc #include "tty.h" 2836Sbill 2937524Smckusick #include "machine/reg.h" 3037524Smckusick #include "machine/pte.h" 3137524Smckusick #include "machine/psl.h" 3237524Smckusick 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) 8435810Smarc register pid; 857816Sroot { 867816Sroot register struct proc *p; 877816Sroot 8835810Smarc for (p = &proc[pidhash[PIDHASH(pid)]] ; 8935810Smarc 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 /* 9635810Smarc * Locate a process group by number 9735810Smarc */ 9835810Smarc struct pgrp * 9935810Smarc pgfind(pgid) 10035810Smarc register pid_t pgid; 10135810Smarc { 10235810Smarc register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; 10335810Smarc 10435810Smarc for (; pgrp; pgrp = pgrp->pg_hforw) 10535810Smarc if (pgrp->pg_id == pgid) 10635810Smarc return(pgrp); 10735810Smarc return ((struct pgrp *)0); 10835810Smarc } 10935810Smarc 11035810Smarc /* 11135810Smarc * Move p to a new or existing process group (and session) 11235810Smarc */ 11335810Smarc pgmv(p, pgid, mksess) 11435810Smarc register struct proc *p; 11535810Smarc pid_t pgid; 11635810Smarc { 11735810Smarc register struct pgrp *pgrp = pgfind(pgid); 11835810Smarc register struct proc **pp = &p->p_pgrp->pg_mem; 11935810Smarc register struct proc *cp; 120*37589Smarc struct pgrp *opgrp; 12135810Smarc register n; 12235810Smarc 12335810Smarc if (pgrp && mksess) /* firewalls */ 124*37589Smarc panic("pgmv: setsid into non-empty pgrp"); 12535810Smarc if (SESS_LEADER(p)) 126*37589Smarc panic("pgmv: session leader attempted setpgrp"); 127*37589Smarc if (pgrp == NULL) { 12835810Smarc /* 12935810Smarc * new process group 13035810Smarc */ 13135810Smarc if (p->p_pid != pgid) 132*37589Smarc panic("pgmv: new pgrp and pid != pgid"); 13335810Smarc MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 13435810Smarc M_WAITOK); 13535810Smarc if (mksess) { 13635810Smarc register struct session *sess; 13735810Smarc /* 13835810Smarc * new session 13935810Smarc */ 14035810Smarc MALLOC(sess, struct session *, sizeof(struct session), 14135810Smarc M_SESSION, M_WAITOK); 14235810Smarc sess->s_leader = p; 14335810Smarc sess->s_count = 1; 14435810Smarc pgrp->pg_session = sess; 14535810Smarc if (p != u.u_procp) 14635810Smarc panic("pgmv: mksession and p != u.u_procp"); 147*37589Smarc u.u_ttyp = NULL; 14835810Smarc u.u_ttyd = 0; 14935810Smarc } else { 15035810Smarc pgrp->pg_session = p->p_session; 15135810Smarc pgrp->pg_session->s_count++; 15235810Smarc } 15335810Smarc pgrp->pg_id = pgid; 15435810Smarc pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)]; 15535810Smarc pgrphash[n] = pgrp; 15635810Smarc pgrp->pg_jobc = 0; 15735810Smarc pgrp->pg_mem = 0; 15835810Smarc } 15935810Smarc /* 16035810Smarc * adjust eligibility of affected pgrps to participate in job control 16135810Smarc */ 16235810Smarc if (PGRP_JOBC(p)) 16335810Smarc p->p_pgrp->pg_jobc--; 16435810Smarc for (cp = p->p_cptr; cp; cp = cp->p_osptr) 16535810Smarc if (PGRP_JOBC(cp)) 16635810Smarc cp->p_pgrp->pg_jobc--; 16735810Smarc /* 16835810Smarc * unlink p from old process group 16935810Smarc */ 17035810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 17135810Smarc if (*pp == p) { 17235810Smarc *pp = p->p_pgrpnxt; 17335810Smarc goto done; 17435810Smarc } 175*37589Smarc panic("pgmv: can't find p on old pgrp"); 17635810Smarc done: 17735810Smarc /* 17835810Smarc * link into new one 17935810Smarc */ 18035810Smarc p->p_pgrpnxt = pgrp->pg_mem; 18135810Smarc pgrp->pg_mem = p; 182*37589Smarc opgrp = p->p_pgrp; 18335810Smarc p->p_pgrp = pgrp; 18435810Smarc /* 18535810Smarc * adjust eligibility of affected pgrps to participate in job control 18635810Smarc */ 18735810Smarc if (PGRP_JOBC(p)) 18835810Smarc p->p_pgrp->pg_jobc++; 18935810Smarc for (cp = p->p_cptr; cp; cp = cp->p_osptr) 19035810Smarc if (PGRP_JOBC(cp)) 19135810Smarc cp->p_pgrp->pg_jobc++; 19235810Smarc /* 19335810Smarc * old pgrp empty? 19435810Smarc */ 195*37589Smarc if (!opgrp->pg_mem) 196*37589Smarc pgdelete(opgrp); 19735810Smarc } 19835810Smarc 19935810Smarc /* 20035810Smarc * remove process from process group 20135810Smarc */ 20235810Smarc pgrm(p) 20335810Smarc register struct proc *p; 20435810Smarc { 20535810Smarc register struct proc **pp = &p->p_pgrp->pg_mem; 20635810Smarc register struct proc *cp; 20735810Smarc 20835810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 20935810Smarc if (*pp == p) { 21035810Smarc *pp = p->p_pgrpnxt; 21135810Smarc goto done; 21235810Smarc } 213*37589Smarc panic("pgrm: can't find p in pgrp"); 21435810Smarc done: 21535810Smarc if (!p->p_pgrp->pg_mem) 21635810Smarc pgdelete(p->p_pgrp); 21735810Smarc p->p_pgrp = 0; 21835810Smarc } 21935810Smarc 22035810Smarc /* 22135810Smarc * delete a process group 22235810Smarc */ 22335810Smarc pgdelete(pgrp) 22435810Smarc register struct pgrp *pgrp; 22535810Smarc { 22635810Smarc register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 22735810Smarc 22835810Smarc for (; *pgp; pgp = &(*pgp)->pg_hforw) 22935810Smarc if (*pgp == pgrp) { 23035810Smarc *pgp = pgrp->pg_hforw; 23135810Smarc goto done; 23235810Smarc } 233*37589Smarc panic("pgdelete: can't find pgrp on hash chain"); 23435810Smarc done: 23535810Smarc if (--pgrp->pg_session->s_count == 0) 23635810Smarc FREE(pgrp->pg_session, M_SESSION); 23735810Smarc FREE(pgrp, M_PGRP); 23835810Smarc } 23935810Smarc 24035810Smarc /* 24116529Skarels * init the process queues 24216529Skarels */ 24316529Skarels pqinit() 24416529Skarels { 24516529Skarels register struct proc *p; 24616529Skarels 24716529Skarels /* 24816529Skarels * most procs are initially on freequeue 24916529Skarels * nb: we place them there in their "natural" order. 25016529Skarels */ 25116529Skarels 25216529Skarels freeproc = NULL; 25316529Skarels for (p = procNPROC; --p > proc; freeproc = p) 25416529Skarels p->p_nxt = freeproc; 25516529Skarels 25616529Skarels /* 25716529Skarels * but proc[0] is special ... 25816529Skarels */ 25916529Skarels 26016529Skarels allproc = p; 26116529Skarels p->p_nxt = NULL; 26216529Skarels p->p_prev = &allproc; 26316529Skarels 26416529Skarels zombproc = NULL; 26516529Skarels } 26635810Smarc 26735810Smarc /* DEBUG */ 26835810Smarc pgrpdump() 26935810Smarc { 27035810Smarc register struct pgrp *pgrp; 27135810Smarc register struct proc *p; 27235810Smarc register i; 27335810Smarc 27435810Smarc for (i=0; i<PIDHSZ; i++) { 27535810Smarc if (pgrphash[i]) { 27635810Smarc printf("\tindx %d\n", i); 27735810Smarc for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 27835810Smarc printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 27935810Smarc pgrp, pgrp->pg_id, pgrp->pg_session, 28035810Smarc pgrp->pg_session->s_count, pgrp->pg_mem); 28135810Smarc for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 28235810Smarc printf("\t\tpid %d addr %x pgrp %x\n", 28335810Smarc p->p_pid, p, p->p_pgrp); 28435810Smarc } 28535810Smarc } 28635810Smarc 28735810Smarc } 28835810Smarc } 28935810Smarc } 290