|
|
1.1 root 1: /* $Header: /newbits/kernel/USRSRC/coh/RCS/sig.c,v 1.4 91/07/24 07:52:13 bin Exp Locker: bin $ */
2: /* (lgl-
3: * The information contained herein is a trade secret of Mark Williams
4: * Company, and is confidential information. It is provided under a
5: * license agreement, and may be copied or disclosed only under the
6: * terms of that agreement. Any reproduction or disclosure of this
7: * material without the express written authorization of Mark Williams
8: * Company or persuant to the license agreement is unlawful.
9: *
10: * COHERENT Version 2.3.37
11: * Copyright (c) 1982, 1983, 1984.
12: * An unpublished work by Mark Williams Company, Chicago.
13: * All rights reserved.
14: -lgl) */
15: /*
16: * Coherent.
17: * Signal handling.
18: *
19: * $Log: sig.c,v $
20: * Revision 1.4 91/07/24 07:52:13 bin
21: * update prov by hal
22: *
23: *
24: * Revision 1.1 88/03/24 16:14:24 src
25: * Initial revision
26: *
27: * 87/11/05 Allan Cornish /usr/src/sys/coh/sig.c
28: * New seg struct now used to allow extended addressing.
29: *
30: * 86/11/19 Allan Cornish /usr/src/sys/coh/sig.c
31: * sigdump() initializes the (new) (IO).io_flag field to 0.
32: */
33: #include <sys/coherent.h>
34: #include <errno.h>
35: #include <sys/ino.h>
36: #include <sys/inode.h>
37: #include <sys/io.h>
38: #include <sys/proc.h>
39: #include <sys/ptrace.h>
40: #include <sys/sched.h>
41: #include <sys/seg.h>
42: #include <signal.h>
43: #include <sys/uproc.h>
44:
45: /*
46: * Send a signal to the process `pp'.
47: */
48: sendsig(sig, pp)
49: register unsigned sig;
50: register PROC *pp;
51: {
52: register sig_t f;
53: register int s;
54:
55: f = ((sig_t)1) << (sig-1);
56: if ((pp->p_isig&f) != 0)
57: return;
58: pp->p_ssig |= f;
59: if (pp->p_state == PSSLEEP) {
60: s = sphi();
61: pp->p_lback->p_lforw = pp->p_lforw;
62: pp->p_lforw->p_lback = pp->p_lback;
63: addu(pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK);
64: setrun(pp);
65: spl(s);
66: }
67: }
68:
69: /*
70: * Return signal number if we have a non ignored signal, else zero.
71: */
72: nondsig()
73: {
74: register PROC *pp;
75: register sig_t mask;
76: register int signo;
77:
78: pp = SELF;
79: signo = 0;
80: pp->p_ssig &= ~pp->p_isig;
81: if (pp->p_ssig != 0) {
82: mask = (sig_t) 1;
83: signo += 1;
84: while ((pp->p_ssig&mask) == 0) {
85: mask <<= 1;
86: signo += 1;
87: }
88: }
89: return (signo);
90: }
91:
92: /*
93: * If we have a signal that isn't ignored, activate it.
94: */
95: actvsig()
96: {
97: register int n;
98: register PROC *pp;
99: register int (*f)();
100:
101: #if EBUG_VM > 0
102: printf("actvsig "); /** DEBUG **/
103: #endif
104:
105: if ((n = nondsig()) == 0)
106: return;
107: pp = SELF;
108: --n;
109: pp->p_ssig &= ~((sig_t)1<<n);
110: f = u.u_sfunc[n];
111: u.u_signo = ++n;
112: if (f != SIG_DFL) {
113: msigint(n, f);
114: return;
115: }
116: msysgen(&u.u_sysgen);
117: if ((pp->p_flags&PFTRAC) != 0) {
118: pp->p_flags |= PFWAIT;
119: n = ptret();
120: pp->p_flags &= ~(PFWAIT|PFSTOP);
121: if (n == 0)
122: return;
123: }
124: if (n>SIGKILL || n==SIGQUIT || n==SIGSYS) {
125: if (sigdump())
126: n |= 0200;
127: }
128: pexit(n);
129: }
130:
131: /*
132: * Create a dump of ourselves onto the file `core'.
133: */
134: sigdump()
135: {
136: register INODE *ip;
137: register SR *srp;
138: register SEG * sp;
139: register int n;
140: register paddr_t ssize;
141:
142: if ((SELF->p_flags&PFNDMP) != 0)
143: return (0);
144: u.u_io.io_seg = IOSYS;
145: u.u_io.io_flag = 0;
146: /* Make the core with the real owners */
147: schizo();
148: if (ftoi("core", 'c') != 0) {
149: schizo();
150: return (0);
151: }
152: if ((ip=u.u_cdiri) == NULL) {
153: if ((ip=imake(IFREG|0644, 0)) == NULL) {
154: schizo();
155: return (0);
156: }
157: } else {
158: if ((ip->i_mode&IFMT)!=IFREG
159: || iaccess(ip, IPW)==0
160: || getment(ip->i_dev, 1)==NULL) {
161: idetach(ip);
162: schizo();
163: return (0);
164: }
165: iclear(ip);
166: }
167: schizo();
168: u.u_error = 0;
169: u.u_io.io_seek = 0;
170: for (srp=u.u_segl; u.u_error==0 && srp<&u.u_segl[NUSEG]; srp++) {
171: if ((sp = srp->sr_segp)==NULL || (srp->sr_flag&SRFDUMP)==0)
172: continue;
173: u.u_io.io_seg = IOPHY;
174: u.u_io.io_phys = sp->s_paddr;
175: u.u_io.io_flag = 0;
176: ssize = sp->s_size;
177: sp->s_lrefc++;
178: while (u.u_error == 0 && ssize != 0) {
179: n = ssize > SCHUNK ? SCHUNK : ssize;
180: u.u_io.io_ioc = n;
181: iwrite(ip, &u.u_io);
182: u.u_io.io_phys += (paddr_t)n;
183: ssize -= (paddr_t)n;
184: }
185: sp->s_lrefc--;
186: }
187: idetach(ip);
188: return (u.u_error==0);
189: }
190:
191: /*
192: * Send a ptrace command to the child.
193: */
194: ptset(req, pid, addr, data)
195: unsigned req;
196: int *addr;
197: {
198: #ifdef TINY
199: sendsig(SELF, SIGSYS);
200: return (0);
201: #else
202: register PROC *pp;
203:
204: lock(pnxgate);
205: for (pp=procq.p_nforw; pp!=&procq; pp=pp->p_nforw)
206: if (pp->p_pid == pid)
207: break;
208: unlock(pnxgate);
209: if (pp==&procq || (pp->p_flags&PFSTOP)==0 || pp->p_ppid!=SELF->p_pid) {
210: u.u_error = ESRCH;
211: return;
212: }
213: lock(pts.pt_gate);
214: pts.pt_req = req;
215: pts.pt_pid = pid;
216: pts.pt_addr = addr;
217: pts.pt_data = data;
218: pts.pt_errs = 0;
219: pts.pt_rval = 0;
220: pts.pt_busy = 1;
221: wakeup((char *)&pts.pt_req);
222: while (pts.pt_busy != 0)
223: sleep((char *)&pts.pt_busy, CVPTSET, IVPTSET, SVPTSET);
224: u.u_error = pts.pt_errs;
225: unlock(pts.pt_gate);
226: return (pts.pt_rval);
227: #endif
228: }
229:
230: /*
231: * This routine is called when a child that is being traced receives a signal
232: * that is not caught or ignored. It follows up on any requests by the parent
233: * and returns when done.
234: */
235: ptret()
236: {
237: #ifdef TINY
238: return (SIGKILL);
239: #else
240: register PROC *pp;
241: register PROC *pp1;
242: register int sign;
243:
244: pp = SELF;
245: next:
246: u.u_error = 0;
247: if (pp->p_ppid == 1)
248: return (SIGKILL);
249: sign = -1;
250: lock(pnxgate);
251: pp1 = &procq;
252: for (;;) {
253: if ((pp1=pp1->p_nforw) == &procq) {
254: sign = SIGKILL;
255: break;
256: }
257: if (pp1->p_pid != pp->p_ppid)
258: continue;
259: if (pp1->p_state == PSSLEEP)
260: wakeup((char *)pp1);
261: break;
262: }
263: unlock(pnxgate);
264: while (sign < 0) {
265: if (pts.pt_busy==0 || pp->p_pid!=pts.pt_pid) {
266: sleep((char *)&pts.pt_req, CVPTRET, IVPTRET, SVPTRET);
267: goto next;
268: }
269: switch (pts.pt_req) {
270: case 1:
271: pts.pt_rval = getuwi(pts.pt_addr);
272: break;
273: case 2:
274: pts.pt_rval = getuwd(pts.pt_addr);
275: break;
276: case 3:
277: if ((unsigned)pts.pt_addr < UPASIZE)
278: pts.pt_rval = *(int *)((char *)&u+pts.pt_addr);
279: else
280: u.u_error = EINVAL;
281: break;
282: case 4:
283: putuwi(pts.pt_addr, pts.pt_data);
284: break;
285: case 5:
286: putuwd(pts.pt_addr, pts.pt_data);
287: break;
288: case 6:
289: if (msetuof(pts.pt_addr, pts.pt_data) == 0)
290: u.u_error = EINVAL;
291: break;
292: case 7:
293: goto sig;
294: case 8:
295: sign = SIGKILL;
296: break;
297: case 9:
298: msigsin();
299: sig:
300: if (pts.pt_data<0 || pts.pt_data>NSIG) {
301: u.u_error = EINVAL;
302: break;
303: }
304: sign = pts.pt_data;
305: if (pts.pt_addr != SIG_IGN)
306: msetppc((vaddr_t)pts.pt_addr);
307: break;
308: default:
309: u.u_error = EINVAL;
310: }
311: if ((pts.pt_errs=u.u_error) == EFAULT)
312: pts.pt_errs = EINVAL;
313: pts.pt_busy = 0;
314: wakeup((char *)&pts.pt_busy);
315: }
316: return (sign);
317: #endif
318: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.