123371Smckusick /* 237728Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 337728Smckusick * All rights reserved. 423371Smckusick * 544438Sbostic * %sccs.include.redist.c% 637728Smckusick * 7*47542Skarels * @(#)kern_proc.c 7.14 (Berkeley) 03/17/91 823371Smckusick */ 936Sbill 1017091Sbloom #include "param.h" 1117091Sbloom #include "systm.h" 1217091Sbloom #include "map.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 "file.h" 2137728Smckusick #include "../ufs/quota.h" 2217091Sbloom #include "uio.h" 2335810Smarc #include "malloc.h" 2417091Sbloom #include "mbuf.h" 2539064Smarc #include "ioctl.h" 2635810Smarc #include "tty.h" 2736Sbill 2817540Skarels /* 297497Sroot * Is p an inferior of the current process? 3036Sbill */ 317497Sroot inferior(p) 327816Sroot register struct proc *p; 3336Sbill { 3445673Skarels 35*47542Skarels for (; p != curproc; p = p->p_pptr) 36*47542Skarels if (p->p_pid == 0) 377497Sroot return (0); 387497Sroot return (1); 3936Sbill } 407816Sroot 4140709Skarels /* 4240709Skarels * Locate a process by number 4340709Skarels */ 447816Sroot struct proc * 457816Sroot pfind(pid) 4635810Smarc register pid; 477816Sroot { 4840709Skarels register struct proc *p = pidhash[PIDHASH(pid)]; 497816Sroot 5040709Skarels for (; p; p = p->p_hash) 517816Sroot if (p->p_pid == pid) 527816Sroot return (p); 537816Sroot return ((struct proc *)0); 547816Sroot } 5516529Skarels 5616529Skarels /* 5735810Smarc * Locate a process group by number 5835810Smarc */ 5935810Smarc struct pgrp * 6035810Smarc pgfind(pgid) 6135810Smarc register pid_t pgid; 6235810Smarc { 6335810Smarc register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; 6435810Smarc 6535810Smarc for (; pgrp; pgrp = pgrp->pg_hforw) 6635810Smarc if (pgrp->pg_id == pgid) 6740709Skarels return (pgrp); 6835810Smarc return ((struct pgrp *)0); 6935810Smarc } 7035810Smarc 7135810Smarc /* 7235810Smarc * Move p to a new or existing process group (and session) 7335810Smarc */ 74*47542Skarels enterpgrp(p, pgid, mksess) 7535810Smarc register struct proc *p; 7635810Smarc pid_t pgid; 7735810Smarc { 7835810Smarc register struct pgrp *pgrp = pgfind(pgid); 7945673Skarels register struct proc **pp; 8035810Smarc register struct proc *cp; 8145673Skarels int n; 8235810Smarc 8339562Smarc #ifdef DIAGNOSTIC 8435810Smarc if (pgrp && mksess) /* firewalls */ 85*47542Skarels panic("enterpgrp: setsid into non-empty pgrp"); 8635810Smarc if (SESS_LEADER(p)) 87*47542Skarels panic("enterpgrp: session leader attempted setpgrp"); 8839562Smarc #endif 8937589Smarc if (pgrp == NULL) { 9035810Smarc /* 9135810Smarc * new process group 9235810Smarc */ 9339562Smarc #ifdef DIAGNOSTIC 9435810Smarc if (p->p_pid != pgid) 95*47542Skarels panic("enterpgrp: new pgrp and pid != pgid"); 9639562Smarc #endif 9735810Smarc MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 9835810Smarc M_WAITOK); 9935810Smarc if (mksess) { 10035810Smarc register struct session *sess; 10135810Smarc /* 10235810Smarc * new session 10335810Smarc */ 10435810Smarc MALLOC(sess, struct session *, sizeof(struct session), 10535810Smarc M_SESSION, M_WAITOK); 10635810Smarc sess->s_leader = p; 10735810Smarc sess->s_count = 1; 10839562Smarc sess->s_ttyvp = NULL; 10939562Smarc sess->s_ttyp = NULL; 11039562Smarc p->p_flag &= ~SCTTY; 11135810Smarc pgrp->pg_session = sess; 11239562Smarc #ifdef DIAGNOSTIC 113*47542Skarels if (p != curproc) 114*47542Skarels panic("enterpgrp: mksession and p != curproc"); 11539562Smarc #endif 11635810Smarc } else { 11735810Smarc pgrp->pg_session = p->p_session; 11835810Smarc pgrp->pg_session->s_count++; 11935810Smarc } 12035810Smarc pgrp->pg_id = pgid; 12145673Skarels pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)]; 12235810Smarc pgrphash[n] = pgrp; 12335810Smarc pgrp->pg_jobc = 0; 12439562Smarc pgrp->pg_mem = NULL; 12544387Smarc } else if (pgrp == p->p_pgrp) 12644387Smarc return; 12745673Skarels 12835810Smarc /* 12945673Skarels * Adjust eligibility of affected pgrps to participate in job control. 13045673Skarels * Increment eligibility counts before decrementing, otherwise we 13145673Skarels * could reach 0 spuriously during the first call. 13235810Smarc */ 13345673Skarels fixjobc(p, pgrp, 1); 13445673Skarels fixjobc(p, p->p_pgrp, 0); 13545673Skarels 13635810Smarc /* 13735810Smarc * unlink p from old process group 13835810Smarc */ 13945673Skarels for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) 14035810Smarc if (*pp == p) { 14135810Smarc *pp = p->p_pgrpnxt; 14235810Smarc goto done; 14335810Smarc } 144*47542Skarels panic("enterpgrp: can't find p on old pgrp"); 14535810Smarc done: 14635810Smarc /* 14745673Skarels * delete old if empty 14845673Skarels */ 14945673Skarels if (p->p_pgrp->pg_mem == 0) 15045673Skarels pgdelete(p->p_pgrp); 15145673Skarels /* 15235810Smarc * link into new one 15335810Smarc */ 15445673Skarels p->p_pgrp = pgrp; 15535810Smarc p->p_pgrpnxt = pgrp->pg_mem; 15635810Smarc pgrp->pg_mem = p; 15735810Smarc } 15835810Smarc 15935810Smarc /* 16035810Smarc * remove process from process group 16135810Smarc */ 162*47542Skarels leavepgrp(p) 16335810Smarc register struct proc *p; 16435810Smarc { 16535810Smarc register struct proc **pp = &p->p_pgrp->pg_mem; 16635810Smarc 16735810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 16835810Smarc if (*pp == p) { 16935810Smarc *pp = p->p_pgrpnxt; 17035810Smarc goto done; 17135810Smarc } 172*47542Skarels panic("leavepgrp: can't find p in pgrp"); 17335810Smarc done: 17435810Smarc if (!p->p_pgrp->pg_mem) 17535810Smarc pgdelete(p->p_pgrp); 17635810Smarc p->p_pgrp = 0; 17735810Smarc } 17835810Smarc 17935810Smarc /* 18035810Smarc * delete a process group 18135810Smarc */ 18235810Smarc pgdelete(pgrp) 18335810Smarc register struct pgrp *pgrp; 18435810Smarc { 18535810Smarc register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 18635810Smarc 18739562Smarc if (pgrp->pg_session->s_ttyp != NULL && 18839562Smarc pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 18939562Smarc pgrp->pg_session->s_ttyp->t_pgrp = NULL; 19035810Smarc for (; *pgp; pgp = &(*pgp)->pg_hforw) 19135810Smarc if (*pgp == pgrp) { 19235810Smarc *pgp = pgrp->pg_hforw; 19335810Smarc goto done; 19435810Smarc } 19537589Smarc panic("pgdelete: can't find pgrp on hash chain"); 19635810Smarc done: 19735810Smarc if (--pgrp->pg_session->s_count == 0) 19835810Smarc FREE(pgrp->pg_session, M_SESSION); 19935810Smarc FREE(pgrp, M_PGRP); 20035810Smarc } 20135810Smarc 20235810Smarc /* 20345673Skarels * Adjust pgrp jobc counters when specified process changes process group. 20445673Skarels * We count the number of processes in each process group that "qualify" 20545673Skarels * the group for terminal job control (those with a parent in a different 20645673Skarels * process group of the same session). If that count reaches zero, the 20745673Skarels * process group becomes orphaned. Check both the specified process' 20845673Skarels * process group and that of its children. 20945673Skarels * entering == 0 => p is leaving specified group. 21045673Skarels * entering == 1 => p is entering specified group. 21144387Smarc */ 21245673Skarels fixjobc(p, pgrp, entering) 21344387Smarc register struct proc *p; 21445673Skarels register struct pgrp *pgrp; 21545673Skarels int entering; 21644387Smarc { 21745673Skarels register struct pgrp *hispgrp; 21845673Skarels register struct session *mysession = pgrp->pg_session; 21944387Smarc 22045673Skarels /* 22145673Skarels * Check p's parent to see whether p qualifies its own process 22245673Skarels * group; if so, adjust count for p's process group. 22345673Skarels */ 22445673Skarels if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 22544387Smarc hispgrp->pg_session == mysession) 22645673Skarels if (entering) 22745673Skarels pgrp->pg_jobc++; 22845673Skarels else if (--pgrp->pg_jobc == 0) 22945673Skarels orphanpg(pgrp); 23044387Smarc 23145673Skarels /* 23245673Skarels * Check this process' children to see whether they qualify 23345673Skarels * their process groups; if so, adjust counts for children's 23445673Skarels * process groups. 23545673Skarels */ 23645673Skarels for (p = p->p_cptr; p; p = p->p_osptr) 23745673Skarels if ((hispgrp = p->p_pgrp) != pgrp && 23844387Smarc hispgrp->pg_session == mysession && 23944387Smarc p->p_stat != SZOMB) 24045673Skarels if (entering) 24144387Smarc hispgrp->pg_jobc++; 24245673Skarels else if (--hispgrp->pg_jobc == 0) 24345673Skarels orphanpg(hispgrp); 24445673Skarels } 24544387Smarc 24645673Skarels /* 24745673Skarels * A process group has become orphaned; 24845673Skarels * if there are any stopped processes in the group, 24945673Skarels * hang-up all process in that group. 25045673Skarels */ 25145673Skarels static 25245673Skarels orphanpg(pg) 25345673Skarels struct pgrp *pg; 25445673Skarels { 25545673Skarels register struct proc *p; 25645673Skarels 25745673Skarels for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { 25845673Skarels if (p->p_stat == SSTOP) { 25945673Skarels for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { 26045673Skarels psignal(p, SIGHUP); 26145673Skarels psignal(p, SIGCONT); 26244387Smarc } 26345673Skarels return; 26445673Skarels } 26545673Skarels } 26644387Smarc } 26745673Skarels 26837728Smckusick #ifdef debug 26935810Smarc /* DEBUG */ 27035810Smarc pgrpdump() 27135810Smarc { 27235810Smarc register struct pgrp *pgrp; 27335810Smarc register struct proc *p; 27435810Smarc register i; 27535810Smarc 27635810Smarc for (i=0; i<PIDHSZ; i++) { 27735810Smarc if (pgrphash[i]) { 27835810Smarc printf("\tindx %d\n", i); 27935810Smarc for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 28035810Smarc printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 28135810Smarc pgrp, pgrp->pg_id, pgrp->pg_session, 28235810Smarc pgrp->pg_session->s_count, pgrp->pg_mem); 28335810Smarc for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 28435810Smarc printf("\t\tpid %d addr %x pgrp %x\n", 28535810Smarc p->p_pid, p, p->p_pgrp); 28635810Smarc } 28735810Smarc } 28835810Smarc 28935810Smarc } 29035810Smarc } 29135810Smarc } 29237728Smckusick #endif /* debug */ 293