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*37524Smckusick * @(#)kern_proc.c 7.4 (Berkeley) 04/25/89 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 29*37524Smckusick #include "machine/reg.h" 30*37524Smckusick #include "machine/pte.h" 31*37524Smckusick #include "machine/psl.h" 32*37524Smckusick 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; 12035810Smarc register n; 12135810Smarc 12235810Smarc if (pgrp && mksess) /* firewalls */ 12335810Smarc panic("pgmv: setsid into non-empty pgrp %d\n", pgid); 12435810Smarc if (SESS_LEADER(p)) 12535810Smarc panic("pgmv: session leader attempted setpgrp\n"); 12635810Smarc if (!pgrp) { 12735810Smarc /* 12835810Smarc * new process group 12935810Smarc */ 13035810Smarc if (p->p_pid != pgid) 13135810Smarc panic("pgmv: new pgrp and pid != pgid\n"); 13235810Smarc MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 13335810Smarc M_WAITOK); 13435810Smarc if (mksess) { 13535810Smarc register struct session *sess; 13635810Smarc /* 13735810Smarc * new session 13835810Smarc */ 13935810Smarc MALLOC(sess, struct session *, sizeof(struct session), 14035810Smarc M_SESSION, M_WAITOK); 14135810Smarc sess->s_leader = p; 14235810Smarc sess->s_count = 1; 14335810Smarc pgrp->pg_session = sess; 14435810Smarc if (p != u.u_procp) 14535810Smarc panic("pgmv: mksession and p != u.u_procp"); 14635810Smarc u.u_ttyp = 0; 14735810Smarc u.u_ttyd = 0; 14835810Smarc } else { 14935810Smarc pgrp->pg_session = p->p_session; 15035810Smarc pgrp->pg_session->s_count++; 15135810Smarc } 15235810Smarc pgrp->pg_id = pgid; 15335810Smarc pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)]; 15435810Smarc pgrphash[n] = pgrp; 15535810Smarc pgrp->pg_jobc = 0; 15635810Smarc pgrp->pg_mem = 0; 15735810Smarc } 15835810Smarc /* 15935810Smarc * adjust eligibility of affected pgrps to participate in job control 16035810Smarc */ 16135810Smarc if (PGRP_JOBC(p)) 16235810Smarc p->p_pgrp->pg_jobc--; 16335810Smarc for (cp = p->p_cptr; cp; cp = cp->p_osptr) 16435810Smarc if (PGRP_JOBC(cp)) 16535810Smarc cp->p_pgrp->pg_jobc--; 16635810Smarc /* 16735810Smarc * unlink p from old process group 16835810Smarc */ 16935810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 17035810Smarc if (*pp == p) { 17135810Smarc *pp = p->p_pgrpnxt; 17235810Smarc goto done; 17335810Smarc } 17435810Smarc panic("pgmv: can't find p on old pgrp\n"); 17535810Smarc done: 17635810Smarc /* 17735810Smarc * link into new one 17835810Smarc */ 17935810Smarc p->p_pgrpnxt = pgrp->pg_mem; 18035810Smarc pgrp->pg_mem = p; 18135810Smarc p->p_pgrp = pgrp; 18235810Smarc /* 18335810Smarc * adjust eligibility of affected pgrps to participate in job control 18435810Smarc */ 18535810Smarc if (PGRP_JOBC(p)) 18635810Smarc p->p_pgrp->pg_jobc++; 18735810Smarc for (cp = p->p_cptr; cp; cp = cp->p_osptr) 18835810Smarc if (PGRP_JOBC(cp)) 18935810Smarc cp->p_pgrp->pg_jobc++; 19035810Smarc /* 19135810Smarc * old pgrp empty? 19235810Smarc */ 19335810Smarc if (!p->p_pgrp->pg_mem) 19435810Smarc pgdelete(p->p_pgrp); 19535810Smarc } 19635810Smarc 19735810Smarc /* 19835810Smarc * remove process from process group 19935810Smarc */ 20035810Smarc pgrm(p) 20135810Smarc register struct proc *p; 20235810Smarc { 20335810Smarc register struct proc **pp = &p->p_pgrp->pg_mem; 20435810Smarc register struct proc *cp; 20535810Smarc 20635810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 20735810Smarc if (*pp == p) { 20835810Smarc *pp = p->p_pgrpnxt; 20935810Smarc goto done; 21035810Smarc } 21135810Smarc panic("pgrm: can't find p in pgrp\n"); 21235810Smarc done: 21335810Smarc if (!p->p_pgrp->pg_mem) 21435810Smarc pgdelete(p->p_pgrp); 21535810Smarc p->p_pgrp = 0; 21635810Smarc } 21735810Smarc 21835810Smarc /* 21935810Smarc * delete a process group 22035810Smarc */ 22135810Smarc pgdelete(pgrp) 22235810Smarc register struct pgrp *pgrp; 22335810Smarc { 22435810Smarc register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 22535810Smarc 22635810Smarc for (; *pgp; pgp = &(*pgp)->pg_hforw) 22735810Smarc if (*pgp == pgrp) { 22835810Smarc *pgp = pgrp->pg_hforw; 22935810Smarc goto done; 23035810Smarc } 23135810Smarc panic("pgdelete: can't find pgrp on hash chain\n"); 23235810Smarc done: 23335810Smarc if (--pgrp->pg_session->s_count == 0) 23435810Smarc FREE(pgrp->pg_session, M_SESSION); 23535810Smarc FREE(pgrp, M_PGRP); 23635810Smarc } 23735810Smarc 23835810Smarc /* 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 } 26435810Smarc 26535810Smarc /* DEBUG */ 26635810Smarc pgrpdump() 26735810Smarc { 26835810Smarc register struct pgrp *pgrp; 26935810Smarc register struct proc *p; 27035810Smarc register i; 27135810Smarc 27235810Smarc for (i=0; i<PIDHSZ; i++) { 27335810Smarc if (pgrphash[i]) { 27435810Smarc printf("\tindx %d\n", i); 27535810Smarc for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 27635810Smarc printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 27735810Smarc pgrp, pgrp->pg_id, pgrp->pg_session, 27835810Smarc pgrp->pg_session->s_count, pgrp->pg_mem); 27935810Smarc for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 28035810Smarc printf("\t\tpid %d addr %x pgrp %x\n", 28135810Smarc p->p_pid, p, p->p_pgrp); 28235810Smarc } 28335810Smarc } 28435810Smarc 28535810Smarc } 28635810Smarc } 28735810Smarc } 288