checkpoint
[unix-history] / usr / src / sys / kern / kern_sig.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
8fe87cbb 6 * @(#)kern_sig.c 7.4 (Berkeley) %G%
da7c5cc6 7 */
961945a8
SL
8
9#include "../machine/reg.h"
10#include "../machine/pte.h"
11#include "../machine/psl.h"
fb1db32c 12#include "../machine/mtpr.h"
687880f9 13
94368568
JB
14#include "param.h"
15#include "systm.h"
16#include "dir.h"
17#include "user.h"
18#include "inode.h"
19#include "proc.h"
20#include "timeb.h"
21#include "times.h"
94368568
JB
22#include "buf.h"
23#include "mount.h"
24#include "text.h"
25#include "seg.h"
26#include "vm.h"
27#include "acct.h"
28#include "uio.h"
29#include "kernel.h"
687880f9 30
feff6b5a 31#define cantmask (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP))
3b2ddb34
MK
32#define stopsigmask (sigmask(SIGSTOP)|sigmask(SIGTSTP)| \
33 sigmask(SIGTTIN)|sigmask(SIGTTOU))
457aa395 34
2e143991
KM
35/*
36 * Generalized interface signal handler.
37 */
4147b3f6
BJ
38sigvec()
39{
457aa395 40 register struct a {
dd012d1e 41 int signo;
457aa395
SL
42 struct sigvec *nsv;
43 struct sigvec *osv;
dd012d1e 44 } *uap = (struct a *)u.u_ap;
457aa395
SL
45 struct sigvec vec;
46 register struct sigvec *sv;
dd012d1e 47 register int sig;
fe7f81f4 48 int bit;
dd012d1e
SL
49
50 sig = uap->signo;
457aa395 51 if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) {
dd012d1e
SL
52 u.u_error = EINVAL;
53 return;
54 }
457aa395
SL
55 sv = &vec;
56 if (uap->osv) {
57 sv->sv_handler = u.u_signal[sig];
58 sv->sv_mask = u.u_sigmask[sig];
fe7f81f4
KM
59 bit = sigmask(sig);
60 sv->sv_flags = 0;
61 if ((u.u_sigonstack & bit) != 0)
62 sv->sv_flags |= SV_ONSTACK;
63 if ((u.u_sigintr & bit) != 0)
64 sv->sv_flags |= SV_INTERRUPT;
457aa395
SL
65 u.u_error =
66 copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec));
67 if (u.u_error)
68 return;
69 }
70 if (uap->nsv) {
71 u.u_error =
72 copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec));
73 if (u.u_error)
74 return;
75 if (sig == SIGCONT && sv->sv_handler == SIG_IGN) {
76 u.u_error = EINVAL;
77 return;
78 }
79 setsigvec(sig, sv);
80 }
dd012d1e 81}
4147b3f6 82
457aa395
SL
83setsigvec(sig, sv)
84 int sig;
85 register struct sigvec *sv;
dd012d1e
SL
86{
87 register struct proc *p;
457aa395 88 register int bit;
dd012d1e 89
feff6b5a 90 bit = sigmask(sig);
dd012d1e
SL
91 p = u.u_procp;
92 /*
93 * Change setting atomically.
94 */
feff6b5a 95 (void) splhigh();
457aa395
SL
96 u.u_signal[sig] = sv->sv_handler;
97 u.u_sigmask[sig] = sv->sv_mask &~ cantmask;
fe7f81f4
KM
98 if (sv->sv_flags & SV_INTERRUPT)
99 u.u_sigintr |= bit;
100 else
101 u.u_sigintr &= ~bit;
102 if (sv->sv_flags & SV_ONSTACK)
457aa395
SL
103 u.u_sigonstack |= bit;
104 else
105 u.u_sigonstack &= ~bit;
106 if (sv->sv_handler == SIG_IGN) {
107 p->p_sig &= ~bit; /* never to be seen again */
108 p->p_sigignore |= bit;
109 p->p_sigcatch &= ~bit;
dd012d1e 110 } else {
457aa395
SL
111 p->p_sigignore &= ~bit;
112 if (sv->sv_handler == SIG_DFL)
113 p->p_sigcatch &= ~bit;
dd012d1e 114 else
457aa395 115 p->p_sigcatch |= bit;
dd012d1e
SL
116 }
117 (void) spl0();
4147b3f6
BJ
118}
119
120sigblock()
121{
dd012d1e 122 struct a {
feff6b5a 123 int mask;
dd012d1e 124 } *uap = (struct a *)u.u_ap;
457aa395 125 register struct proc *p = u.u_procp;
4147b3f6 126
feff6b5a 127 (void) splhigh();
dd012d1e 128 u.u_r.r_val1 = p->p_sigmask;
feff6b5a 129 p->p_sigmask |= uap->mask &~ cantmask;
dd012d1e 130 (void) spl0();
4147b3f6
BJ
131}
132
133sigsetmask()
687880f9 134{
dd012d1e 135 struct a {
feff6b5a 136 int mask;
dd012d1e
SL
137 } *uap = (struct a *)u.u_ap;
138 register struct proc *p = u.u_procp;
687880f9 139
feff6b5a 140 (void) splhigh();
dd012d1e 141 u.u_r.r_val1 = p->p_sigmask;
feff6b5a 142 p->p_sigmask = uap->mask &~ cantmask;
dd012d1e 143 (void) spl0();
687880f9
BJ
144}
145
4147b3f6
BJ
146sigpause()
147{
dd012d1e 148 struct a {
feff6b5a 149 int mask;
dd012d1e
SL
150 } *uap = (struct a *)u.u_ap;
151 register struct proc *p = u.u_procp;
4147b3f6 152
dd012d1e
SL
153 /*
154 * When returning from sigpause, we want
155 * the old mask to be restored after the
156 * signal handler has finished. Thus, we
157 * save it here and mark the proc structure
158 * to indicate this (should be in u.).
159 */
160 u.u_oldmask = p->p_sigmask;
161 p->p_flag |= SOMASK;
feff6b5a 162 p->p_sigmask = uap->mask &~ cantmask;
dd012d1e
SL
163 for (;;)
164 sleep((caddr_t)&u, PSLEP);
165 /*NOTREACHED*/
4147b3f6 166}
457aa395 167#undef cantmask
4147b3f6
BJ
168
169sigstack()
170{
457aa395 171 register struct a {
457aa395
SL
172 struct sigstack *nss;
173 struct sigstack *oss;
dd012d1e 174 } *uap = (struct a *)u.u_ap;
457aa395 175 struct sigstack ss;
4147b3f6 176
457aa395
SL
177 if (uap->oss) {
178 u.u_error = copyout((caddr_t)&u.u_sigstack, (caddr_t)uap->oss,
179 sizeof (struct sigstack));
180 if (u.u_error)
181 return;
182 }
183 if (uap->nss) {
184 u.u_error =
185 copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss));
186 if (u.u_error == 0)
187 u.u_sigstack = ss;
188 }
4147b3f6
BJ
189}
190
1e3738da
BJ
191kill()
192{
dd012d1e
SL
193 register struct a {
194 int pid;
195 int signo;
196 } *uap = (struct a *)u.u_ap;
7713be67 197 register struct proc *p;
1e3738da 198
7713be67
KM
199 if (uap->signo < 0 || uap->signo > NSIG) {
200 u.u_error = EINVAL;
201 return;
202 }
203 if (uap->pid > 0) {
204 /* kill single process */
205 p = pfind(uap->pid);
206 if (p == 0) {
207 u.u_error = ESRCH;
208 return;
209 }
210 if (u.u_uid && u.u_uid != p->p_uid)
211 u.u_error = EPERM;
212 else if (uap->signo)
213 psignal(p, uap->signo);
214 return;
215 }
216 switch (uap->pid) {
217 case -1: /* broadcast signal */
c52373fd 218 u.u_error = killpg1(uap->signo, 0, 1);
7713be67
KM
219 break;
220 case 0: /* signal own process group */
221 u.u_error = killpg1(uap->signo, 0, 0);
222 break;
223 default: /* negative explicit process group */
224 u.u_error = killpg1(uap->signo, -uap->pid, 0);
225 break;
226 }
227 return;
1e3738da
BJ
228}
229
230killpg()
231{
3b4f6e10 232 register struct a {
8fe87cbb 233 int pgid;
3b4f6e10
SL
234 int signo;
235 } *uap = (struct a *)u.u_ap;
1e3738da 236
7713be67
KM
237 if (uap->signo < 0 || uap->signo > NSIG) {
238 u.u_error = EINVAL;
239 return;
240 }
8fe87cbb 241 u.u_error = killpg1(uap->signo, uap->pgid, 0);
1e3738da
BJ
242}
243
dd012d1e
SL
244/* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */
245
8fe87cbb
MT
246killpg1(signo, pgid, all)
247 int signo, pgid, all;
3b4f6e10
SL
248{
249 register struct proc *p;
8fe87cbb
MT
250 struct pgrp *pgrp;
251 int f = 0, error = 0;
3b4f6e10 252
8fe87cbb
MT
253
254 if (all)
255 /*
256 * broadcast
687880f9 257 */
8fe87cbb
MT
258 for (p = allproc; p != NULL; p = p->p_nxt) {
259 if (p->p_ppid == 0 || p->p_flag&SSYS ||
260 p == u.u_procp ||
261 (u.u_uid && u.u_uid != p->p_uid &&
262 !(signo == SIGCONT && inferior(p))))
263 continue;
264 f++;
265 if (signo)
266 psignal(p, signo);
267 }
268 else {
269 if (pgid == 0)
270 /*
271 * zero pgid means send to my process group.
272 */
273 pgrp = u.u_procp->p_pgrp;
274 else {
275 pgrp = pgfind(pgid);
276 if (pgrp == NULL)
277 return(ESRCH);
278 }
279 if (!(pgrp->pg_jobc) &&
280 (signo==SIGTTIN || signo==SIGTTOU || signo==SIGTSTP))
281 return(EPERM);
282 for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) {
283 if (p->p_ppid == 0 || p->p_flag&SSYS)
284 continue;
285 if (u.u_uid && u.u_uid != p->p_uid &&
286 !(signo == SIGCONT && inferior(p))) {
c52373fd 287 error = EPERM;
8fe87cbb
MT
288 continue;
289 }
290 f++;
291 if (signo)
292 psignal(p, signo);
7713be67 293 }
687880f9 294 }
8db20a41 295 return (error ? error : (f == 0 ? ESRCH : 0));
4147b3f6 296}
687880f9
BJ
297
298/*
299 * Send the specified signal to
8fe87cbb 300 * all processes with 'pgid' as
687880f9 301 * process group.
687880f9 302 */
8fe87cbb
MT
303gsignal(pgid, sig)
304{
305 register struct pgrp *pgrp;
306 register struct proc *p;
307
308 if (!pgid)
309 return;
310 if ((pgrp = pgfind(pgid)) == NULL)
311 return;
312 pgsignal(pgrp, sig);
313}
314
315pgsignal(pgrp, sig)
316 register struct pgrp *pgrp;
687880f9
BJ
317{
318 register struct proc *p;
319
8fe87cbb
MT
320 if (!(pgrp->pg_jobc) &&
321 (sig==SIGTTIN || sig==SIGTTOU || sig==SIGTSTP))
687880f9 322 return;
8fe87cbb
MT
323 for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt)
324 psignal(p, sig);
687880f9
BJ
325}
326
327/*
328 * Send the specified signal to
329 * the specified process.
330 */
331psignal(p, sig)
332 register struct proc *p;
333 register int sig;
334{
335 register int s;
336 register int (*action)();
feff6b5a 337 int mask;
687880f9
BJ
338
339 if ((unsigned)sig >= NSIG)
340 return;
feff6b5a 341 mask = sigmask(sig);
687880f9
BJ
342
343 /*
344 * If proc is traced, always give parent a chance.
687880f9
BJ
345 */
346 if (p->p_flag & STRC)
347 action = SIG_DFL;
348 else {
687880f9 349 /*
dd012d1e
SL
350 * If the signal is being ignored,
351 * then we forget about it immediately.
687880f9 352 */
feff6b5a 353 if (p->p_sigignore & mask)
687880f9 354 return;
feff6b5a 355 if (p->p_sigmask & mask)
dd012d1e 356 action = SIG_HOLD;
feff6b5a 357 else if (p->p_sigcatch & mask)
dd012d1e
SL
358 action = SIG_CATCH;
359 else
360 action = SIG_DFL;
687880f9 361 }
687880f9 362 if (sig) {
687880f9
BJ
363 switch (sig) {
364
365 case SIGTERM:
dd012d1e 366 if ((p->p_flag&STRC) || action != SIG_DFL)
687880f9
BJ
367 break;
368 /* fall into ... */
369
370 case SIGKILL:
371 if (p->p_nice > NZERO)
372 p->p_nice = NZERO;
373 break;
374
375 case SIGCONT:
3b2ddb34 376 p->p_sig &= ~stopsigmask;
687880f9
BJ
377 break;
378
687880f9
BJ
379 case SIGTSTP:
380 case SIGTTIN:
381 case SIGTTOU:
8fe87cbb
MT
382 /*FALLTHROUGH*/
383 case SIGSTOP:
feff6b5a 384 p->p_sig &= ~sigmask(SIGCONT);
687880f9
BJ
385 break;
386 }
8fe87cbb 387 p->p_sig |= mask;
687880f9 388 }
687880f9
BJ
389 /*
390 * Defer further processing for signals which are held.
391 */
392 if (action == SIG_HOLD)
393 return;
feff6b5a 394 s = splhigh();
687880f9
BJ
395 switch (p->p_stat) {
396
397 case SSLEEP:
398 /*
399 * If process is sleeping at negative priority
400 * we can't interrupt the sleep... the signal will
401 * be noticed when the process returns through
402 * trap() or syscall().
403 */
404 if (p->p_pri <= PZERO)
405 goto out;
406 /*
407 * Process is sleeping and traced... make it runnable
408 * so it can discover the signal in issig() and stop
409 * for the parent.
410 */
411 if (p->p_flag&STRC)
412 goto run;
413 switch (sig) {
414
415 case SIGSTOP:
416 case SIGTSTP:
417 case SIGTTIN:
418 case SIGTTOU:
419 /*
420 * These are the signals which by default
421 * stop a process.
422 */
423 if (action != SIG_DFL)
424 goto run;
687880f9
BJ
425 /*
426 * If a child in vfork(), stopping could
427 * cause deadlock.
428 */
429 if (p->p_flag&SVFORK)
430 goto out;
feff6b5a 431 p->p_sig &= ~mask;
687880f9 432 p->p_cursig = sig;
ad6c75cb 433 psignal(p->p_pptr, SIGCHLD);
687880f9
BJ
434 stop(p);
435 goto out;
436
437 case SIGIO:
438 case SIGURG:
439 case SIGCHLD:
434b302a 440 case SIGWINCH:
687880f9
BJ
441 /*
442 * These signals are special in that they
443 * don't get propogated... if the process
444 * isn't interested, forget it.
445 */
446 if (action != SIG_DFL)
447 goto run;
feff6b5a 448 p->p_sig &= ~mask; /* take it away */
687880f9
BJ
449 goto out;
450
451 default:
452 /*
453 * All other signals cause the process to run
454 */
455 goto run;
456 }
457 /*NOTREACHED*/
458
459 case SSTOP:
460 /*
461 * If traced process is already stopped,
462 * then no further action is necessary.
463 */
464 if (p->p_flag&STRC)
465 goto out;
466 switch (sig) {
467
468 case SIGKILL:
469 /*
470 * Kill signal always sets processes running.
471 */
472 goto run;
473
474 case SIGCONT:
475 /*
476 * If the process catches SIGCONT, let it handle
477 * the signal itself. If it isn't waiting on
478 * an event, then it goes back to run state.
479 * Otherwise, process goes back to sleep state.
480 */
481 if (action != SIG_DFL || p->p_wchan == 0)
482 goto run;
483 p->p_stat = SSLEEP;
484 goto out;
485
486 case SIGSTOP:
487 case SIGTSTP:
488 case SIGTTIN:
489 case SIGTTOU:
490 /*
491 * Already stopped, don't need to stop again.
492 * (If we did the shell could get confused.)
493 */
feff6b5a 494 p->p_sig &= ~mask; /* take it away */
687880f9
BJ
495 goto out;
496
497 default:
498 /*
499 * If process is sleeping interruptibly, then
500 * unstick it so that when it is continued
501 * it can look at the signal.
502 * But don't setrun the process as its not to
503 * be unstopped by the signal alone.
504 */
505 if (p->p_wchan && p->p_pri > PZERO)
506 unsleep(p);
507 goto out;
508 }
509 /*NOTREACHED*/
510
511 default:
512 /*
513 * SRUN, SIDL, SZOMB do nothing with the signal,
514 * other than kicking ourselves if we are running.
515 * It will either never be noticed, or noticed very soon.
516 */
517 if (p == u.u_procp && !noproc)
518 aston();
519 goto out;
520 }
521 /*NOTREACHED*/
522run:
523 /*
524 * Raise priority to at least PUSER.
525 */
526 if (p->p_pri > PUSER)
e4f89871 527 p->p_pri = PUSER;
687880f9
BJ
528 setrun(p);
529out:
530 splx(s);
531}
532
533/*
534 * Returns true if the current
535 * process has a signal to process.
536 * The signal to process is put in p_cursig.
537 * This is asked at least once each time a process enters the
538 * system (though this can usually be done without actually
539 * calling issig by checking the pending signal masks.)
540 * A signal does not do anything
541 * directly to a process; it sets
542 * a flag that asks the process to
543 * do something to itself.
544 */
545issig()
546{
547 register struct proc *p;
548 register int sig;
feff6b5a 549 int sigbits, mask;
687880f9
BJ
550
551 p = u.u_procp;
552 for (;;) {
f99e4a3a 553 sigbits = p->p_sig &~ p->p_sigmask;
687880f9 554 if ((p->p_flag&STRC) == 0)
f99e4a3a 555 sigbits &= ~p->p_sigignore;
687880f9 556 if (p->p_flag&SVFORK)
3b2ddb34 557 sigbits &= ~stopsigmask;
687880f9
BJ
558 if (sigbits == 0)
559 break;
8011f5df 560 sig = ffs((long)sigbits);
feff6b5a
JB
561 mask = sigmask(sig);
562 p->p_sig &= ~mask; /* take the signal! */
687880f9 563 p->p_cursig = sig;
dd012d1e 564 if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) {
687880f9
BJ
565 /*
566 * If traced, always stop, and stay
567 * stopped until released by the parent.
568 */
ad6c75cb 569 psignal(p->p_pptr, SIGCHLD);
687880f9
BJ
570 do {
571 stop(p);
572 swtch();
573 } while (!procxmt() && p->p_flag&STRC);
574
575 /*
f99e4a3a
SL
576 * If the traced bit got turned off,
577 * then put the signal taken above back into p_sig
578 * and go back up to the top to rescan signals.
579 * This ensures that p_sig* and u_signal are consistent.
687880f9 580 */
f99e4a3a 581 if ((p->p_flag&STRC) == 0) {
feff6b5a 582 p->p_sig |= mask;
687880f9
BJ
583 continue;
584 }
585
586 /*
587 * If parent wants us to take the signal,
588 * then it will leave it in p->p_cursig;
589 * otherwise we just look for signals again.
590 */
591 sig = p->p_cursig;
592 if (sig == 0)
593 continue;
f99e4a3a
SL
594
595 /*
596 * If signal is being masked put it back
597 * into p_sig and look for other signals.
598 */
feff6b5a
JB
599 mask = sigmask(sig);
600 if (p->p_sigmask & mask) {
601 p->p_sig |= mask;
f99e4a3a
SL
602 continue;
603 }
687880f9 604 }
a488db1a 605 switch ((int)u.u_signal[sig]) {
687880f9
BJ
606
607 case SIG_DFL:
608 /*
609 * Don't take default actions on system processes.
610 */
611 if (p->p_ppid == 0)
612 break;
613 switch (sig) {
614
615 case SIGTSTP:
616 case SIGTTIN:
617 case SIGTTOU:
687880f9
BJ
618 case SIGSTOP:
619 if (p->p_flag&STRC)
620 continue;
ad6c75cb 621 psignal(p->p_pptr, SIGCHLD);
687880f9
BJ
622 stop(p);
623 swtch();
624 continue;
625
626 case SIGCONT:
627 case SIGCHLD:
dd012d1e 628 case SIGURG:
457aa395 629 case SIGIO:
434b302a 630 case SIGWINCH:
687880f9
BJ
631 /*
632 * These signals are normally not
633 * sent if the action is the default.
634 */
635 continue; /* == ignore */
636
637 default:
638 goto send;
639 }
640 /*NOTREACHED*/
641
642 case SIG_HOLD:
643 case SIG_IGN:
644 /*
645 * Masking above should prevent us
646 * ever trying to take action on a held
647 * or ignored signal, unless process is traced.
648 */
649 if ((p->p_flag&STRC) == 0)
650 printf("issig\n");
651 continue;
652
653 default:
654 /*
655 * This signal has an action, let
656 * psig process it.
657 */
658 goto send;
659 }
660 /*NOTREACHED*/
661 }
662 /*
663 * Didn't find a signal to send.
664 */
665 p->p_cursig = 0;
666 return (0);
667
668send:
669 /*
670 * Let psig process the signal.
671 */
672 return (sig);
673}
674
687880f9
BJ
675/*
676 * Put the argument process into the stopped
ad6c75cb
MK
677 * state and notify the parent via wakeup.
678 * Signals are handled elsewhere.
687880f9
BJ
679 */
680stop(p)
681 register struct proc *p;
682{
683
684 p->p_stat = SSTOP;
685 p->p_flag &= ~SWTED;
686 wakeup((caddr_t)p->p_pptr);
687880f9
BJ
687}
688
689/*
690 * Perform the action specified by
691 * the current signal.
692 * The usual sequence is:
693 * if (issig())
694 * psig();
695 * The signal bit has already been cleared by issig,
696 * and the current signal number stored in p->p_cursig.
697 */
698psig()
699{
dd012d1e
SL
700 register struct proc *p = u.u_procp;
701 register int sig = p->p_cursig;
feff6b5a 702 int mask = sigmask(sig), returnmask;
687880f9
BJ
703 register int (*action)();
704
dd012d1e 705 if (sig == 0)
687880f9 706 panic("psig");
dd012d1e 707 action = u.u_signal[sig];
687880f9 708 if (action != SIG_DFL) {
feff6b5a 709 if (action == SIG_IGN || (p->p_sigmask & mask))
687880f9
BJ
710 panic("psig action");
711 u.u_error = 0;
687880f9 712 /*
dd012d1e
SL
713 * Set the new mask value and also defer further
714 * occurences of this signal (unless we're simulating
715 * the old signal facilities).
716 *
717 * Special case: user has done a sigpause. Here the
718 * current mask is not of interest, but rather the
719 * mask from before the sigpause is what we want restored
720 * after the signal processing is completed.
687880f9 721 */
feff6b5a 722 (void) splhigh();
dd012d1e
SL
723 if (p->p_flag & SOUSIG) {
724 if (sig != SIGILL && sig != SIGTRAP) {
725 u.u_signal[sig] = SIG_DFL;
feff6b5a 726 p->p_sigcatch &= ~mask;
dd012d1e 727 }
feff6b5a 728 mask = 0;
687880f9 729 }
dd012d1e
SL
730 if (p->p_flag & SOMASK) {
731 returnmask = u.u_oldmask;
732 p->p_flag &= ~SOMASK;
733 } else
734 returnmask = p->p_sigmask;
feff6b5a 735 p->p_sigmask |= u.u_sigmask[sig] | mask;
dd012d1e 736 (void) spl0();
1e3738da 737 u.u_ru.ru_nsignals++;
dd012d1e
SL
738 sendsig(action, sig, returnmask);
739 p->p_cursig = 0;
687880f9
BJ
740 return;
741 }
742 u.u_acflag |= AXSIG;
dd012d1e 743 switch (sig) {
687880f9
BJ
744
745 case SIGILL:
746 case SIGIOT:
747 case SIGBUS:
748 case SIGQUIT:
749 case SIGTRAP:
750 case SIGEMT:
751 case SIGFPE:
752 case SIGSEGV:
753 case SIGSYS:
dd012d1e 754 u.u_arg[0] = sig;
687880f9 755 if (core())
dd012d1e 756 sig += 0200;
687880f9 757 }
dd012d1e 758 exit(sig);
687880f9
BJ
759}
760
687880f9
BJ
761/*
762 * Create a core image on the file "core"
763 * If you are looking for protection glitches,
764 * there are probably a wealth of them here
765 * when this occurs to a suid command.
766 *
767 * It writes UPAGES block of the
768 * user.h area followed by the entire
769 * data+stack segments.
770 */
771core()
772{
773 register struct inode *ip;
715baff1 774 register struct nameidata *ndp = &u.u_nd;
687880f9 775
be6bd5b8 776 if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid)
7b0cb7cb 777 return (0);
1e3738da
BJ
778 if (ctob(UPAGES+u.u_dsize+u.u_ssize) >=
779 u.u_rlimit[RLIMIT_CORE].rlim_cur)
687880f9 780 return (0);
362072cf
KM
781 if (u.u_procp->p_textp && access(u.u_procp->p_textp->x_iptr, IREAD))
782 return (0);
687880f9 783 u.u_error = 0;
715baff1
KM
784 ndp->ni_nameiop = CREATE | FOLLOW;
785 ndp->ni_segflg = UIO_SYSSPACE;
786 ndp->ni_dirp = "core";
787 ip = namei(ndp);
687880f9
BJ
788 if (ip == NULL) {
789 if (u.u_error)
790 return (0);
715baff1 791 ip = maknode(0644, ndp);
687880f9
BJ
792 if (ip==NULL)
793 return (0);
794 }
7b0cb7cb
BJ
795 if (access(ip, IWRITE) ||
796 (ip->i_mode&IFMT) != IFREG ||
797 ip->i_nlink != 1) {
687880f9 798 u.u_error = EFAULT;
7b0cb7cb
BJ
799 goto out;
800 }
728df0db
SL
801#ifdef MMAP
802 { register int fd;
803 /* unmasp funky devices in the user's address space */
804 for (fd = 0; fd < u.u_lastfile; fd++)
805 if (u.u_ofile[fd] && (u.u_pofile[fd] & UF_MAPPED))
806 munmapfd(fd);
807 }
808#endif
4f083fd7 809 itrunc(ip, (u_long)0);
7b0cb7cb 810 u.u_acflag |= ACORE;
dd012d1e
SL
811 u.u_error = rdwri(UIO_WRITE, ip,
812 (caddr_t)&u,
813 ctob(UPAGES),
8011f5df 814 (off_t)0, 1, (int *)0);
1edb1cf8 815 if (u.u_error == 0)
a1edc12b 816 u.u_error = rdwri(UIO_WRITE, ip,
e0fc9a90 817 (caddr_t)ctob(dptov(u.u_procp, 0)),
8011f5df
MK
818 (int)ctob(u.u_dsize),
819 (off_t)ctob(UPAGES), 0, (int *)0);
1edb1cf8 820 if (u.u_error == 0)
a1edc12b 821 u.u_error = rdwri(UIO_WRITE, ip,
e0fc9a90 822 (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)),
8011f5df
MK
823 (int)ctob(u.u_ssize),
824 (off_t)ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0);
7b0cb7cb 825out:
687880f9 826 iput(ip);
7b0cb7cb 827 return (u.u_error == 0);
687880f9 828}