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*45673Skarels * @(#)kern_proc.c 7.12 (Berkeley) 12/01/90 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 "vm.h" 2117091Sbloom #include "text.h" 2217091Sbloom #include "file.h" 2337728Smckusick #include "../ufs/quota.h" 2417091Sbloom #include "uio.h" 2535810Smarc #include "malloc.h" 2617091Sbloom #include "mbuf.h" 2739064Smarc #include "ioctl.h" 2835810Smarc #include "tty.h" 2936Sbill 3037524Smckusick #include "machine/reg.h" 3137524Smckusick #include "machine/pte.h" 3237524Smckusick #include "machine/psl.h" 3337524Smckusick 3417540Skarels /* 357497Sroot * Is p an inferior of the current process? 3636Sbill */ 377497Sroot inferior(p) 387816Sroot register struct proc *p; 3936Sbill { 40*45673Skarels 417497Sroot for (; p != u.u_procp; p = p->p_pptr) 427497Sroot if (p->p_ppid == 0) 437497Sroot return (0); 447497Sroot return (1); 4536Sbill } 467816Sroot 4740709Skarels /* 4840709Skarels * Locate a process by number 4940709Skarels */ 507816Sroot struct proc * 517816Sroot pfind(pid) 5235810Smarc register pid; 537816Sroot { 5440709Skarels register struct proc *p = pidhash[PIDHASH(pid)]; 557816Sroot 5640709Skarels for (; p; p = p->p_hash) 577816Sroot if (p->p_pid == pid) 587816Sroot return (p); 597816Sroot return ((struct proc *)0); 607816Sroot } 6116529Skarels 6216529Skarels /* 6335810Smarc * Locate a process group by number 6435810Smarc */ 6535810Smarc struct pgrp * 6635810Smarc pgfind(pgid) 6735810Smarc register pid_t pgid; 6835810Smarc { 6935810Smarc register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; 7035810Smarc 7135810Smarc for (; pgrp; pgrp = pgrp->pg_hforw) 7235810Smarc if (pgrp->pg_id == pgid) 7340709Skarels return (pgrp); 7435810Smarc return ((struct pgrp *)0); 7535810Smarc } 7635810Smarc 7735810Smarc /* 7835810Smarc * Move p to a new or existing process group (and session) 7935810Smarc */ 8035810Smarc pgmv(p, pgid, mksess) 8135810Smarc register struct proc *p; 8235810Smarc pid_t pgid; 8335810Smarc { 8435810Smarc register struct pgrp *pgrp = pgfind(pgid); 85*45673Skarels register struct proc **pp; 8635810Smarc register struct proc *cp; 87*45673Skarels int n; 8835810Smarc 8939562Smarc #ifdef DIAGNOSTIC 9035810Smarc if (pgrp && mksess) /* firewalls */ 9137589Smarc panic("pgmv: setsid into non-empty pgrp"); 9235810Smarc if (SESS_LEADER(p)) 9337589Smarc panic("pgmv: session leader attempted setpgrp"); 9439562Smarc #endif 9537589Smarc if (pgrp == NULL) { 9635810Smarc /* 9735810Smarc * new process group 9835810Smarc */ 9939562Smarc #ifdef DIAGNOSTIC 10035810Smarc if (p->p_pid != pgid) 10137589Smarc panic("pgmv: new pgrp and pid != pgid"); 10239562Smarc #endif 10335810Smarc MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 10435810Smarc M_WAITOK); 10535810Smarc if (mksess) { 10635810Smarc register struct session *sess; 10735810Smarc /* 10835810Smarc * new session 10935810Smarc */ 11035810Smarc MALLOC(sess, struct session *, sizeof(struct session), 11135810Smarc M_SESSION, M_WAITOK); 11235810Smarc sess->s_leader = p; 11335810Smarc sess->s_count = 1; 11439562Smarc sess->s_ttyvp = NULL; 11539562Smarc sess->s_ttyp = NULL; 11639562Smarc p->p_flag &= ~SCTTY; 11735810Smarc pgrp->pg_session = sess; 11839562Smarc #ifdef DIAGNOSTIC 11935810Smarc if (p != u.u_procp) 12035810Smarc panic("pgmv: mksession and p != u.u_procp"); 12139562Smarc #endif 12235810Smarc } else { 12335810Smarc pgrp->pg_session = p->p_session; 12435810Smarc pgrp->pg_session->s_count++; 12535810Smarc } 12635810Smarc pgrp->pg_id = pgid; 127*45673Skarels pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)]; 12835810Smarc pgrphash[n] = pgrp; 12935810Smarc pgrp->pg_jobc = 0; 13039562Smarc pgrp->pg_mem = NULL; 13144387Smarc } else if (pgrp == p->p_pgrp) 13244387Smarc return; 133*45673Skarels 13435810Smarc /* 135*45673Skarels * Adjust eligibility of affected pgrps to participate in job control. 136*45673Skarels * Increment eligibility counts before decrementing, otherwise we 137*45673Skarels * could reach 0 spuriously during the first call. 13835810Smarc */ 139*45673Skarels fixjobc(p, pgrp, 1); 140*45673Skarels fixjobc(p, p->p_pgrp, 0); 141*45673Skarels 14235810Smarc /* 14335810Smarc * unlink p from old process group 14435810Smarc */ 145*45673Skarels for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) 14635810Smarc if (*pp == p) { 14735810Smarc *pp = p->p_pgrpnxt; 14835810Smarc goto done; 14935810Smarc } 15037589Smarc panic("pgmv: can't find p on old pgrp"); 15135810Smarc done: 15235810Smarc /* 153*45673Skarels * delete old if empty 154*45673Skarels */ 155*45673Skarels if (p->p_pgrp->pg_mem == 0) 156*45673Skarels pgdelete(p->p_pgrp); 157*45673Skarels /* 15835810Smarc * link into new one 15935810Smarc */ 160*45673Skarels p->p_pgrp = pgrp; 16135810Smarc p->p_pgrpnxt = pgrp->pg_mem; 16235810Smarc pgrp->pg_mem = p; 16335810Smarc } 16435810Smarc 16535810Smarc /* 16635810Smarc * remove process from process group 16735810Smarc */ 16835810Smarc pgrm(p) 16935810Smarc register struct proc *p; 17035810Smarc { 17135810Smarc register struct proc **pp = &p->p_pgrp->pg_mem; 17235810Smarc 17335810Smarc for (; *pp; pp = &(*pp)->p_pgrpnxt) 17435810Smarc if (*pp == p) { 17535810Smarc *pp = p->p_pgrpnxt; 17635810Smarc goto done; 17735810Smarc } 17837589Smarc panic("pgrm: can't find p in pgrp"); 17935810Smarc done: 18035810Smarc if (!p->p_pgrp->pg_mem) 18135810Smarc pgdelete(p->p_pgrp); 18235810Smarc p->p_pgrp = 0; 18335810Smarc } 18435810Smarc 18535810Smarc /* 18635810Smarc * delete a process group 18735810Smarc */ 18835810Smarc pgdelete(pgrp) 18935810Smarc register struct pgrp *pgrp; 19035810Smarc { 19135810Smarc register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 19235810Smarc 19339562Smarc if (pgrp->pg_session->s_ttyp != NULL && 19439562Smarc pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 19539562Smarc pgrp->pg_session->s_ttyp->t_pgrp = NULL; 19635810Smarc for (; *pgp; pgp = &(*pgp)->pg_hforw) 19735810Smarc if (*pgp == pgrp) { 19835810Smarc *pgp = pgrp->pg_hforw; 19935810Smarc goto done; 20035810Smarc } 20137589Smarc panic("pgdelete: can't find pgrp on hash chain"); 20235810Smarc done: 20335810Smarc if (--pgrp->pg_session->s_count == 0) 20435810Smarc FREE(pgrp->pg_session, M_SESSION); 20535810Smarc FREE(pgrp, M_PGRP); 20635810Smarc } 20735810Smarc 20835810Smarc /* 209*45673Skarels * Adjust pgrp jobc counters when specified process changes process group. 210*45673Skarels * We count the number of processes in each process group that "qualify" 211*45673Skarels * the group for terminal job control (those with a parent in a different 212*45673Skarels * process group of the same session). If that count reaches zero, the 213*45673Skarels * process group becomes orphaned. Check both the specified process' 214*45673Skarels * process group and that of its children. 215*45673Skarels * entering == 0 => p is leaving specified group. 216*45673Skarels * entering == 1 => p is entering specified group. 21744387Smarc */ 218*45673Skarels fixjobc(p, pgrp, entering) 21944387Smarc register struct proc *p; 220*45673Skarels register struct pgrp *pgrp; 221*45673Skarels int entering; 22244387Smarc { 223*45673Skarels register struct pgrp *hispgrp; 224*45673Skarels register struct session *mysession = pgrp->pg_session; 22544387Smarc 226*45673Skarels /* 227*45673Skarels * Check p's parent to see whether p qualifies its own process 228*45673Skarels * group; if so, adjust count for p's process group. 229*45673Skarels */ 230*45673Skarels if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 23144387Smarc hispgrp->pg_session == mysession) 232*45673Skarels if (entering) 233*45673Skarels pgrp->pg_jobc++; 234*45673Skarels else if (--pgrp->pg_jobc == 0) 235*45673Skarels orphanpg(pgrp); 23644387Smarc 237*45673Skarels /* 238*45673Skarels * Check this process' children to see whether they qualify 239*45673Skarels * their process groups; if so, adjust counts for children's 240*45673Skarels * process groups. 241*45673Skarels */ 242*45673Skarels for (p = p->p_cptr; p; p = p->p_osptr) 243*45673Skarels if ((hispgrp = p->p_pgrp) != pgrp && 24444387Smarc hispgrp->pg_session == mysession && 24544387Smarc p->p_stat != SZOMB) 246*45673Skarels if (entering) 24744387Smarc hispgrp->pg_jobc++; 248*45673Skarels else if (--hispgrp->pg_jobc == 0) 249*45673Skarels orphanpg(hispgrp); 250*45673Skarels } 25144387Smarc 252*45673Skarels /* 253*45673Skarels * A process group has become orphaned; 254*45673Skarels * if there are any stopped processes in the group, 255*45673Skarels * hang-up all process in that group. 256*45673Skarels */ 257*45673Skarels static 258*45673Skarels orphanpg(pg) 259*45673Skarels struct pgrp *pg; 260*45673Skarels { 261*45673Skarels register struct proc *p; 262*45673Skarels 263*45673Skarels for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { 264*45673Skarels if (p->p_stat == SSTOP) { 265*45673Skarels for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { 266*45673Skarels psignal(p, SIGHUP); 267*45673Skarels psignal(p, SIGCONT); 26844387Smarc } 269*45673Skarels return; 270*45673Skarels } 271*45673Skarels } 27244387Smarc } 273*45673Skarels 27444387Smarc /* 27516529Skarels * init the process queues 27616529Skarels */ 27716529Skarels pqinit() 27816529Skarels { 27916529Skarels register struct proc *p; 28016529Skarels 28116529Skarels /* 28216529Skarels * most procs are initially on freequeue 28316529Skarels * nb: we place them there in their "natural" order. 28416529Skarels */ 28516529Skarels 28616529Skarels freeproc = NULL; 28716529Skarels for (p = procNPROC; --p > proc; freeproc = p) 28816529Skarels p->p_nxt = freeproc; 28916529Skarels 29016529Skarels /* 29116529Skarels * but proc[0] is special ... 29216529Skarels */ 29316529Skarels 29416529Skarels allproc = p; 29516529Skarels p->p_nxt = NULL; 29616529Skarels p->p_prev = &allproc; 29716529Skarels 29816529Skarels zombproc = NULL; 29916529Skarels } 30035810Smarc 30137728Smckusick #ifdef debug 30235810Smarc /* DEBUG */ 30335810Smarc pgrpdump() 30435810Smarc { 30535810Smarc register struct pgrp *pgrp; 30635810Smarc register struct proc *p; 30735810Smarc register i; 30835810Smarc 30935810Smarc for (i=0; i<PIDHSZ; i++) { 31035810Smarc if (pgrphash[i]) { 31135810Smarc printf("\tindx %d\n", i); 31235810Smarc for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 31335810Smarc printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 31435810Smarc pgrp, pgrp->pg_id, pgrp->pg_session, 31535810Smarc pgrp->pg_session->s_count, pgrp->pg_mem); 31635810Smarc for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 31735810Smarc printf("\t\tpid %d addr %x pgrp %x\n", 31835810Smarc p->p_pid, p, p->p_pgrp); 31935810Smarc } 32035810Smarc } 32135810Smarc 32235810Smarc } 32335810Smarc } 32435810Smarc } 32537728Smckusick #endif /* debug */ 326