From dd012d1ef606864be6e4748fdc347dcf654edd54 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 2 Jun 1983 23:00:05 -0800 Subject: [PATCH 1/1] new signals SCCS-vsn: sys/kern/kern_exec.c 4.2 SCCS-vsn: sys/kern/kern_exit.c 4.3 SCCS-vsn: sys/kern/kern_fork.c 4.2 SCCS-vsn: sys/kern/kern_sig.c 5.19 SCCS-vsn: sys/kern/kern_xxx.c 4.3 SCCS-vsn: sys/kern/sys_generic.c 5.37 SCCS-vsn: sys/vax/vax/locore.s 4.80 SCCS-vsn: sys/vax/vax/machdep.c 4.79 SCCS-vsn: sys/vax/include/pcb.h 4.7 SCCS-vsn: sys/vax/vax/trap.c 4.28 --- usr/src/sys/kern/kern_exec.c | 33 ++---- usr/src/sys/kern/kern_exit.c | 20 ++-- usr/src/sys/kern/kern_fork.c | 11 +- usr/src/sys/kern/kern_sig.c | 197 ++++++++++++++++++++++++--------- usr/src/sys/kern/kern_xxx.c | 70 +++--------- usr/src/sys/kern/sys_generic.c | 4 +- usr/src/sys/vax/include/pcb.h | 4 +- usr/src/sys/vax/vax/locore.s | 13 ++- usr/src/sys/vax/vax/machdep.c | 72 +++++++++--- usr/src/sys/vax/vax/trap.c | 9 +- 10 files changed, 261 insertions(+), 172 deletions(-) diff --git a/usr/src/sys/kern/kern_exec.c b/usr/src/sys/kern/kern_exec.c index b8465c364b..f261fc6b47 100644 --- a/usr/src/sys/kern/kern_exec.c +++ b/usr/src/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* kern_exec.c 4.1 83/05/27 */ +/* kern_exec.c 4.2 83/06/02 */ #include "../machine/reg.h" #include "../machine/pte.h" @@ -352,7 +352,7 @@ getxfile(ip, nargc, uid, gid) sleep((caddr_t)u.u_procp, PZERO - 1); u.u_procp->p_flag &= ~(SVFDONE|SKEEP); } - u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SNUSIG); + u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SOUSIG); u.u_procp->p_flag |= pagi; u.u_dmap = u.u_cdmap; u.u_smap = u.u_csmap; @@ -402,34 +402,17 @@ setregs() { register int (**rp)(); register int i, sigmask; + register struct proc *p = u.u_procp; - for (rp = &u.u_signal[1], sigmask = 1; 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. - */ + rp = &u.u_signal[1]; + for (sigmask = 1; rp < &u.u_signal[NSIG]; sigmask <<= 1, rp++) + /* disallow masked signals to carry over? */ + if (p->p_sigcatch & sigmask && (p->p_sigmask & sigmask) == 0) { (void) spl6(); + p->p_sigcatch &= ~sigmask; *rp = SIG_DFL; - if ((int)*rp & 1) - u.u_procp->p_siga0 |= sigmask; - else - u.u_procp->p_siga0 &= ~sigmask; - if ((int)*rp & 2) - u.u_procp->p_siga1 |= sigmask; - else - u.u_procp->p_siga1 &= ~sigmask; (void) spl0(); - continue; } - } #ifdef vax /* for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];) diff --git a/usr/src/sys/kern/kern_exit.c b/usr/src/sys/kern/kern_exit.c index 2bd4ec4d41..b27ca3b8ff 100644 --- a/usr/src/sys/kern/kern_exit.c +++ b/usr/src/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* kern_exit.c 4.2 83/05/31 */ +/* kern_exit.c 4.3 83/06/02 */ #include "../machine/reg.h" #include "../machine/psl.h" @@ -51,14 +51,10 @@ exit(rv) p = u.u_procp; p->p_flag &= ~(STRC|SULOCK); p->p_flag |= SWEXIT; - (void) spl6(); - /* we know SIG_IGN is 1 */ - p->p_siga0 = ~0; - p->p_siga1 = 0; - (void) spl0(); + p->p_sigignore = ~0; p->p_cpticks = 0; p->p_pctcpu = 0; - for (i=0; ip_osptr = 0; p->p_cptr = 0; p->p_sig = 0; - p->p_siga0 = 0; - p->p_siga1 = 0; + p->p_sigcatch = 0; + p->p_sigignore = 0; + p->p_sigmask = 0; p->p_pgrp = 0; p->p_flag = 0; p->p_wchan = 0; @@ -240,14 +237,13 @@ loop: return (0); } } - if (f == 0) { + if (f == 0) return (ECHILD); - } if (options&WNOHANG) { u.u_r.r_val1 = 0; return (0); } - if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) { + if ((u.u_procp->p_flag&SOUSIG) == 0 && setjmp(&u.u_qsave)) { u.u_eosys = RESTARTSYS; return (0); } diff --git a/usr/src/sys/kern/kern_fork.c b/usr/src/sys/kern/kern_fork.c index 9caa44fcf5..9c7fe94ba2 100644 --- a/usr/src/sys/kern/kern_fork.c +++ b/usr/src/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* kern_fork.c 4.1 83/05/27 */ +/* kern_fork.c 4.2 83/06/02 */ #include "../machine/reg.h" #include "../machine/pte.h" @@ -131,7 +131,7 @@ retry: #endif rpp->p_stat = SIDL; timerclear(&rpp->p_realtimer.it_value); - rpp->p_flag = SLOAD | (rip->p_flag & (SPAGI|SNUSIG)); + rpp->p_flag = SLOAD | (rip->p_flag & (SPAGI|SOUSIG)); if (isvfork) { rpp->p_flag |= SVFORK; rpp->p_ndx = rip->p_ndx; @@ -152,9 +152,10 @@ retry: rip->p_cptr = rpp; rpp->p_time = 0; rpp->p_cpu = 0; - rpp->p_siga0 = rip->p_siga0; - rpp->p_siga1 = rip->p_siga1; - /* take along any pending signals, like stops? */ + rpp->p_sigmask = rip->p_sigmask; + rpp->p_sigcatch = rip->p_sigcatch; + rpp->p_sigignore = rip->p_sigignore; + /* take along any pending signals like stops? */ if (isvfork) { rpp->p_tsize = rpp->p_dsize = rpp->p_ssize = 0; rpp->p_szpt = clrnd(ctopt(UPAGES)); diff --git a/usr/src/sys/kern/kern_sig.c b/usr/src/sys/kern/kern_sig.c index f9b38bfd51..527252da14 100644 --- a/usr/src/sys/kern/kern_sig.c +++ b/usr/src/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* kern_sig.c 5.19 83/05/31 */ +/* kern_sig.c 5.19 83/06/02 */ #include "../machine/reg.h" #include "../machine/pte.h" @@ -23,39 +23,121 @@ #include "../h/kernel.h" #include "../h/nami.h" -/* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ - sigvec() { + struct a { + int signo; + int (*sighandler)(); + int sigmask; + } *uap = (struct a *)u.u_ap; + register int sig; + + sig = uap->signo; + if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP || + (sig == SIGCONT && uap->sighandler == SIG_IGN)) { + u.u_error = EINVAL; + return; + } + setsignal(sig, uap->sighandler, uap->sigmask); +} +setsignal(sig, action, sigmask) + int sig, (*action)(), sigmask; +{ + register struct proc *p; + register int mask; + + u.u_r.r_val1 = (int)u.u_signal[sig]; + mask = 1 << (sig - 1); + p = u.u_procp; + /* + * Change setting atomically. + */ + (void) spl6(); + u.u_signal[sig] = action; + u.u_sigmask[sig] = sigmask; + if (action == SIG_IGN) { + p->p_sig &= ~mask; /* never to be seen again */ + p->p_sigignore |= mask; + p->p_sigcatch &= ~mask; + } else { + p->p_sigignore &= ~mask; + if (action == SIG_DFL) + p->p_sigcatch &= ~mask; + else + p->p_sigcatch |= mask; + } + (void) spl0(); } sigblock() { + struct a { + int mask; + } *uap = (struct a *)u.u_ap; + struct proc *p = u.u_procp; + (void) spl6(); + u.u_r.r_val1 = p->p_sigmask; + p->p_sigmask |= uap->mask; + (void) spl0(); } sigsetmask() { + struct a { + int mask; + } *uap = (struct a *)u.u_ap; + register struct proc *p = u.u_procp; + (void) spl6(); + u.u_r.r_val1 = p->p_sigmask; + p->p_sigmask = uap->mask; + (void) spl0(); } sigpause() { + struct a { + int mask; + } *uap = (struct a *)u.u_ap; + register struct proc *p = u.u_procp; + /* + * When returning from sigpause, we want + * the old mask to be restored after the + * signal handler has finished. Thus, we + * save it here and mark the proc structure + * to indicate this (should be in u.). + */ + u.u_oldmask = p->p_sigmask; + p->p_flag |= SOMASK; + p->p_sigmask = uap->mask; + for (;;) + sleep((caddr_t)&u, PSLEP); + /*NOTREACHED*/ } sigstack() { + struct a { + caddr_t asp; + int onsigstack; + } *uap = (struct a *)u.u_ap; + u.u_sigstack = uap->asp; + u.u_onsigstack = uap->onsigstack; } -#ifdef notdef kill() { + register struct a { + int pid; + int signo; + } *uap = (struct a *)u.u_ap; + u.u_error = kill1(0, uap->signo, uap->pid); } -#endif killpg() { @@ -67,6 +149,8 @@ killpg() u.u_error = kill1(1, uap->signo, uap->pgrp); } +/* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ + kill1(ispgrp, signo, who) int ispgrp, signo, who; { @@ -117,8 +201,6 @@ kill1(ispgrp, signo, who) * Send the specified signal to * all processes with 'pgrp' as * process group. - * Called by tty.c for quits and - * interrupts. */ gsignal(pgrp, sig) register int pgrp; @@ -142,28 +224,30 @@ psignal(p, sig) { register int s; register int (*action)(); - long sigmask; + int sigmask; if ((unsigned)sig >= NSIG) return; - sigmask = (1L << (sig-1)); + sigmask = 1 << (sig-1); /* * If proc is traced, always give parent a chance. - * Otherwise get the signal action from the bits in the proc table. */ if (p->p_flag & STRC) action = SIG_DFL; else { - s = (p->p_siga1&sigmask) != 0; - s <<= 1; - s |= (p->p_siga0&sigmask) != 0; - action = (int(*)())s; /* - * If the signal is ignored, we forget about it immediately. + * If the signal is being ignored, + * then we forget about it immediately. */ - if (action == SIG_IGN) + if (p->p_sigignore & sigmask) return; + if (p->p_sigmask & sigmask) + action = SIG_HOLD; + else if (p->p_sigcatch & sigmask) + action = SIG_CATCH; + else + action = SIG_DFL; } #define mask(sig) (1<<(sig-1)) #define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU)) @@ -172,7 +256,7 @@ psignal(p, sig) switch (sig) { case SIGTERM: - if ((p->p_flag&STRC) != 0 || action != SIG_DFL) + if ((p->p_flag&STRC) || action != SIG_DFL) break; /* fall into ... */ @@ -370,24 +454,23 @@ issig() { register struct proc *p; register int sig; - long sigbits; - long sigmask; + int sigbits, sigmask; p = u.u_procp; for (;;) { sigbits = p->p_sig; if ((p->p_flag&STRC) == 0) - sigbits &= ~p->p_ignsig; + sigbits &= ~(p->p_sigignore | p->p_sigmask); if (p->p_flag&SVFORK) #define bit(a) (1<<(a-1)) sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); if (sigbits == 0) break; - sig = ffs((int)sigbits); - sigmask = 1L << (sig-1); + sig = ffs(sigbits); + sigmask = 1 << (sig-1); p->p_sig &= ~sigmask; /* take the signal! */ p->p_cursig = sig; - if (p->p_flag&STRC && (p->p_flag&SVFORK)==0) { + if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) { /* * If traced, always stop, and stay * stopped until released by the parent. @@ -449,6 +532,7 @@ issig() case SIGCONT: case SIGCHLD: + case SIGURG: /* * These signals are normally not * sent if the action is the default. @@ -523,40 +607,50 @@ stop(p) */ psig() { - register struct proc *rp = u.u_procp; - register int n = rp->p_cursig; - long sigmask = 1L << (n-1); + register struct proc *p = u.u_procp; + register int sig = p->p_cursig; + int sigmask = 1 << (sig - 1), returnmask; register int (*action)(); - if (rp->p_cursig == 0) + if (sig == 0) panic("psig"); - action = u.u_signal[n]; + action = u.u_signal[sig]; if (action != SIG_DFL) { - if (action == SIG_IGN || action == SIG_HOLD) + if (action == SIG_IGN || (p->p_sigmask & sigmask)) panic("psig action"); u.u_error = 0; - if (n != SIGILL && n != SIGTRAP) - u.u_signal[n] = 0; /* - * If this catch value indicates automatic holding of - * subsequent signals, set the hold value. + * Set the new mask value and also defer further + * occurences of this signal (unless we're simulating + * the old signal facilities). + * + * Special case: user has done a sigpause. Here the + * current mask is not of interest, but rather the + * mask from before the sigpause is what we want restored + * after the signal processing is completed. */ - if (SIGISDEFER(action)) { - (void) spl6(); - /* SIG_HOLD known to be 3 */ - rp->p_siga0 |= sigmask; - rp->p_siga1 |= sigmask; - u.u_signal[n] = SIG_HOLD; - (void) spl0(); - action = SIGUNDEFER(action); + (void) spl6(); + if (p->p_flag & SOUSIG) { + if (sig != SIGILL && sig != SIGTRAP) { + u.u_signal[sig] = SIG_DFL; + p->p_sigcatch &= ~sigmask; + } + sigmask = 0; } + if (p->p_flag & SOMASK) { + returnmask = u.u_oldmask; + p->p_flag &= ~SOMASK; + } else + returnmask = p->p_sigmask; + p->p_sigmask = u.u_sigmask[sig] | sigmask; + (void) spl0(); u.u_ru.ru_nsignals++; - sendsig(action, n); - rp->p_cursig = 0; + sendsig(action, sig, returnmask); + p->p_cursig = 0; return; } u.u_acflag |= AXSIG; - switch (n) { + switch (sig) { case SIGILL: case SIGIOT: @@ -567,11 +661,11 @@ psig() case SIGFPE: case SIGSEGV: case SIGSYS: - u.u_arg[0] = n; + u.u_arg[0] = sig; if (core()) - n += 0200; + sig += 0200; } - exit(n); + exit(sig); } /* @@ -612,11 +706,10 @@ core() } itrunc(ip, (u_long)0); u.u_acflag |= ACORE; - /* if (u.u_error == 0) */ - u.u_error = rdwri(UIO_WRITE, ip, - (caddr_t)&u, - ctob(UPAGES), - 0, 1, (int *)0); + u.u_error = rdwri(UIO_WRITE, ip, + (caddr_t)&u, + ctob(UPAGES), + 0, 1, (int *)0); if (u.u_error == 0) u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)ctob(dptov(u.u_procp, 0)), diff --git a/usr/src/sys/kern/kern_xxx.c b/usr/src/sys/kern/kern_xxx.c index 9b739b0aa8..6466d0c7a6 100644 --- a/usr/src/sys/kern/kern_xxx.c +++ b/usr/src/sys/kern/kern_xxx.c @@ -1,4 +1,4 @@ -/* kern_xxx.c 4.2 83/05/31 */ +/* kern_xxx.c 4.3 83/06/02 */ #include "../h/param.h" #include "../h/systm.h" @@ -325,64 +325,30 @@ okill() ossig() { - register int (*f)(); struct a { int signo; int (*fun)(); - } *uap; - register struct proc *p = u.u_procp; - register a; - long sigmask; + } *uap = (struct a *)u.u_ap; + register int a, (*f)(); + struct proc *p = u.u_procp; - uap = (struct a *)u.u_ap; - a = uap->signo & SIGNUMMASK; f = uap->fun; - if (a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP || - a==SIGCONT && (f == SIG_IGN || f == SIG_HOLD)) { - u.u_error = EINVAL; - return; - } - if ((uap->signo &~ SIGNUMMASK) || (f != SIG_DFL && f != SIG_IGN && - SIGISDEFER(f))) - u.u_procp->p_flag |= SNUSIG; - /* - * Don't clobber registers if we are to simulate - * a ret+rti. - */ - if ((uap->signo&SIGDORTI) == 0) - u.u_r.r_val1 = (int)u.u_signal[a]; + a = uap->signo; /* - * Change setting atomically. + * Kill processes trying to use job control facilities + * (this'll help us find any vestiges of the old stuff). */ - (void) spl6(); - sigmask = 1L << (a-1); - if (f == SIG_IGN) - p->p_sig &= ~sigmask; /* never to be seen again */ - u.u_signal[a] = f; - if (f != SIG_DFL && f != SIG_IGN && f != SIG_HOLD) - f = SIG_CATCH; - if ((int)f & 1) - p->p_siga0 |= sigmask; - else - p->p_siga0 &= ~sigmask; - if ((int)f & 2) - p->p_siga1 |= sigmask; - else - p->p_siga1 &= ~sigmask; - (void) spl0(); - /* - * Now handle options. - */ - if (uap->signo & SIGDOPAUSE) { - /* - * Simulate a PDP11 style wait instrution which - * atomically lowers priority, enables interrupts - * and hangs. - */ - opause(); - /*NOTREACHED*/ + if ((a &~ 0377) || + (f != SIG_DFL && f != SIG_IGN && ((int)f) & 1)) { + psignal(p, SIGSYS); + return; + } + if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP || + a == SIGCONT && (f == SIG_IGN || f == SIG_HOLD)) { + u.u_error = EINVAL; + return; } - if (uap->signo & SIGDORTI) - u.u_eosys = SIMULATERTI; + setsignal(a, f, 0); + p->p_flag |= SOUSIG; /* mark as simulating old stuff */ } #endif diff --git a/usr/src/sys/kern/sys_generic.c b/usr/src/sys/kern/sys_generic.c index 56ff7b8836..32a59e9d39 100644 --- a/usr/src/sys/kern/sys_generic.c +++ b/usr/src/sys/kern/sys_generic.c @@ -1,4 +1,4 @@ -/* sys_generic.c 5.36 83/05/27 */ +/* sys_generic.c 5.37 83/06/02 */ #include "../h/param.h" #include "../h/systm.h" @@ -129,7 +129,7 @@ rwuio(uio, rw) } count = uio->uio_resid; uio->uio_offset = fp->f_offset; - if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) { + if ((u.u_procp->p_flag&SOUSIG) == 0 && setjmp(&u.u_qsave)) { if (uio->uio_resid == count) u.u_eosys = RESTARTSYS; } else diff --git a/usr/src/sys/vax/include/pcb.h b/usr/src/sys/vax/include/pcb.h index 91fdf34212..7c3ce52913 100644 --- a/usr/src/sys/vax/include/pcb.h +++ b/usr/src/sys/vax/include/pcb.h @@ -1,4 +1,4 @@ -/* pcb.h 4.6 82/10/31 */ +/* pcb.h 4.7 83/06/02 */ /* * VAX process control block @@ -38,7 +38,7 @@ struct pcb int pcb_szpt; /* number of pages of user page table */ int pcb_cmap2; int *pcb_sswap; - int pcb_sigc[3]; + int pcb_sigc[4]; }; #define AST_NONE 0x04000000 /* ast level */ diff --git a/usr/src/sys/vax/vax/locore.s b/usr/src/sys/vax/vax/locore.s index 17fb2fd8be..a2526dbc3d 100644 --- a/usr/src/sys/vax/vax/locore.s +++ b/usr/src/sys/vax/vax/locore.s @@ -1,4 +1,4 @@ -/* locore.s 4.79 83/05/30 */ +/* locore.s 4.80 83/06/02 */ #include "../machine/psl.h" #include "../machine/pte.h" @@ -499,7 +499,7 @@ start: rei /* put signal trampoline code in u. area */ 1: movab _u,r0 - movc3 $12,sigcode,PCB_SIGC(r0) + movc3 $16,sigcode,PCB_SIGC(r0) /* save reboot flags in global _boothowto */ movl r11,_boothowto /* calculate firstaddr, and call main() */ @@ -508,13 +508,14 @@ start: /* proc[1] == /etc/init now running here; run icode */ pushl $PSL_CURMOD|PSL_PRVMOD; pushl $0; rei -/* signal trampoline code: it is known that this code takes exactly 12 bytes */ -/* in ../h/pcb.h and in the movc3 above */ +/* signal trampoline code: it is known that this code takes exactly 16 bytes */ +/* in ../vax/pcb.h and in the movc3 above */ sigcode: - calls $3,1(pc) + calls $4,5(pc) # params pushed by sendsig + chmk $139 # cleanup mask and onsigstack rei .word 0x7f # registers 0-6 (6==sp/compat) - callg (ap),*12(ap) + callg (ap),*16(ap) ret /* diff --git a/usr/src/sys/vax/vax/machdep.c b/usr/src/sys/vax/vax/machdep.c index 8da05e0461..675eedd157 100644 --- a/usr/src/sys/vax/vax/machdep.c +++ b/usr/src/sys/vax/vax/machdep.c @@ -1,4 +1,4 @@ -/* machdep.c 4.78 83/05/21 */ +/* machdep.c 4.79 83/06/02 */ #include "../machine/reg.h" #include "../machine/pte.h" @@ -244,39 +244,53 @@ vmtime(otime, olbolt, oicr) #endif /* - * Send an interrupt to process + * Send an interrupt to process. * - * SHOULD CHANGE THIS TO PASS ONE MORE WORD SO THAT ALL INFORMATION - * PROVIDED BY HARDWARE IS AVAILABLE TO THE USER PROCESS. + * Stack is set up to allow sigcode stored + * in u. to call routine, followed by chmk + * to sigcleanup routine below. After sigcleanup + * resets the signal mask and the notion of + * onsigstack, it returns to user who then + * unwinds with the rei at the bottom of sigcode. */ -sendsig(p, n) - int (*p)(); +sendsig(p, sig, mask) + int (*p)(), sig, mask; { register int *usp, *regs; + int oonsigstack; regs = u.u_ar0; - usp = (int *)regs[SP]; - usp -= 5; + oonsigstack = u.u_onsigstack; + if (!u.u_onsigstack && u.u_sigstack) { + usp = (int *)u.u_sigstack; + u.u_onsigstack = 1; + } else + usp = (int *)regs[SP]; + usp -= 8; if ((int)usp <= USRSTACK - ctob(u.u_ssize)) (void) grow((unsigned)usp); ; /* Avoid asm() label botch */ #ifndef lint - asm("probew $3,$20,(r11)"); + asm("probew $3,$32,(r11)"); asm("beql bad"); #else - if (useracc((caddr_t)usp, 0x20, 1)) + if (useracc((caddr_t)usp, 32, 1)) goto bad; #endif - *usp++ = n; - if (n == SIGILL || n == SIGFPE) { + *usp++ = sig; + if (sig == SIGILL || sig == SIGFPE) { *usp++ = u.u_code; u.u_code = 0; } else *usp++ = 0; + *usp++ = (int)(usp + 2); *usp++ = (int)p; + /* struct sigcontext used for the inward return */ + *usp++ = oonsigstack; + *usp++ = mask; *usp++ = regs[PC]; *usp++ = regs[PS]; - regs[SP] = (int)(usp - 5); + regs[SP] = (int)(usp - 8); regs[PS] &= ~(PSL_CM|PSL_FPD); regs[PC] = (int)u.u_pcb.pcb_sigc; return; @@ -288,11 +302,38 @@ bad: * instruction to halt it in its tracks. */ u.u_signal[SIGILL] = SIG_DFL; - u.u_procp->p_siga0 &= ~(1<<(SIGILL-1)); - u.u_procp->p_siga1 &= ~(1<<(SIGILL-1)); + sig = 1 << (SIGILL - 1); + u.u_procp->p_sigignore &= ~sig; + u.u_procp->p_sigcatch &= ~sig; + u.u_procp->p_sigmask &= ~sig; psignal(u.u_procp, SIGILL); } +/* + * Routine to cleanup state after a signal + * has been taken. Reset signal mask and + * notion of on signal stack from context + * left there by sendsig (above). Pop these + * values in preparation for rei which follows + * return from this routine. + */ +sigcleanup() +{ + register int *usp = (int *)u.u_ar0[SP]; + +#ifndef lint + asm("prober $3,$8,(r11)"); + asm("bnequ 1f; ret; 1:"); +#else + if (useracc((caddr_t)usp, 8, 0)) + return; +#endif + u.u_onsigstack = *usp++ & 01; + u.u_procp->p_sigmask = *usp++; + u.u_ar0[SP] = (int)usp; +} + +#ifdef notdef dorti() { struct frame frame; @@ -326,6 +367,7 @@ dorti() u.u_ar0[PS] &= ~PSL_USERCLR; u.u_ar0[SP] = (int)sp; } +#endif /* * Memenable enables the memory controlle corrected data reporting. diff --git a/usr/src/sys/vax/vax/trap.c b/usr/src/sys/vax/vax/trap.c index e3d2c45f11..52e7698f8e 100644 --- a/usr/src/sys/vax/vax/trap.c +++ b/usr/src/sys/vax/vax/trap.c @@ -1,4 +1,4 @@ -/* trap.c 4.27 83/01/22 */ +/* trap.c 4.28 83/06/02 */ #include "../machine/psl.h" #include "../machine/reg.h" @@ -190,6 +190,10 @@ syscall(sp, type, code, pc, psl) if (!USERMODE(locr0[PS])) panic("syscall"); u.u_ar0 = locr0; + if (code == 139) { /* XXX */ + sigcleanup(); /* XXX */ + goto done; /* XXX */ + } params = (caddr_t)locr0[AP] + NBPW; u.u_error = 0; opc = pc - 2; @@ -246,8 +250,10 @@ asm("ok:"); /* GROT */ locr0[PS] &= ~PSL_C; if (u.u_eosys == RESTARTSYS) pc = opc; +#ifdef notdef else if (u.u_eosys == SIMULATERTI) dorti(); +#endif else if (u.u_error) { #ifndef lint bad: @@ -258,6 +264,7 @@ bad: locr0[R0] = u.u_r.r_val1; locr0[R1] = u.u_r.r_val2; } +done: p = u.u_procp; if (p->p_cursig || ISSIG(p)) psig(); -- 2.20.1