DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦caa525eff⟧ TextFile

    Length: 5887 (0x16ff)
    Types: TextFile
    Notes: UNIX file
    Names: »sig.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦2d53db1df⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »sys/coh/sig.c« 

TextFile

/* (-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
}