123371Smckusick /* 237728Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 337728Smckusick * All rights reserved. 423371Smckusick * 537728Smckusick * Redistribution and use in source and binary forms are permitted 637728Smckusick * provided that the above copyright notice and this paragraph are 737728Smckusick * duplicated in all such forms and that any documentation, 837728Smckusick * advertising materials, and other materials related to such 937728Smckusick * distribution and use acknowledge that the software was developed 1037728Smckusick * by the University of California, Berkeley. The name of the 1137728Smckusick * University may not be used to endorse or promote products derived 1237728Smckusick * from this software without specific prior written permission. 1337728Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1437728Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1537728Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1637728Smckusick * 17*40709Skarels * @(#)kern_proc.c 7.9 (Berkeley) 04/03/90 1823371Smckusick */ 1936Sbill 2017091Sbloom #include "param.h" 2117091Sbloom #include "systm.h" 2217091Sbloom #include "map.h" 2317091Sbloom #include "user.h" 2417091Sbloom #include "kernel.h" 2517091Sbloom #include "proc.h" 2617091Sbloom #include "buf.h" 2717091Sbloom #include "seg.h" 2817091Sbloom #include "acct.h" 2917091Sbloom #include "wait.h" 3017091Sbloom #include "vm.h" 3117091Sbloom #include "text.h" 3217091Sbloom #include "file.h" 3337728Smckusick #include "../ufs/quota.h" 3417091Sbloom #include "uio.h" 3535810Smarc #include "malloc.h" 3617091Sbloom #include "mbuf.h" 3739064Smarc #include "ioctl.h" 3835810Smarc #include "tty.h" 3936Sbill 4037524Smckusick #include "machine/reg.h" 4137524Smckusick #include "machine/pte.h" 4237524Smckusick #include "machine/psl.h" 4337524Smckusick 4417540Skarels /* 4525385Skarels * Clear any pending stops for top and all descendents. 4617540Skarels */ 4725385Skarels spgrp(top) 4817540Skarels struct proc *top; 497497Sroot { 5017540Skarels register struct proc *p; 517497Sroot int f = 0; 527497Sroot 5317540Skarels p = top; 5417540Skarels for (;;) { 5525385Skarels p->p_sig &= 5617540Skarels ~(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU)); 577497Sroot f++; 587497Sroot /* 5917540Skarels * If this process has children, descend to them next, 6017540Skarels * otherwise do any siblings, and if done with this level, 6117540Skarels * follow back up the tree (but not past top). 627497Sroot */ 6317540Skarels if (p->p_cptr) 6417540Skarels p = p->p_cptr; 6517540Skarels else if (p == top) 6617540Skarels return (f); 6717540Skarels else if (p->p_osptr) 6817540Skarels p = p->p_osptr; 6917540Skarels else for (;;) { 7017540Skarels p = p->p_pptr; 7117540Skarels if (p == top) 7217540Skarels return (f); 7317540Skarels if (p->p_osptr) { 7417540Skarels p = p->p_osptr; 7517540Skarels break; 7617540Skarels } 7717540Skarels } 787497Sroot } 797497Sroot } 807497Sroot 8136Sbill /* 827497Sroot * Is p an inferior of the current process? 8336Sbill */ 847497Sroot inferior(p) 857816Sroot register struct proc *p; 8636Sbill { 877497Sroot for (; p != u.u_procp; p = p->p_pptr) 887497Sroot if (p->p_ppid == 0) 897497Sroot return (0); 907497Sroot return (1); 9136Sbill } 927816Sroot 93*40709Skarels /* 94*40709Skarels * Locate a process by number 95*40709Skarels */ 967816Sroot struct proc * 977816Sroot pfind(pid) 9835810Smarc register pid; 997816Sroot { 100*40709Skarels register struct proc *p = pidhash[PIDHASH(pid)]; 1017816Sroot 102*40709Skarels for (; p; p = p->p_hash) 1037816Sroot if (p->p_pid == pid) 1047816Sroot return (p); 1057816Sroot return ((struct proc *)0); 1067816Sroot } 10716529Skarels 10816529Skarels /* 10935810Smarc * Locate a process group by number 11035810Smarc */ 11135810Smarc struct pgrp * 11235810Smarc pgfind(pgid) 11335810Smarc register pid_t pgid; 11435810Smarc { 11535810Smarc register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; 11635810Smarc 11735810Smarc for (; pgrp; pgrp = pgrp->pg_hforw) 11835810Smarc if (pgrp->pg_id == pgid) 119*40709Skarels return (pgrp); 12035810Smarc return ((struct pgrp *)0); 12135810Smarc } 12235810Smarc 12335810Smarc /* 12435810Smarc * Move p to a new or existing process group (and session) 12535810Smarc */ 12635810Smarc pgmv(p, pgid, mksess) 12735810Smarc register struct proc *p; 12835810Smarc pid_t pgid; 12935810Smarc { 13035810Smarc register struct pgrp *pgrp = pgfind(pgid); 13135810Smarc register struct proc **pp = &p->p_pgrp->pg_mem; 13235810Smarc register struct proc *cp; 13337589Smarc struct pgrp *opgrp; 13435810Smarc register n; 13535810Smarc 13639562Smarc #ifdef DIAGNOSTIC 13735810Smarc if (pgrp && mksess) /* firewalls */ 13837589Smarc panic("pgmv: setsid into non-empty pgrp"); 13935810Smarc if (SESS_LEADER(p)) 14037589Smarc panic("pgmv: session leader attempted setpgrp"); 14139562Smarc #endif 14237589Smarc if (pgrp == NULL) { 14335810Smarc /* 14435810Smarc * new process group 14535810Smarc */ 14639562Smarc #ifdef DIAGNOSTIC 14735810Smarc if (p->p_pid != pgid) 14837589Smarc panic("pgmv: new pgrp and pid != pgid"); 14939562Smarc #endif 15035810Smarc MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 15135810Smarc M_WAITOK); 15235810Smarc if (mksess) { 15335810Smarc register struct session *sess; 15435810Smarc /* 15535810Smarc * new session 15635810Smarc */ 15735810Smarc MALLOC(sess, struct session *, sizeof(struct session), 15835810Smarc M_SESSION, M_WAITOK); 15935810Smarc sess->s_leader = p; 16035810Smarc sess->s_count = 1; 16139562Smarc sess->s_ttyvp = NULL; 16239562Smarc sess->s_ttyp = NULL; 16339562Smarc p->p_flag &= ~SCTTY; 16435810Smarc pgrp->pg_session = sess; 16539562Smarc #ifdef DIAGNOSTIC 16635810Smarc if (p != u.u_procp) 16735810Smarc panic("pgmv: mksession and p != u.u_procp"); 16839562Smarc #endif 16935810Smarc } else { 17035810Smarc pgrp->pg_session = p->p_session; 17135810Smarc pgrp->pg_session->s_count++; 17235810Smarc } 17335810Smarc pgrp->pg_id = pgid; 17435810Smarc pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)]; 17535810Smarc pgrphash[n] = pgrp; 17635810Smarc pgrp->pg_jobc = 0; 17739562Smarc pgrp->pg_mem = NULL; 17835810Smarc } 17935810Smarc /* 18035810Smarc * adjust eligibility of affected pgrps to participate in job control 18135810Smarc */ 18235810Smarc if (PGRP_JOBC(p)) 18335810Smarc p->p_pgrp->pg_jobc--; 18435810Smarc for (cp = p->p_cptr; cp; cp = cp->p_osptr) 18535810Smarc if (PGRP_JOBC(cp)) 18635810Smarc cp->p_pgrp->pg_jobc--; 18735810Smarc /* 18835810Smarc * unlink p from old process group 18935810Smarc */ 19035810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 19135810Smarc if (*pp == p) { 19235810Smarc *pp = p->p_pgrpnxt; 19335810Smarc goto done; 19435810Smarc } 19537589Smarc panic("pgmv: can't find p on old pgrp"); 19635810Smarc done: 19735810Smarc /* 19835810Smarc * link into new one 19935810Smarc */ 20035810Smarc p->p_pgrpnxt = pgrp->pg_mem; 20135810Smarc pgrp->pg_mem = p; 20237589Smarc opgrp = p->p_pgrp; 20335810Smarc p->p_pgrp = pgrp; 20435810Smarc /* 20535810Smarc * adjust eligibility of affected pgrps to participate in job control 20635810Smarc */ 20735810Smarc if (PGRP_JOBC(p)) 20835810Smarc p->p_pgrp->pg_jobc++; 20935810Smarc for (cp = p->p_cptr; cp; cp = cp->p_osptr) 21035810Smarc if (PGRP_JOBC(cp)) 21135810Smarc cp->p_pgrp->pg_jobc++; 21235810Smarc /* 21335810Smarc * old pgrp empty? 21435810Smarc */ 21537589Smarc if (!opgrp->pg_mem) 21637589Smarc pgdelete(opgrp); 21735810Smarc } 21835810Smarc 21935810Smarc /* 22035810Smarc * remove process from process group 22135810Smarc */ 22235810Smarc pgrm(p) 22335810Smarc register struct proc *p; 22435810Smarc { 22535810Smarc register struct proc **pp = &p->p_pgrp->pg_mem; 22635810Smarc 22735810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 22835810Smarc if (*pp == p) { 22935810Smarc *pp = p->p_pgrpnxt; 23035810Smarc goto done; 23135810Smarc } 23237589Smarc panic("pgrm: can't find p in pgrp"); 23335810Smarc done: 23435810Smarc if (!p->p_pgrp->pg_mem) 23535810Smarc pgdelete(p->p_pgrp); 23635810Smarc p->p_pgrp = 0; 23735810Smarc } 23835810Smarc 23935810Smarc /* 24035810Smarc * delete a process group 24135810Smarc */ 24235810Smarc pgdelete(pgrp) 24335810Smarc register struct pgrp *pgrp; 24435810Smarc { 24535810Smarc register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 24635810Smarc 24739562Smarc if (pgrp->pg_session->s_ttyp != NULL && 24839562Smarc pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 24939562Smarc pgrp->pg_session->s_ttyp->t_pgrp = NULL; 25035810Smarc for (; *pgp; pgp = &(*pgp)->pg_hforw) 25135810Smarc if (*pgp == pgrp) { 25235810Smarc *pgp = pgrp->pg_hforw; 25335810Smarc goto done; 25435810Smarc } 25537589Smarc panic("pgdelete: can't find pgrp on hash chain"); 25635810Smarc done: 25735810Smarc if (--pgrp->pg_session->s_count == 0) 25835810Smarc FREE(pgrp->pg_session, M_SESSION); 25935810Smarc FREE(pgrp, M_PGRP); 26035810Smarc } 26135810Smarc 26235810Smarc /* 26316529Skarels * init the process queues 26416529Skarels */ 26516529Skarels pqinit() 26616529Skarels { 26716529Skarels register struct proc *p; 26816529Skarels 26916529Skarels /* 27016529Skarels * most procs are initially on freequeue 27116529Skarels * nb: we place them there in their "natural" order. 27216529Skarels */ 27316529Skarels 27416529Skarels freeproc = NULL; 27516529Skarels for (p = procNPROC; --p > proc; freeproc = p) 27616529Skarels p->p_nxt = freeproc; 27716529Skarels 27816529Skarels /* 27916529Skarels * but proc[0] is special ... 28016529Skarels */ 28116529Skarels 28216529Skarels allproc = p; 28316529Skarels p->p_nxt = NULL; 28416529Skarels p->p_prev = &allproc; 28516529Skarels 28616529Skarels zombproc = NULL; 28716529Skarels } 28835810Smarc 28937728Smckusick #ifdef debug 29035810Smarc /* DEBUG */ 29135810Smarc pgrpdump() 29235810Smarc { 29335810Smarc register struct pgrp *pgrp; 29435810Smarc register struct proc *p; 29535810Smarc register i; 29635810Smarc 29735810Smarc for (i=0; i<PIDHSZ; i++) { 29835810Smarc if (pgrphash[i]) { 29935810Smarc printf("\tindx %d\n", i); 30035810Smarc for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 30135810Smarc printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 30235810Smarc pgrp, pgrp->pg_id, pgrp->pg_session, 30335810Smarc pgrp->pg_session->s_count, pgrp->pg_mem); 30435810Smarc for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 30535810Smarc printf("\t\tpid %d addr %x pgrp %x\n", 30635810Smarc p->p_pid, p, p->p_pgrp); 30735810Smarc } 30835810Smarc } 30935810Smarc 31035810Smarc } 31135810Smarc } 31235810Smarc } 31337728Smckusick #endif /* debug */ 314