xref: /csrg-svn/sys/kern/kern_sig.c (revision 7421)
1 /*	kern_sig.c	5.1	82/07/15	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/dir.h"
6 #include "../h/user.h"
7 #include "../h/reg.h"
8 #include "../h/inode.h"
9 #include "../h/proc.h"
10 #include "../h/clock.h"
11 #include "../h/mtpr.h"
12 #include "../h/timeb.h"
13 #include "../h/times.h"
14 #include "../h/conf.h"
15 #include "../h/buf.h"
16 #include "../h/mount.h"
17 #include "../h/text.h"
18 #include "../h/seg.h"
19 #include "../h/pte.h"
20 #include "../h/psl.h"
21 #include "../h/vm.h"
22 #include "../h/vlimit.h"
23 #include "../h/acct.h"
24 
25 ssig()
26 {
27 	register int (*f)();
28 	struct a {
29 		int	signo;
30 		int	(*fun)();
31 	} *uap;
32 	register struct proc *p = u.u_procp;
33 	register a;
34 	long sigmask;
35 
36 	uap = (struct a *)u.u_ap;
37 	a = uap->signo & SIGNUMMASK;
38 	f = uap->fun;
39 	if (a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP ||
40 	    a==SIGCONT && (f == SIG_IGN || f == SIG_HOLD)) {
41 		u.u_error = EINVAL;
42 		return;
43 	}
44 	if ((uap->signo &~ SIGNUMMASK) || (f != SIG_DFL && f != SIG_IGN &&
45 	    SIGISDEFER(f)))
46 		u.u_procp->p_flag |= SNUSIG;
47 	/*
48 	 * Don't clobber registers if we are to simulate
49 	 * a ret+rti.
50 	 */
51 	if ((uap->signo&SIGDORTI) == 0)
52 		u.u_r.r_val1 = (int)u.u_signal[a];
53 	/*
54 	 * Change setting atomically.
55 	 */
56 	(void) spl6();
57 	sigmask = 1L << (a-1);
58 	if (u.u_signal[a] == SIG_IGN)
59 		p->p_sig &= ~sigmask;		/* never to be seen again */
60 	u.u_signal[a] = f;
61 	if (f != SIG_DFL && f != SIG_IGN && f != SIG_HOLD)
62 		f = SIG_CATCH;
63 	if ((int)f & 1)
64 		p->p_siga0 |= sigmask;
65 	else
66 		p->p_siga0 &= ~sigmask;
67 	if ((int)f & 2)
68 		p->p_siga1 |= sigmask;
69 	else
70 		p->p_siga1 &= ~sigmask;
71 	(void) spl0();
72 	/*
73 	 * Now handle options.
74 	 */
75 	if (uap->signo & SIGDOPAUSE) {
76 		/*
77 		 * Simulate a PDP11 style wait instrution which
78 		 * atomically lowers priority, enables interrupts
79 		 * and hangs.
80 		 */
81 		pause();
82 		/*NOTREACHED*/
83 	}
84 	if (uap->signo & SIGDORTI)
85 		u.u_eosys = SIMULATERTI;
86 }
87 
88 kill()
89 {
90 	register struct proc *p;
91 	register a, sig;
92 	register struct a {
93 		int	pid;
94 		int	signo;
95 	} *uap;
96 	int f, priv;
97 
98 	uap = (struct a *)u.u_ap;
99 	f = 0;
100 	a = uap->pid;
101 	priv = 0;
102 	sig = uap->signo;
103 	if (sig < 0)
104 		/*
105 		 * A negative signal means send to process group.
106 		 */
107 		uap->signo = -uap->signo;
108 	if (uap->signo == 0 || uap->signo > NSIG) {
109 		u.u_error = EINVAL;
110 		return;
111 	}
112 	if (a > 0 && sig > 0) {
113 		p = pfind(a);
114 		if (p == 0 || u.u_uid && u.u_uid != p->p_uid) {
115 			u.u_error = ESRCH;
116 			return;
117 		}
118 		psignal(p, uap->signo);
119 		return;
120 	}
121 	if (a==-1 && u.u_uid==0) {
122 		priv++;
123 		a = 0;
124 		sig = -1;		/* like sending to pgrp */
125 	} else if (a==0) {
126 		/*
127 		 * Zero process id means send to my process group.
128 		 */
129 		sig = -1;
130 		a = u.u_procp->p_pgrp;
131 		if (a == 0) {
132 			u.u_error = EINVAL;
133 			return;
134 		}
135 	}
136 	for(p = proc; p < procNPROC; p++) {
137 		if (p->p_stat == NULL)
138 			continue;
139 		if (sig > 0) {
140 			if (p->p_pid != a)
141 				continue;
142 		} else if (p->p_pgrp!=a && priv==0 || p->p_ppid==0 ||
143 		    (p->p_flag&SSYS) || (priv && p==u.u_procp))
144 			continue;
145 		if (u.u_uid != 0 && u.u_uid != p->p_uid &&
146 		    (uap->signo != SIGCONT || !inferior(p)))
147 			continue;
148 		f++;
149 		psignal(p, uap->signo);
150 	}
151 	if (f == 0)
152 		u.u_error = ESRCH;
153 }
154 
155 /*
156  * Priority for tracing
157  */
158 #define	IPCPRI	PZERO
159 
160 /*
161  * Tracing variables.
162  * Used to pass trace command from
163  * parent to child being traced.
164  * This data base cannot be
165  * shared and is locked
166  * per user.
167  */
168 struct {
169 	int	ip_lock;
170 	int	ip_req;
171 	int	*ip_addr;
172 	int	ip_data;
173 } ipc;
174 
175 /*
176  * Send the specified signal to
177  * all processes with 'pgrp' as
178  * process group.
179  * Called by tty.c for quits and
180  * interrupts.
181  */
182 gsignal(pgrp, sig)
183 	register int pgrp;
184 {
185 	register struct proc *p;
186 
187 	if (pgrp == 0)
188 		return;
189 	for(p = proc; p < procNPROC; p++)
190 		if (p->p_pgrp == pgrp)
191 			psignal(p, sig);
192 }
193 
194 /*
195  * Send the specified signal to
196  * the specified process.
197  */
198 psignal(p, sig)
199 	register struct proc *p;
200 	register int sig;
201 {
202 	register int s;
203 	register int (*action)();
204 	long sigmask;
205 
206 	if ((unsigned)sig >= NSIG)
207 		return;
208 	sigmask = (1L << (sig-1));
209 
210 	/*
211 	 * If proc is traced, always give parent a chance.
212 	 * Otherwise get the signal action from the bits in the proc table.
213 	 */
214 	if (p->p_flag & STRC)
215 		action = SIG_DFL;
216 	else {
217 		s = (p->p_siga1&sigmask) != 0;
218 		s <<= 1;
219 		s |= (p->p_siga0&sigmask) != 0;
220 		action = (int(*)())s;
221 		/*
222 		 * If the signal is ignored, we forget about it immediately.
223 		 */
224 		if (action == SIG_IGN)
225 			return;
226 	}
227 #define mask(sig)	(1<<(sig-1))
228 #define	stops	(mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU))
229 	if (sig) {
230 		p->p_sig |= sigmask;
231 		switch (sig) {
232 
233 		case SIGTERM:
234 			if ((p->p_flag&STRC) != 0 || action != SIG_DFL)
235 				break;
236 			/* fall into ... */
237 
238 		case SIGKILL:
239 			if (p->p_nice > NZERO)
240 				p->p_nice = NZERO;
241 			break;
242 
243 		case SIGCONT:
244 			p->p_sig &= ~stops;
245 			break;
246 
247 		case SIGSTOP:
248 		case SIGTSTP:
249 		case SIGTTIN:
250 		case SIGTTOU:
251 			p->p_sig &= ~mask(SIGCONT);
252 			break;
253 		}
254 	}
255 #undef mask
256 #undef stops
257 	/*
258 	 * Defer further processing for signals which are held.
259 	 */
260 	if (action == SIG_HOLD)
261 		return;
262 	s = spl6();
263 	switch (p->p_stat) {
264 
265 	case SSLEEP:
266 		/*
267 		 * If process is sleeping at negative priority
268 		 * we can't interrupt the sleep... the signal will
269 		 * be noticed when the process returns through
270 		 * trap() or syscall().
271 		 */
272 		if (p->p_pri <= PZERO)
273 			goto out;
274 		/*
275 		 * Process is sleeping and traced... make it runnable
276 		 * so it can discover the signal in issig() and stop
277 		 * for the parent.
278 		 */
279 		if (p->p_flag&STRC)
280 			goto run;
281 		switch (sig) {
282 
283 		case SIGSTOP:
284 		case SIGTSTP:
285 		case SIGTTIN:
286 		case SIGTTOU:
287 			/*
288 			 * These are the signals which by default
289 			 * stop a process.
290 			 */
291 			if (action != SIG_DFL)
292 				goto run;
293 			/*
294 			 * Don't clog system with children of init
295 			 * stopped from the keyboard.
296 			 */
297 			if (sig != SIGSTOP && p->p_pptr == &proc[1]) {
298 				psignal(p, SIGKILL);
299 				p->p_sig &= ~sigmask;
300 				splx(s);
301 				return;
302 			}
303 			/*
304 			 * If a child in vfork(), stopping could
305 			 * cause deadlock.
306 			 */
307 			if (p->p_flag&SVFORK)
308 				goto out;
309 			p->p_sig &= ~sigmask;
310 			p->p_cursig = sig;
311 			stop(p);
312 			goto out;
313 
314 		case SIGIO:
315 		case SIGURG:
316 		case SIGCHLD:
317 			/*
318 			 * These signals are special in that they
319 			 * don't get propogated... if the process
320 			 * isn't interested, forget it.
321 			 */
322 			if (action != SIG_DFL)
323 				goto run;
324 			p->p_sig &= ~sigmask;		/* take it away */
325 			goto out;
326 
327 		default:
328 			/*
329 			 * All other signals cause the process to run
330 			 */
331 			goto run;
332 		}
333 		/*NOTREACHED*/
334 
335 	case SSTOP:
336 		/*
337 		 * If traced process is already stopped,
338 		 * then no further action is necessary.
339 		 */
340 		if (p->p_flag&STRC)
341 			goto out;
342 		switch (sig) {
343 
344 		case SIGKILL:
345 			/*
346 			 * Kill signal always sets processes running.
347 			 */
348 			goto run;
349 
350 		case SIGCONT:
351 			/*
352 			 * If the process catches SIGCONT, let it handle
353 			 * the signal itself.  If it isn't waiting on
354 			 * an event, then it goes back to run state.
355 			 * Otherwise, process goes back to sleep state.
356 			 */
357 			if (action != SIG_DFL || p->p_wchan == 0)
358 				goto run;
359 			p->p_stat = SSLEEP;
360 			goto out;
361 
362 		case SIGSTOP:
363 		case SIGTSTP:
364 		case SIGTTIN:
365 		case SIGTTOU:
366 			/*
367 			 * Already stopped, don't need to stop again.
368 			 * (If we did the shell could get confused.)
369 			 */
370 			p->p_sig &= ~sigmask;		/* take it away */
371 			goto out;
372 
373 		default:
374 			/*
375 			 * If process is sleeping interruptibly, then
376 			 * unstick it so that when it is continued
377 			 * it can look at the signal.
378 			 * But don't setrun the process as its not to
379 			 * be unstopped by the signal alone.
380 			 */
381 			if (p->p_wchan && p->p_pri > PZERO)
382 				unsleep(p);
383 			goto out;
384 		}
385 		/*NOTREACHED*/
386 
387 	default:
388 		/*
389 		 * SRUN, SIDL, SZOMB do nothing with the signal,
390 		 * other than kicking ourselves if we are running.
391 		 * It will either never be noticed, or noticed very soon.
392 		 */
393 		if (p == u.u_procp && !noproc)
394 			aston();
395 		goto out;
396 	}
397 	/*NOTREACHED*/
398 run:
399 	/*
400 	 * Raise priority to at least PUSER.
401 	 */
402 	if (p->p_pri > PUSER)
403 		if ((p != u.u_procp || noproc) && p->p_stat == SRUN &&
404 		    (p->p_flag & SLOAD)) {
405 			remrq(p);
406 			p->p_pri = PUSER;
407 			setrq(p);
408 		} else
409 			p->p_pri = PUSER;
410 	setrun(p);
411 out:
412 	splx(s);
413 }
414 
415 /*
416  * Returns true if the current
417  * process has a signal to process.
418  * The signal to process is put in p_cursig.
419  * This is asked at least once each time a process enters the
420  * system (though this can usually be done without actually
421  * calling issig by checking the pending signal masks.)
422  * A signal does not do anything
423  * directly to a process; it sets
424  * a flag that asks the process to
425  * do something to itself.
426  */
427 issig()
428 {
429 	register struct proc *p;
430 	register int sig;
431 	long sigbits;
432 	long sigmask;
433 
434 	p = u.u_procp;
435 	for (;;) {
436 		sigbits = p->p_sig;
437 		if ((p->p_flag&STRC) == 0)
438 			sigbits &= ~p->p_ignsig;
439 		if (p->p_flag&SVFORK)
440 #define bit(a) (1<<(a-1))
441 			sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU));
442 		if (sigbits == 0)
443 			break;
444 		sig = ffs((int)sigbits);
445 		sigmask = 1L << (sig-1);
446 		p->p_sig &= ~sigmask;		/* take the signal! */
447 		p->p_cursig = sig;
448 		if (p->p_flag&STRC && (p->p_flag&SVFORK)==0) {
449 			/*
450 			 * If traced, always stop, and stay
451 			 * stopped until released by the parent.
452 			 */
453 			do {
454 				stop(p);
455 				swtch();
456 			} while (!procxmt() && p->p_flag&STRC);
457 
458 			/*
459 			 * If the traced bit got turned off,
460 			 * then put the signal taken above back into p_sig
461 			 * and go back up to the top to rescan signals.
462 			 * This ensures that siga0 and u_signal are consistent.
463 			 */
464 			if ((p->p_flag&STRC) == 0) {
465 				p->p_sig |= sigmask;
466 				continue;
467 			}
468 
469 			/*
470 			 * If parent wants us to take the signal,
471 			 * then it will leave it in p->p_cursig;
472 			 * otherwise we just look for signals again.
473 			 */
474 			sig = p->p_cursig;
475 			if (sig == 0)
476 				continue;
477 		}
478 		switch (u.u_signal[sig]) {
479 
480 		case SIG_DFL:
481 			/*
482 			 * Don't take default actions on system processes.
483 			 */
484 			if (p->p_ppid == 0)
485 				break;
486 			switch (sig) {
487 
488 			case SIGTSTP:
489 			case SIGTTIN:
490 			case SIGTTOU:
491 				/*
492 				 * Children of init aren't allowed to stop
493 				 * on signals from the keyboard.
494 				 */
495 				if (p->p_pptr == &proc[1]) {
496 					psignal(p, SIGKILL);
497 					continue;
498 				}
499 				/* fall into ... */
500 
501 			case SIGSTOP:
502 				if (p->p_flag&STRC)
503 					continue;
504 				stop(p);
505 				swtch();
506 				continue;
507 
508 			case SIGCONT:
509 			case SIGCHLD:
510 				/*
511 				 * These signals are normally not
512 				 * sent if the action is the default.
513 				 */
514 				continue;		/* == ignore */
515 
516 			default:
517 				goto send;
518 			}
519 			/*NOTREACHED*/
520 
521 		case SIG_HOLD:
522 		case SIG_IGN:
523 			/*
524 			 * Masking above should prevent us
525 			 * ever trying to take action on a held
526 			 * or ignored signal, unless process is traced.
527 			 */
528 			if ((p->p_flag&STRC) == 0)
529 				printf("issig\n");
530 			continue;
531 
532 		default:
533 			/*
534 			 * This signal has an action, let
535 			 * psig process it.
536 			 */
537 			goto send;
538 		}
539 		/*NOTREACHED*/
540 	}
541 	/*
542 	 * Didn't find a signal to send.
543 	 */
544 	p->p_cursig = 0;
545 	return (0);
546 
547 send:
548 	/*
549 	 * Let psig process the signal.
550 	 */
551 	return (sig);
552 }
553 
554 #ifndef vax
555 ffs(mask)
556 	register long mask;
557 {
558 	register int i;
559 
560 	for(i=1; i<NSIG; i++) {
561 		if (mask & 1)
562 			return (i);
563 		mask >>= 1;
564 	}
565 	return (0);
566 }
567 #endif
568 
569 /*
570  * Put the argument process into the stopped
571  * state and notify the parent via wakeup and/or signal.
572  */
573 stop(p)
574 	register struct proc *p;
575 {
576 
577 	p->p_stat = SSTOP;
578 	p->p_flag &= ~SWTED;
579 	wakeup((caddr_t)p->p_pptr);
580 	/*
581 	 * Avoid sending signal to parent if process is traced
582 	 */
583 	if (p->p_flag&STRC)
584 		return;
585 	psignal(p->p_pptr, SIGCHLD);
586 }
587 
588 /*
589  * Perform the action specified by
590  * the current signal.
591  * The usual sequence is:
592  *	if (issig())
593  *		psig();
594  * The signal bit has already been cleared by issig,
595  * and the current signal number stored in p->p_cursig.
596  */
597 psig()
598 {
599 	register struct proc *rp = u.u_procp;
600 	register int n = rp->p_cursig;
601 	long sigmask = 1L << (n-1);
602 	register int (*action)();
603 
604 	if (rp->p_cursig == 0)
605 		panic("psig");
606 	action = u.u_signal[n];
607 	if (action != SIG_DFL) {
608 		if (action == SIG_IGN || action == SIG_HOLD)
609 			panic("psig action");
610 		u.u_error = 0;
611 		if (n != SIGILL && n != SIGTRAP)
612 			u.u_signal[n] = 0;
613 		/*
614 		 * If this catch value indicates automatic holding of
615 		 * subsequent signals, set the hold value.
616 		 */
617 		if (SIGISDEFER(action)) {
618 			(void) spl6();
619 			if ((int)SIG_HOLD & 1)
620 				rp->p_siga0 |= sigmask;
621 			else
622 				rp->p_siga0 &= ~sigmask;
623 			if ((int)SIG_HOLD & 2)
624 				rp->p_siga1 |= sigmask;
625 			else
626 				rp->p_siga1 &= ~sigmask;
627 			u.u_signal[n] = SIG_HOLD;
628 			(void) spl0();
629 			action = SIGUNDEFER(action);
630 		}
631 		sendsig(action, n);
632 		rp->p_cursig = 0;
633 		return;
634 	}
635 	u.u_acflag |= AXSIG;
636 	switch (n) {
637 
638 	case SIGILL:
639 	case SIGIOT:
640 	case SIGBUS:
641 	case SIGQUIT:
642 	case SIGTRAP:
643 	case SIGEMT:
644 	case SIGFPE:
645 	case SIGSEGV:
646 	case SIGSYS:
647 		u.u_arg[0] = n;
648 		if (core())
649 			n += 0200;
650 	}
651 	exit(n);
652 }
653 
654 #ifdef unneeded
655 int	corestop = 0;
656 #endif
657 /*
658  * Create a core image on the file "core"
659  * If you are looking for protection glitches,
660  * there are probably a wealth of them here
661  * when this occurs to a suid command.
662  *
663  * It writes UPAGES block of the
664  * user.h area followed by the entire
665  * data+stack segments.
666  */
667 core()
668 {
669 	register struct inode *ip;
670 	extern schar();
671 
672 #ifdef unneeded
673 	if (corestop) {
674 		int i;
675 		for (i = 0; i < 10; i++)
676 			if (u.u_comm[i])
677 				putchar(u.u_comm[i], 0);
678 		printf(", uid %d\n", u.u_uid);
679 		if (corestop&2)
680 			asm("halt");
681 	}
682 #endif
683 	if (u.u_uid != u.u_ruid)
684 		return;
685 	if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= u.u_limit[LIM_CORE])
686 		return (0);
687 	u.u_error = 0;
688 	u.u_dirp = "core";
689 	ip = namei(schar, 1, 1);
690 	if (ip == NULL) {
691 		if (u.u_error)
692 			return (0);
693 		ip = maknode(0666);
694 		if (ip==NULL)
695 			return (0);
696 	}
697 	if (!access(ip, IWRITE) &&
698 	   (ip->i_mode&IFMT) == IFREG &&
699 	   ip->i_nlink == 1) {
700 		itrunc(ip);
701 		u.u_acflag |= ACORE;
702 		u.u_offset = 0;
703 		u.u_base = (caddr_t)&u;
704 		u.u_count = ctob(UPAGES);
705 		u.u_segflg = 1;
706 		writei(ip);
707 		u.u_base = (char *)ctob(u.u_tsize);
708 		u.u_count = ctob(u.u_dsize);
709 		u.u_segflg = 0;
710 		writei(ip);
711 		u.u_base = (char *)(USRSTACK - ctob(u.u_ssize));
712 		u.u_count = ctob(u.u_ssize);
713 		writei(ip);
714 	} else
715 		u.u_error = EFAULT;
716 	iput(ip);
717 	return (u.u_error==0);
718 }
719 
720 /*
721  * grow the stack to include the SP
722  * true return if successful.
723  */
724 grow(sp)
725 	unsigned sp;
726 {
727 	register si;
728 
729 	if (sp >= USRSTACK-ctob(u.u_ssize))
730 		return (0);
731 	si = clrnd(btoc((USRSTACK-sp)) - u.u_ssize + SINCR);
732 	if (ctob(u.u_ssize+si) > u.u_limit[LIM_STACK])
733 		return (0);
734 	if (chksize(u.u_tsize, u.u_dsize, u.u_ssize+si))
735 		return (0);
736 	if (swpexpand(u.u_dsize, u.u_ssize+si, &u.u_dmap, &u.u_smap)==0)
737 		return (0);
738 
739 	expand(si, P1BR);
740 	return (1);
741 }
742 
743 /*
744  * sys-trace system call.
745  */
746 ptrace()
747 {
748 	register struct proc *p;
749 	register struct a {
750 		int	req;
751 		int	pid;
752 		int	*addr;
753 		int	data;
754 	} *uap;
755 
756 	uap = (struct a *)u.u_ap;
757 	if (uap->req <= 0) {
758 		u.u_procp->p_flag |= STRC;
759 		return;
760 	}
761 	p = pfind(uap->pid);
762 	if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid) {
763 		u.u_error = ESRCH;
764 		return;
765 	}
766 	while (ipc.ip_lock)
767 		sleep((caddr_t)&ipc, IPCPRI);
768 	ipc.ip_lock = p->p_pid;
769 	ipc.ip_data = uap->data;
770 	ipc.ip_addr = uap->addr;
771 	ipc.ip_req = uap->req;
772 	p->p_flag &= ~SWTED;
773 	while (ipc.ip_req > 0) {
774 		if (p->p_stat==SSTOP)
775 			setrun(p);
776 		sleep((caddr_t)&ipc, IPCPRI);
777 	}
778 	u.u_r.r_val1 = ipc.ip_data;
779 	if (ipc.ip_req < 0)
780 		u.u_error = EIO;
781 	ipc.ip_lock = 0;
782 	wakeup((caddr_t)&ipc);
783 }
784 
785 int ipcreg[] = {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC};
786 /*
787  * Code that the child process
788  * executes to implement the command
789  * of the parent process in tracing.
790  */
791 procxmt()
792 {
793 	register int i;
794 	register *p;
795 	register struct text *xp;
796 
797 	if (ipc.ip_lock != u.u_procp->p_pid)
798 		return (0);
799 	u.u_procp->p_slptime = 0;
800 	i = ipc.ip_req;
801 	ipc.ip_req = 0;
802 	switch (i) {
803 
804 	/* read user I */
805 	case 1:
806 		if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
807 			goto error;
808 		ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
809 		break;
810 
811 	/* read user D */
812 	case 2:
813 		if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
814 			goto error;
815 		ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
816 		break;
817 
818 	/* read u */
819 	case 3:
820 		i = (int)ipc.ip_addr;
821 		if (i<0 || i >= ctob(UPAGES))
822 			goto error;
823 		ipc.ip_data = ((physadr)&u)->r[i>>2];
824 		break;
825 
826 	/* write user I */
827 	/* Must set up to allow writing */
828 	case 4:
829 		/*
830 		 * If text, must assure exclusive use
831 		 */
832 		if (xp = u.u_procp->p_textp) {
833 			if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
834 				goto error;
835 			xp->x_iptr->i_flag &= ~ITEXT;
836 		}
837 		i = -1;
838 		if (chgprot((caddr_t)ipc.ip_addr, RW) &&
839 		    chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW))
840 			i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
841 		(void) chgprot((caddr_t)ipc.ip_addr, RO);
842 		(void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO);
843 		if (i < 0)
844 			goto error;
845 		if (xp)
846 			xp->x_flag |= XWRIT;
847 		break;
848 
849 	/* write user D */
850 	case 5:
851 		if (suword((caddr_t)ipc.ip_addr, 0) < 0)
852 			goto error;
853 		(void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
854 		break;
855 
856 	/* write u */
857 	case 6:
858 		i = (int)ipc.ip_addr;
859 		p = (int *)&((physadr)&u)->r[i>>2];
860 		for (i=0; i<16; i++)
861 			if (p == &u.u_ar0[ipcreg[i]])
862 				goto ok;
863 		if (p == &u.u_ar0[PS]) {
864 			ipc.ip_data |= PSL_CURMOD|PSL_PRVMOD;
865 			ipc.ip_data &=  ~PSL_USERCLR;
866 			goto ok;
867 		}
868 		goto error;
869 
870 	ok:
871 		*p = ipc.ip_data;
872 		break;
873 
874 	/* set signal and continue */
875 	/* one version causes a trace-trap */
876 	case 9:
877 	case 7:
878 		if ((int)ipc.ip_addr != 1)
879 			u.u_ar0[PC] = (int)ipc.ip_addr;
880 		if ((unsigned)ipc.ip_data > NSIG)
881 			goto error;
882 		u.u_procp->p_cursig = ipc.ip_data;	/* see issig */
883 		if (i == 9)
884 			u.u_ar0[PS] |= PSL_T;
885 		wakeup((caddr_t)&ipc);
886 		return (1);
887 
888 	/* force exit */
889 	case 8:
890 		wakeup((caddr_t)&ipc);
891 		exit(u.u_procp->p_cursig);
892 
893 	default:
894 	error:
895 		ipc.ip_req = -1;
896 	}
897 	wakeup((caddr_t)&ipc);
898 	return (0);
899 }
900