|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1989 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution is only permitted until one year after the first shipment ! 6: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and ! 7: * binary forms are permitted provided that: (1) source distributions retain ! 8: * this entire copyright notice and comment, and (2) distributions including ! 9: * binaries display the following acknowledgement: This product includes ! 10: * software developed by the University of California, Berkeley and its ! 11: * contributors'' in the documentation or other materials provided with the ! 12: * distribution and in all advertising materials mentioning features or use ! 13: * of this software. Neither the name of the University nor the names of ! 14: * its contributors may be used to endorse or promote products derived from ! 15: * this software without specific prior written permission. ! 16: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 19: * ! 20: * @(#)kern_proc.c 7.11 (Berkeley) 6/28/90 ! 21: */ ! 22: ! 23: #include "param.h" ! 24: #include "systm.h" ! 25: #include "map.h" ! 26: #include "user.h" ! 27: #include "kernel.h" ! 28: #include "proc.h" ! 29: #include "buf.h" ! 30: #include "seg.h" ! 31: #include "acct.h" ! 32: #include "wait.h" ! 33: #include "vm.h" ! 34: #include "text.h" ! 35: #include "file.h" ! 36: #include "../ufs/quota.h" ! 37: #include "uio.h" ! 38: #include "malloc.h" ! 39: #include "mbuf.h" ! 40: #include "ioctl.h" ! 41: #include "tty.h" ! 42: ! 43: #include "machine/reg.h" ! 44: #include "machine/pte.h" ! 45: #include "machine/psl.h" ! 46: ! 47: /* ! 48: * Is p an inferior of the current process? ! 49: */ ! 50: inferior(p) ! 51: register struct proc *p; ! 52: { ! 53: for (; p != u.u_procp; p = p->p_pptr) ! 54: if (p->p_ppid == 0) ! 55: return (0); ! 56: return (1); ! 57: } ! 58: ! 59: /* ! 60: * Locate a process by number ! 61: */ ! 62: struct proc * ! 63: pfind(pid) ! 64: register pid; ! 65: { ! 66: register struct proc *p = pidhash[PIDHASH(pid)]; ! 67: ! 68: for (; p; p = p->p_hash) ! 69: if (p->p_pid == pid) ! 70: return (p); ! 71: return ((struct proc *)0); ! 72: } ! 73: ! 74: /* ! 75: * Locate a process group by number ! 76: */ ! 77: struct pgrp * ! 78: pgfind(pgid) ! 79: register pid_t pgid; ! 80: { ! 81: register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; ! 82: ! 83: for (; pgrp; pgrp = pgrp->pg_hforw) ! 84: if (pgrp->pg_id == pgid) ! 85: return (pgrp); ! 86: return ((struct pgrp *)0); ! 87: } ! 88: ! 89: /* ! 90: * Move p to a new or existing process group (and session) ! 91: */ ! 92: pgmv(p, pgid, mksess) ! 93: register struct proc *p; ! 94: pid_t pgid; ! 95: { ! 96: register struct pgrp *pgrp = pgfind(pgid); ! 97: register struct proc **pp = &p->p_pgrp->pg_mem; ! 98: register struct proc *cp; ! 99: struct pgrp *opgrp; ! 100: register n; ! 101: ! 102: #ifdef DIAGNOSTIC ! 103: if (pgrp && mksess) /* firewalls */ ! 104: panic("pgmv: setsid into non-empty pgrp"); ! 105: if (SESS_LEADER(p)) ! 106: panic("pgmv: session leader attempted setpgrp"); ! 107: #endif ! 108: if (pgrp == NULL) { ! 109: /* ! 110: * new process group ! 111: */ ! 112: #ifdef DIAGNOSTIC ! 113: if (p->p_pid != pgid) ! 114: panic("pgmv: new pgrp and pid != pgid"); ! 115: #endif ! 116: MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, ! 117: M_WAITOK); ! 118: if (mksess) { ! 119: register struct session *sess; ! 120: /* ! 121: * new session ! 122: */ ! 123: MALLOC(sess, struct session *, sizeof(struct session), ! 124: M_SESSION, M_WAITOK); ! 125: sess->s_leader = p; ! 126: sess->s_count = 1; ! 127: sess->s_ttyvp = NULL; ! 128: sess->s_ttyp = NULL; ! 129: p->p_flag &= ~SCTTY; ! 130: pgrp->pg_session = sess; ! 131: #ifdef DIAGNOSTIC ! 132: if (p != u.u_procp) ! 133: panic("pgmv: mksession and p != u.u_procp"); ! 134: #endif ! 135: } else { ! 136: pgrp->pg_session = p->p_session; ! 137: pgrp->pg_session->s_count++; ! 138: } ! 139: pgrp->pg_id = pgid; ! 140: pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)]; ! 141: pgrphash[n] = pgrp; ! 142: pgrp->pg_jobc = 0; ! 143: pgrp->pg_mem = NULL; ! 144: } else if (pgrp == p->p_pgrp) ! 145: return; ! 146: /* ! 147: * adjust eligibility of affected pgrps to participate in job control ! 148: */ ! 149: fixjobc(p, 0); ! 150: /* ! 151: * unlink p from old process group ! 152: */ ! 153: for (; *pp; pp = &(*pp)->p_pgrpnxt) ! 154: if (*pp == p) { ! 155: *pp = p->p_pgrpnxt; ! 156: goto done; ! 157: } ! 158: panic("pgmv: can't find p on old pgrp"); ! 159: done: ! 160: /* ! 161: * link into new one ! 162: */ ! 163: p->p_pgrpnxt = pgrp->pg_mem; ! 164: pgrp->pg_mem = p; ! 165: opgrp = p->p_pgrp; ! 166: p->p_pgrp = pgrp; ! 167: /* ! 168: * adjust eligibility of affected pgrps to participate in job control ! 169: */ ! 170: fixjobc(p, 1); ! 171: /* ! 172: * delete old if empty ! 173: */ ! 174: if (!opgrp->pg_mem) ! 175: pgdelete(opgrp); ! 176: } ! 177: ! 178: /* ! 179: * remove process from process group ! 180: */ ! 181: pgrm(p) ! 182: register struct proc *p; ! 183: { ! 184: register struct proc **pp = &p->p_pgrp->pg_mem; ! 185: ! 186: for (; *pp; pp = &(*pp)->p_pgrpnxt) ! 187: if (*pp == p) { ! 188: *pp = p->p_pgrpnxt; ! 189: goto done; ! 190: } ! 191: panic("pgrm: can't find p in pgrp"); ! 192: done: ! 193: if (!p->p_pgrp->pg_mem) ! 194: pgdelete(p->p_pgrp); ! 195: p->p_pgrp = 0; ! 196: } ! 197: ! 198: /* ! 199: * delete a process group ! 200: */ ! 201: pgdelete(pgrp) ! 202: register struct pgrp *pgrp; ! 203: { ! 204: register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; ! 205: ! 206: if (pgrp->pg_session->s_ttyp != NULL && ! 207: pgrp->pg_session->s_ttyp->t_pgrp == pgrp) ! 208: pgrp->pg_session->s_ttyp->t_pgrp = NULL; ! 209: for (; *pgp; pgp = &(*pgp)->pg_hforw) ! 210: if (*pgp == pgrp) { ! 211: *pgp = pgrp->pg_hforw; ! 212: goto done; ! 213: } ! 214: panic("pgdelete: can't find pgrp on hash chain"); ! 215: done: ! 216: if (--pgrp->pg_session->s_count == 0) ! 217: FREE(pgrp->pg_session, M_SESSION); ! 218: FREE(pgrp, M_PGRP); ! 219: } ! 220: ! 221: /* ! 222: * Adjust pgrp jobc counter. ! 223: * flag == 0 => p is leaving current state. ! 224: * flag == 1 => p is entering current state. ! 225: */ ! 226: fixjobc(p, flag) ! 227: register struct proc *p; ! 228: register flag; ! 229: { ! 230: register struct pgrp *mypgrp = p->p_pgrp, *hispgrp; ! 231: register struct session *mysession = mypgrp->pg_session; ! 232: register struct proc *qp; ! 233: ! 234: if ((hispgrp = p->p_pptr->p_pgrp) != mypgrp && ! 235: hispgrp->pg_session == mysession) ! 236: if (flag) ! 237: mypgrp->pg_jobc++; ! 238: else if (--mypgrp->pg_jobc == 0) { ! 239: int deliver = 0; ! 240: ! 241: sigstopped: ! 242: for (qp = mypgrp->pg_mem; qp != NULL; ! 243: qp = qp->p_pgrpnxt) ! 244: if (deliver) { ! 245: psignal(qp, SIGHUP); ! 246: psignal(qp, SIGCONT); ! 247: } else if (qp->p_stat == SSTOP) { ! 248: deliver++; ! 249: goto sigstopped; ! 250: } ! 251: } ! 252: ! 253: for (p = p->p_cptr; p != NULL; p = p->p_osptr) ! 254: if ((hispgrp = p->p_pgrp) != mypgrp && ! 255: hispgrp->pg_session == mysession && ! 256: p->p_stat != SZOMB) ! 257: if (flag) ! 258: hispgrp->pg_jobc++; ! 259: else if (--hispgrp->pg_jobc == 0) { ! 260: int deliver = 0; ! 261: ! 262: sigstopped2: ! 263: for (qp = hispgrp->pg_mem; qp != NULL; ! 264: qp = qp->p_pgrpnxt) ! 265: if (deliver) { ! 266: psignal(qp, SIGHUP); ! 267: psignal(qp, SIGCONT); ! 268: } else if (qp->p_stat == SSTOP) { ! 269: deliver++; ! 270: goto sigstopped2; ! 271: } ! 272: } ! 273: } ! 274: ! 275: /* ! 276: * init the process queues ! 277: */ ! 278: pqinit() ! 279: { ! 280: register struct proc *p; ! 281: ! 282: /* ! 283: * most procs are initially on freequeue ! 284: * nb: we place them there in their "natural" order. ! 285: */ ! 286: ! 287: freeproc = NULL; ! 288: for (p = procNPROC; --p > proc; freeproc = p) ! 289: p->p_nxt = freeproc; ! 290: ! 291: /* ! 292: * but proc[0] is special ... ! 293: */ ! 294: ! 295: allproc = p; ! 296: p->p_nxt = NULL; ! 297: p->p_prev = &allproc; ! 298: ! 299: zombproc = NULL; ! 300: } ! 301: ! 302: #ifdef debug ! 303: /* DEBUG */ ! 304: pgrpdump() ! 305: { ! 306: register struct pgrp *pgrp; ! 307: register struct proc *p; ! 308: register i; ! 309: ! 310: for (i=0; i<PIDHSZ; i++) { ! 311: if (pgrphash[i]) { ! 312: printf("\tindx %d\n", i); ! 313: for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { ! 314: printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", ! 315: pgrp, pgrp->pg_id, pgrp->pg_session, ! 316: pgrp->pg_session->s_count, pgrp->pg_mem); ! 317: for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { ! 318: printf("\t\tpid %d addr %x pgrp %x\n", ! 319: p->p_pid, p, p->p_pgrp); ! 320: } ! 321: } ! 322: ! 323: } ! 324: } ! 325: } ! 326: #endif /* debug */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.