X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/64d6118ba6a37d7a47167ed5a815dc44400d8c50..7afda1259b9e3fe72bac9c9b397a5996ad9cad9c:/usr/src/sys/kern/kern_proc.c diff --git a/usr/src/sys/kern/kern_proc.c b/usr/src/sys/kern/kern_proc.c index 04d1a52e04..edae387630 100644 --- a/usr/src/sys/kern/kern_proc.c +++ b/usr/src/sys/kern/kern_proc.c @@ -1,4 +1,4 @@ -/* kern_proc.c 3.2 %H% */ +/* kern_proc.c 3.20 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -12,9 +12,12 @@ #include "../h/inode.h" #include "../h/seg.h" #include "../h/acct.h" +#include "/usr/include/wait.h" #include "../h/pte.h" #include "../h/vm.h" #include "../h/text.h" +#include "../h/psl.h" +#include "../h/vlimit.h" /* * exec system call, with and without environments. @@ -59,7 +62,7 @@ exece() ne = 0; nc = 0; uap = (struct execa *)u.u_ap; - if ((bno = malloc(swapmap, ctod(clrnd((int) btoc(NCARGS))))) == 0) { + if ((bno = malloc(argmap, ctod(clrnd((int) btoc(NCARGS))))) == 0) { swkill(u.u_procp, "exece"); goto bad; } @@ -97,7 +100,8 @@ exece() if ((nc&BMASK) == 0) { if (bp) bdwrite(bp); - bp = getblk(swapdev, (daddr_t)(dbtofsb(swplo+bno)+(nc>>BSHIFT))); + bp = getblk(argdev, + (daddr_t)(dbtofsb(bno)+(nc>>BSHIFT))); cp = bp->b_un.b_addr; } nc++; @@ -111,7 +115,7 @@ exece() if (getxfile(ip, nc) || u.u_error) { badarg: for (c = 0; c < nc; c += BSIZE) - if (bp = baddr(swapdev, dbtofsb(swplo+bno)+(c>>BSHIFT))) { + if (bp = baddr(argdev, dbtofsb(bno)+(c>>BSHIFT))) { bp->b_flags |= B_AGE; /* throw away */ bp->b_flags &= ~B_DELWRI; /* cancel io */ brelse(bp); @@ -127,38 +131,39 @@ badarg: ucp = USRSTACK - nc - NBPW; ap = ucp - na*NBPW - 3*NBPW; u.u_ar0[SP] = ap; - VOID suword((caddr_t)ap, na-ne); + (void) suword((caddr_t)ap, na-ne); nc = 0; for (;;) { ap += NBPW; if (na==ne) { - VOID suword((caddr_t)ap, 0); + (void) suword((caddr_t)ap, 0); ap += NBPW; } if (--na < 0) break; - VOID suword((caddr_t)ap, ucp); + (void) suword((caddr_t)ap, ucp); do { if ((nc&BMASK) == 0) { if (bp) brelse(bp); - bp = bread(swapdev, (daddr_t)(dbtofsb(swplo+bno)+(nc>>BSHIFT))); + bp = bread(argdev, + (daddr_t)(dbtofsb(bno)+(nc>>BSHIFT))); bp->b_flags |= B_AGE; /* throw away */ bp->b_flags &= ~B_DELWRI; /* cancel io */ cp = bp->b_un.b_addr; } - VOID subyte((caddr_t)ucp++, (c = *cp++)); + (void) subyte((caddr_t)ucp++, (c = *cp++)); nc++; } while(c&0377); } - VOID suword((caddr_t)ap, 0); - VOID suword((caddr_t)ucp, 0); + (void) suword((caddr_t)ap, 0); + (void) suword((caddr_t)ucp, 0); setregs(); bad: if (bp) brelse(bp); if (bno) - mfree(swapmap, ctod(clrnd((int) btoc(NCARGS))), bno); + mfree(argmap, ctod(clrnd((int) btoc(NCARGS))), bno); iput(ip); } @@ -251,7 +256,8 @@ register struct inode *ip; ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize))); ss = clrnd(SSIZE + btoc(nargc)); if (overlay) { - if ((u.u_procp->p_flag & SPAGI) || u.u_sep==0 && ctos(ts) != ctos(u.u_tsize) || nargc) { + if ((u.u_procp->p_flag & SPAGI) || + u.u_sep==0 && ctos(ts) != ctos(u.u_tsize) || nargc) { u.u_error = ENOMEM; goto bad; } @@ -310,7 +316,7 @@ register struct inode *ip; 1 + ts/CLSIZE, (int)btoc(u.u_exdata.ux_dsize)); /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */ - mtpr(TBIA,1); + mtpr(TBIA, 0); /* * set SUID/SGID protections, if no tracing @@ -324,7 +330,7 @@ register struct inode *ip; if(ip->i_mode&ISGID) u.u_gid = ip->i_gid; } else - psignal(u.u_procp, SIGTRC); + psignal(u.u_procp, SIGTRAP); } u.u_tsize = ts; u.u_dsize = ds; @@ -339,12 +345,37 @@ bad: */ setregs() { - register int *rp; + register int (**rp)(); register i; + long sigmask; - for(rp = &u.u_signal[0]; rp < &u.u_signal[NSIG]; rp++) - if((*rp & 1) == 0) - *rp = 0; + for(rp = &u.u_signal[0], sigmask = 1L; rp < &u.u_signal[NSIG]; + sigmask <<= 1, rp++) { + switch (*rp) { + + case SIG_IGN: + case SIG_DFL: + case SIG_HOLD: + continue; + + default: + /* + * Normal or deferring catch; revert to default. + */ + (void) spl6(); + *rp = SIG_DFL; + if ((int)*rp & 1) + u.u_procp->p_siga0 |= sigmask; + else + u.u_procp->p_siga1 &= ~sigmask; + if ((int)*rp & 2) + u.u_procp->p_siga1 |= sigmask; + else + u.u_procp->p_siga1 &= ~sigmask; + (void) spl0(); + continue; + } + } /* for(rp = &u.u_ar0[0]; rp < &u.u_ar0[16];) *rp++ = 0; @@ -354,8 +385,8 @@ setregs() if (u.u_pofile[i]&EXCLOSE) { closef(u.u_ofile[i]); u.u_ofile[i] = NULL; + u.u_pofile[i] &= ~EXCLOSE; } - u.u_pofile[i] &= ~EXCLOSE; } /* * Remember file name for accounting. @@ -399,10 +430,19 @@ exit(rv) p->p_flag &= ~(STRC|SULOCK); p->p_flag |= SWEXIT; p->p_clktim = 0; - rate.v_pgin -= p->p_aveflt; + (void) spl6(); + if ((int)SIG_IGN & 1) + p->p_siga0 = ~0; + else + p->p_siga0 = 0; + if ((int)SIG_IGN & 2) + p->p_siga1 = ~0; + else + p->p_siga1 = 0; + (void) spl0(); p->p_aveflt = 0; for(i=0; ip_stat = SZOMB; i = PIDHASH(p->p_pid); x = p - proc; @@ -451,22 +493,51 @@ done: ((struct xproc *)p)->xp_vm = u.u_vm; /* overlay */ vmsadd(&((struct xproc *)p)->xp_vm, &u.u_cvm); for(q = &proc[0]; q < &proc[NPROC]; q++) - if(q->p_ppid == p->p_pid) { - wakeup((caddr_t)&proc[1]); + if(q->p_pptr == p) { + q->p_pptr = &proc[1]; q->p_ppid = 1; - if (q->p_stat==SSTOP) - setrun(q); + wakeup((caddr_t)&proc[1]); + /* + * Traced processes are killed + * since their existence means someone is screwing up. + * Stopped processes are sent a hangup and a continue. + * This is designed to be ``safe'' for setuid + * processes since they must be willing to tolerate + * hangups anyways. + */ + if (q->p_flag&STRC) { + q->p_flag &= ~STRC; + psignal(q, SIGKILL); + } else if (q->p_stat == SSTOP) { + psignal(q, SIGHUP); + psignal(q, SIGCONT); + } + /* + * Protect this process from future + * tty signals, clear TSTP/TTIN/TTOU if pending, + * and set SDETACH bit on procs. + */ + spgrp(q, -1); } - q = pfind(p->p_ppid); - if (q) - wakeup((caddr_t)q); + wakeup((caddr_t)p->p_pptr); + psignal(p->p_pptr, SIGCHLD); swtch(); } wait() { + struct vtimes vm; + struct vtimes *vp; - wait1((struct vtimes *)0); + if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) { + wait1(0, (struct vtimes *)0); + return; + } + vp = (struct vtimes *)u.u_ar0[R1]; + wait1(u.u_ar0[R0], &vm); + if (u.u_error) + return; + (void) copyout((caddr_t)&vm, (caddr_t)vp, sizeof (struct vtimes)); } /* @@ -476,17 +547,17 @@ wait() * Look also for stopped (traced) children, * and pass back status from them. */ -wait1(vp) +wait1(options, vp) + register options; struct vtimes *vp; { register f; register struct proc *p; f = 0; - loop: for(p = &proc[0]; p < &proc[NPROC]; p++) - if(p->p_ppid == u.u_procp->p_pid) { + if(p->p_pptr == u.u_procp) { f++; if(p->p_stat == SZOMB) { u.u_r.r_val1 = p->p_pid; @@ -499,27 +570,40 @@ loop: p->p_stat = NULL; p->p_pid = 0; p->p_ppid = 0; + p->p_pptr = 0; p->p_sig = 0; + p->p_siga0 = 0; + p->p_siga1 = 0; p->p_pgrp = 0; p->p_flag = 0; p->p_wchan = 0; + p->p_cursig = 0; return; } - if(p->p_stat == SSTOP) { - if((p->p_flag&SWTED) == 0) { - p->p_flag |= SWTED; - u.u_r.r_val1 = p->p_pid; - u.u_r.r_val2 = (fsig(p)<<8) | 0177; - return; - } - continue; + if (p->p_stat == SSTOP && (p->p_flag&SWTED)==0 && + (p->p_flag&STRC || options&WUNTRACED)) { + p->p_flag |= SWTED; + u.u_r.r_val1 = p->p_pid; + u.u_r.r_val2 = (p->p_cursig<<8) | WSTOPPED; + return; } } - if(f) { - sleep((caddr_t)u.u_procp, PWAIT); - goto loop; + if (f==0) { + u.u_error = ECHILD; + return; + } + if (options&WNOHANG) { + u.u_r.r_val1 = 0; + return; + } +/* + if (setjmp(u.u_qsav)) { + u.u_eosys = RESTARTSYS; + return; } - u.u_error = ECHILD; +*/ + sleep((caddr_t)u.u_procp, PWAIT); + goto loop; } /* @@ -561,8 +645,8 @@ fork1(isvfork) if (p2==NULL || (u.u_uid!=0 && (p2==&proc[NPROC-1] || a>MAXUPRC))) { u.u_error = EAGAIN; if (!isvfork) { - VOID vsexpand(0, &u.u_cdmap, 1); - VOID vsexpand(0, &u.u_csmap, 1); + (void) vsexpand(0, &u.u_cdmap, 1); + (void) vsexpand(0, &u.u_csmap, 1); } goto out; } @@ -602,6 +686,10 @@ sbreak() if (n < 0) n = 0; d = clrnd(n - u.u_dsize); + if (ctob(u.u_dsize+d) > u.u_limit[LIM_DATA]) { + u.u_error = ENOMEM; + return; + } if (chksize(u.u_tsize, u.u_dsize+d, u.u_ssize)) return; if (swpexpand(u.u_dsize+d, u.u_ssize, &u.u_dmap, &u.u_smap)==0)