|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 5887 (0x16ff) Types: TextFile Notes: UNIX file Names: »sig.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦2d53db1df⟧ UNIX Filesystem └─⟦this⟧ »sys/coh/sig.c«
/* (-lgl * The information contained herein is a trade secret of Mark Williams * Company, and is confidential information. It is provided under a * license agreement, and may be copied or disclosed only under the * terms of that agreement. Any reproduction or disclosure of this * material without the express written authorization of Mark Williams * Company or persuant to the license agreement is unlawful. * * COHERENT Version 0.7.3 * Copyright (c) 1982, 1983, 1984. * An unpublished work by Mark Williams Company, Chicago. * All rights reserved. -lgl) */ /* * Coherent. * Signal handling. */ #include <coherent.h> #include <errno.h> #include <ino.h> #include <inode.h> #include <io.h> #include <proc.h> #include <ptrace.h> #include <sched.h> #include <seg.h> #include <signal.h> #include <uproc.h> /* * Send a signal to the process `pp'. */ sendsig(sig, pp) register unsigned sig; register PROC *pp; { register sig_t f; register int s; f = ((sig_t)1) << (sig-1); if ((pp->p_isig&f) != 0) return; pp->p_ssig |= f; if (pp->p_state == PSSLEEP) { #ifndef QWAKEUP s = sphi(); pp->p_lback->p_lforw = pp->p_lforw; pp->p_lforw->p_lback = pp->p_lback; addu(pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK); setrun(pp); spl(s); #else pp->p_flags |= PFWAKE; ntowake += 1; #endif } } /* * Return signal number if we have a non ignored signal, else zero. */ nondsig() { register PROC *pp; register sig_t mask; register int signo; pp = SELF; signo = 0; pp->p_ssig &= ~pp->p_isig; if (pp->p_ssig != 0) { mask = (sig_t) 1; signo += 1; while ((pp->p_ssig&mask) == 0) { mask <<= 1; signo += 1; } } return (signo); } /* * If we have a signal that isn't ignored, activate it. */ actvsig() { register int n; register PROC *pp; register int (*f)(); if ((n = nondsig()) == 0) return; pp = SELF; --n; pp->p_ssig &= ~((sig_t)1<<n); f = u.u_sfunc[n]; u.u_signo = ++n; if (f != SIG_DFL) { msigint(n, f); return; } msysgen(&u.u_sysgen); if ((pp->p_flags&PFTRAC) != 0) { pp->p_flags |= PFWAIT; n = ptret(); pp->p_flags &= ~(PFWAIT|PFSTOP); if (n == 0) return; } if (n>SIGKILL || n==SIGQUIT || n==SIGSYS) { if (sigdump()) n |= 0200; } pexit(n); } /* * Create a dump of ourselves onto the file `core'. */ sigdump() { register INODE *ip; register SR *srp; register int n; register paddr_t ssize; if ((SELF->p_flags&PFNDMP) != 0) return (0); u.u_io.io_seg = IOSYS; /* Make the core with the real owners */ schizo(); if (ftoi("core", 'c') != 0) { schizo(); return (0); } if ((ip=u.u_cdiri) == NULL) { if ((ip=imake(IFREG|0644, 0)) == NULL) { schizo(); return (0); } } else { if ((ip->i_mode&IFMT)!=IFREG || iaccess(ip, IPW)==0 || getment(ip->i_dev, 1)==NULL) { idetach(ip); schizo(); return (0); } iclear(ip); } schizo(); u.u_error = 0; u.u_io.io_seek = 0; for (srp=u.u_segl; u.u_error==0 && srp<&u.u_segl[NUSEG]; srp++) { if (srp->sr_segp==NULL || (srp->sr_flag&SRFDUMP)==0) continue; u.u_io.io_seg = IOPHY; u.u_io.io_phys = ctob((paddr_t)srp->sr_segp->s_mbase); ssize = ctob((paddr_t)(srp->sr_segp->s_size)); while (u.u_error == 0 && ssize != 0) { n = ssize > SCHUNK ? SCHUNK : ssize; u.u_io.io_ioc = n; iwrite(ip, &u.u_io); u.u_io.io_phys += (paddr_t)n; ssize -= (paddr_t)n; } } idetach(ip); return (u.u_error==0); } /* * Send a ptrace command to the child. */ ptset(req, pid, addr, data) unsigned req; int *addr; { #ifdef TINY sendsig(SELF, SIGSYS); return (0); #else register PROC *pp; lock(pnxgate); for (pp=procq.p_nforw; pp!=&procq; pp=pp->p_nforw) if (pp->p_pid == pid) break; unlock(pnxgate); if (pp==&procq || (pp->p_flags&PFSTOP)==0 || pp->p_ppid!=SELF->p_pid) { u.u_error = ESRCH; return; } lock(pts.pt_gate); pts.pt_req = req; pts.pt_pid = pid; pts.pt_addr = addr; pts.pt_data = data; pts.pt_errs = 0; pts.pt_rval = 0; pts.pt_busy = 1; wakeup((char *)&pts.pt_req); while (pts.pt_busy != 0) sleep((char *)&pts.pt_busy, CVPTSET, IVPTSET, SVPTSET); u.u_error = pts.pt_errs; unlock(pts.pt_gate); return (pts.pt_rval); #endif } /* * This routine is called when a child that is being traced receives a signal * that is not caught or ignored. It follows up on any requests by the parent * and returns when done. */ ptret() { #ifdef TINY return (SIGKILL); #else register PROC *pp; register PROC *pp1; register int sign; pp = SELF; next: u.u_error = 0; if (pp->p_ppid == 1) return (SIGKILL); sign = -1; lock(pnxgate); pp1 = &procq; for (;;) { if ((pp1=pp1->p_nforw) == &procq) { sign = SIGKILL; break; } if (pp1->p_pid != pp->p_ppid) continue; if (pp1->p_state == PSSLEEP) wakeup((char *)pp1); break; } unlock(pnxgate); while (sign < 0) { if (pts.pt_busy==0 || pp->p_pid!=pts.pt_pid) { sleep((char *)&pts.pt_req, CVPTRET, IVPTRET, SVPTRET); goto next; } switch (pts.pt_req) { case 1: pts.pt_rval = getuwi(pts.pt_addr); break; case 2: pts.pt_rval = getuwd(pts.pt_addr); break; case 3: if ((unsigned)pts.pt_addr < UPASIZE) pts.pt_rval = *(int *)((char *)&u+pts.pt_addr); else u.u_error = EINVAL; break; case 4: putuwi(pts.pt_addr, pts.pt_data); break; case 5: putuwd(pts.pt_addr, pts.pt_data); break; case 6: if (msetuof(pts.pt_addr, pts.pt_data) == 0) u.u_error = EINVAL; break; case 7: goto sig; case 8: sign = SIGKILL; break; case 9: msigsin(); sig: if (pts.pt_data<0 || pts.pt_data>NSIG) { u.u_error = EINVAL; break; } sign = pts.pt_data; if (pts.pt_addr != SIG_IGN) msetppc((vaddr_t)pts.pt_addr); break; default: u.u_error = EINVAL; } if ((pts.pt_errs=u.u_error) == EFAULT) pts.pt_errs = EINVAL; pts.pt_busy = 0; wakeup((char *)&pts.pt_busy); } return (sign); #endif }