added depend label
[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 *
728df0db 6 * @(#)kern_sig.c 7.3 (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
SL
232 register struct a {
233 int pgrp;
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 }
241 u.u_error = killpg1(uap->signo, uap->pgrp, 0);
1e3738da
BJ
242}
243
dd012d1e
SL
244/* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */
245
7713be67
KM
246killpg1(signo, pgrp, all)
247 int signo, pgrp, all;
3b4f6e10
SL
248{
249 register struct proc *p;
7713be67 250 int f, error = 0;
3b4f6e10 251
7713be67 252 if (!all && pgrp == 0) {
687880f9
BJ
253 /*
254 * Zero process id means send to my process group.
255 */
7713be67
KM
256 pgrp = u.u_procp->p_pgrp;
257 if (pgrp == 0)
c52373fd 258 return (ESRCH);
687880f9 259 }
1d348849 260 for (f = 0, p = allproc; p != NULL; p = p->p_nxt) {
7713be67
KM
261 if ((p->p_pgrp != pgrp && !all) || p->p_ppid == 0 ||
262 (p->p_flag&SSYS) || (all && p == u.u_procp))
687880f9
BJ
263 continue;
264 if (u.u_uid != 0 && u.u_uid != p->p_uid &&
7713be67 265 (signo != SIGCONT || !inferior(p))) {
c52373fd
KM
266 if (!all)
267 error = EPERM;
687880f9 268 continue;
7713be67 269 }
c52373fd 270 f++;
dc7d58ca
SL
271 if (signo)
272 psignal(p, signo);
687880f9 273 }
8db20a41 274 return (error ? error : (f == 0 ? ESRCH : 0));
4147b3f6 275}
687880f9
BJ
276
277/*
278 * Send the specified signal to
279 * all processes with 'pgrp' as
280 * process group.
687880f9
BJ
281 */
282gsignal(pgrp, sig)
283 register int pgrp;
284{
285 register struct proc *p;
286
287 if (pgrp == 0)
288 return;
1d348849 289 for (p = allproc; p != NULL; p = p->p_nxt)
687880f9
BJ
290 if (p->p_pgrp == pgrp)
291 psignal(p, sig);
292}
293
294/*
295 * Send the specified signal to
296 * the specified process.
297 */
298psignal(p, sig)
299 register struct proc *p;
300 register int sig;
301{
302 register int s;
303 register int (*action)();
feff6b5a 304 int mask;
687880f9
BJ
305
306 if ((unsigned)sig >= NSIG)
307 return;
feff6b5a 308 mask = sigmask(sig);
687880f9
BJ
309
310 /*
311 * If proc is traced, always give parent a chance.
687880f9
BJ
312 */
313 if (p->p_flag & STRC)
314 action = SIG_DFL;
315 else {
687880f9 316 /*
dd012d1e
SL
317 * If the signal is being ignored,
318 * then we forget about it immediately.
687880f9 319 */
feff6b5a 320 if (p->p_sigignore & mask)
687880f9 321 return;
feff6b5a 322 if (p->p_sigmask & mask)
dd012d1e 323 action = SIG_HOLD;
feff6b5a 324 else if (p->p_sigcatch & mask)
dd012d1e
SL
325 action = SIG_CATCH;
326 else
327 action = SIG_DFL;
687880f9 328 }
687880f9 329 if (sig) {
feff6b5a 330 p->p_sig |= mask;
687880f9
BJ
331 switch (sig) {
332
333 case SIGTERM:
dd012d1e 334 if ((p->p_flag&STRC) || action != SIG_DFL)
687880f9
BJ
335 break;
336 /* fall into ... */
337
338 case SIGKILL:
339 if (p->p_nice > NZERO)
340 p->p_nice = NZERO;
341 break;
342
343 case SIGCONT:
3b2ddb34 344 p->p_sig &= ~stopsigmask;
687880f9
BJ
345 break;
346
347 case SIGSTOP:
348 case SIGTSTP:
349 case SIGTTIN:
350 case SIGTTOU:
feff6b5a 351 p->p_sig &= ~sigmask(SIGCONT);
687880f9
BJ
352 break;
353 }
354 }
687880f9
BJ
355 /*
356 * Defer further processing for signals which are held.
357 */
358 if (action == SIG_HOLD)
359 return;
feff6b5a 360 s = splhigh();
687880f9
BJ
361 switch (p->p_stat) {
362
363 case SSLEEP:
364 /*
365 * If process is sleeping at negative priority
366 * we can't interrupt the sleep... the signal will
367 * be noticed when the process returns through
368 * trap() or syscall().
369 */
370 if (p->p_pri <= PZERO)
371 goto out;
372 /*
373 * Process is sleeping and traced... make it runnable
374 * so it can discover the signal in issig() and stop
375 * for the parent.
376 */
377 if (p->p_flag&STRC)
378 goto run;
379 switch (sig) {
380
381 case SIGSTOP:
382 case SIGTSTP:
383 case SIGTTIN:
384 case SIGTTOU:
385 /*
386 * These are the signals which by default
387 * stop a process.
388 */
389 if (action != SIG_DFL)
390 goto run;
391 /*
392 * Don't clog system with children of init
393 * stopped from the keyboard.
394 */
395 if (sig != SIGSTOP && p->p_pptr == &proc[1]) {
396 psignal(p, SIGKILL);
feff6b5a 397 p->p_sig &= ~mask;
687880f9
BJ
398 splx(s);
399 return;
400 }
401 /*
402 * If a child in vfork(), stopping could
403 * cause deadlock.
404 */
405 if (p->p_flag&SVFORK)
406 goto out;
feff6b5a 407 p->p_sig &= ~mask;
687880f9 408 p->p_cursig = sig;
ad6c75cb 409 psignal(p->p_pptr, SIGCHLD);
687880f9
BJ
410 stop(p);
411 goto out;
412
413 case SIGIO:
414 case SIGURG:
415 case SIGCHLD:
434b302a 416 case SIGWINCH:
687880f9
BJ
417 /*
418 * These signals are special in that they
419 * don't get propogated... if the process
420 * isn't interested, forget it.
421 */
422 if (action != SIG_DFL)
423 goto run;
feff6b5a 424 p->p_sig &= ~mask; /* take it away */
687880f9
BJ
425 goto out;
426
427 default:
428 /*
429 * All other signals cause the process to run
430 */
431 goto run;
432 }
433 /*NOTREACHED*/
434
435 case SSTOP:
436 /*
437 * If traced process is already stopped,
438 * then no further action is necessary.
439 */
440 if (p->p_flag&STRC)
441 goto out;
442 switch (sig) {
443
444 case SIGKILL:
445 /*
446 * Kill signal always sets processes running.
447 */
448 goto run;
449
450 case SIGCONT:
451 /*
452 * If the process catches SIGCONT, let it handle
453 * the signal itself. If it isn't waiting on
454 * an event, then it goes back to run state.
455 * Otherwise, process goes back to sleep state.
456 */
457 if (action != SIG_DFL || p->p_wchan == 0)
458 goto run;
459 p->p_stat = SSLEEP;
460 goto out;
461
462 case SIGSTOP:
463 case SIGTSTP:
464 case SIGTTIN:
465 case SIGTTOU:
466 /*
467 * Already stopped, don't need to stop again.
468 * (If we did the shell could get confused.)
469 */
feff6b5a 470 p->p_sig &= ~mask; /* take it away */
687880f9
BJ
471 goto out;
472
473 default:
474 /*
475 * If process is sleeping interruptibly, then
476 * unstick it so that when it is continued
477 * it can look at the signal.
478 * But don't setrun the process as its not to
479 * be unstopped by the signal alone.
480 */
481 if (p->p_wchan && p->p_pri > PZERO)
482 unsleep(p);
483 goto out;
484 }
485 /*NOTREACHED*/
486
487 default:
488 /*
489 * SRUN, SIDL, SZOMB do nothing with the signal,
490 * other than kicking ourselves if we are running.
491 * It will either never be noticed, or noticed very soon.
492 */
493 if (p == u.u_procp && !noproc)
494 aston();
495 goto out;
496 }
497 /*NOTREACHED*/
498run:
499 /*
500 * Raise priority to at least PUSER.
501 */
502 if (p->p_pri > PUSER)
e4f89871 503 p->p_pri = PUSER;
687880f9
BJ
504 setrun(p);
505out:
506 splx(s);
507}
508
509/*
510 * Returns true if the current
511 * process has a signal to process.
512 * The signal to process is put in p_cursig.
513 * This is asked at least once each time a process enters the
514 * system (though this can usually be done without actually
515 * calling issig by checking the pending signal masks.)
516 * A signal does not do anything
517 * directly to a process; it sets
518 * a flag that asks the process to
519 * do something to itself.
520 */
521issig()
522{
523 register struct proc *p;
524 register int sig;
feff6b5a 525 int sigbits, mask;
687880f9
BJ
526
527 p = u.u_procp;
528 for (;;) {
f99e4a3a 529 sigbits = p->p_sig &~ p->p_sigmask;
687880f9 530 if ((p->p_flag&STRC) == 0)
f99e4a3a 531 sigbits &= ~p->p_sigignore;
687880f9 532 if (p->p_flag&SVFORK)
3b2ddb34 533 sigbits &= ~stopsigmask;
687880f9
BJ
534 if (sigbits == 0)
535 break;
8011f5df 536 sig = ffs((long)sigbits);
feff6b5a
JB
537 mask = sigmask(sig);
538 p->p_sig &= ~mask; /* take the signal! */
687880f9 539 p->p_cursig = sig;
dd012d1e 540 if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) {
687880f9
BJ
541 /*
542 * If traced, always stop, and stay
543 * stopped until released by the parent.
544 */
ad6c75cb 545 psignal(p->p_pptr, SIGCHLD);
687880f9
BJ
546 do {
547 stop(p);
548 swtch();
549 } while (!procxmt() && p->p_flag&STRC);
550
551 /*
f99e4a3a
SL
552 * If the traced bit got turned off,
553 * then put the signal taken above back into p_sig
554 * and go back up to the top to rescan signals.
555 * This ensures that p_sig* and u_signal are consistent.
687880f9 556 */
f99e4a3a 557 if ((p->p_flag&STRC) == 0) {
feff6b5a 558 p->p_sig |= mask;
687880f9
BJ
559 continue;
560 }
561
562 /*
563 * If parent wants us to take the signal,
564 * then it will leave it in p->p_cursig;
565 * otherwise we just look for signals again.
566 */
567 sig = p->p_cursig;
568 if (sig == 0)
569 continue;
f99e4a3a
SL
570
571 /*
572 * If signal is being masked put it back
573 * into p_sig and look for other signals.
574 */
feff6b5a
JB
575 mask = sigmask(sig);
576 if (p->p_sigmask & mask) {
577 p->p_sig |= mask;
f99e4a3a
SL
578 continue;
579 }
687880f9 580 }
a488db1a 581 switch ((int)u.u_signal[sig]) {
687880f9
BJ
582
583 case SIG_DFL:
584 /*
585 * Don't take default actions on system processes.
586 */
587 if (p->p_ppid == 0)
588 break;
589 switch (sig) {
590
591 case SIGTSTP:
592 case SIGTTIN:
593 case SIGTTOU:
594 /*
595 * Children of init aren't allowed to stop
596 * on signals from the keyboard.
597 */
598 if (p->p_pptr == &proc[1]) {
599 psignal(p, SIGKILL);
600 continue;
601 }
602 /* fall into ... */
603
604 case SIGSTOP:
605 if (p->p_flag&STRC)
606 continue;
ad6c75cb 607 psignal(p->p_pptr, SIGCHLD);
687880f9
BJ
608 stop(p);
609 swtch();
610 continue;
611
612 case SIGCONT:
613 case SIGCHLD:
dd012d1e 614 case SIGURG:
457aa395 615 case SIGIO:
434b302a 616 case SIGWINCH:
687880f9
BJ
617 /*
618 * These signals are normally not
619 * sent if the action is the default.
620 */
621 continue; /* == ignore */
622
623 default:
624 goto send;
625 }
626 /*NOTREACHED*/
627
628 case SIG_HOLD:
629 case SIG_IGN:
630 /*
631 * Masking above should prevent us
632 * ever trying to take action on a held
633 * or ignored signal, unless process is traced.
634 */
635 if ((p->p_flag&STRC) == 0)
636 printf("issig\n");
637 continue;
638
639 default:
640 /*
641 * This signal has an action, let
642 * psig process it.
643 */
644 goto send;
645 }
646 /*NOTREACHED*/
647 }
648 /*
649 * Didn't find a signal to send.
650 */
651 p->p_cursig = 0;
652 return (0);
653
654send:
655 /*
656 * Let psig process the signal.
657 */
658 return (sig);
659}
660
687880f9
BJ
661/*
662 * Put the argument process into the stopped
ad6c75cb
MK
663 * state and notify the parent via wakeup.
664 * Signals are handled elsewhere.
687880f9
BJ
665 */
666stop(p)
667 register struct proc *p;
668{
669
670 p->p_stat = SSTOP;
671 p->p_flag &= ~SWTED;
672 wakeup((caddr_t)p->p_pptr);
687880f9
BJ
673}
674
675/*
676 * Perform the action specified by
677 * the current signal.
678 * The usual sequence is:
679 * if (issig())
680 * psig();
681 * The signal bit has already been cleared by issig,
682 * and the current signal number stored in p->p_cursig.
683 */
684psig()
685{
dd012d1e
SL
686 register struct proc *p = u.u_procp;
687 register int sig = p->p_cursig;
feff6b5a 688 int mask = sigmask(sig), returnmask;
687880f9
BJ
689 register int (*action)();
690
dd012d1e 691 if (sig == 0)
687880f9 692 panic("psig");
dd012d1e 693 action = u.u_signal[sig];
687880f9 694 if (action != SIG_DFL) {
feff6b5a 695 if (action == SIG_IGN || (p->p_sigmask & mask))
687880f9
BJ
696 panic("psig action");
697 u.u_error = 0;
687880f9 698 /*
dd012d1e
SL
699 * Set the new mask value and also defer further
700 * occurences of this signal (unless we're simulating
701 * the old signal facilities).
702 *
703 * Special case: user has done a sigpause. Here the
704 * current mask is not of interest, but rather the
705 * mask from before the sigpause is what we want restored
706 * after the signal processing is completed.
687880f9 707 */
feff6b5a 708 (void) splhigh();
dd012d1e
SL
709 if (p->p_flag & SOUSIG) {
710 if (sig != SIGILL && sig != SIGTRAP) {
711 u.u_signal[sig] = SIG_DFL;
feff6b5a 712 p->p_sigcatch &= ~mask;
dd012d1e 713 }
feff6b5a 714 mask = 0;
687880f9 715 }
dd012d1e
SL
716 if (p->p_flag & SOMASK) {
717 returnmask = u.u_oldmask;
718 p->p_flag &= ~SOMASK;
719 } else
720 returnmask = p->p_sigmask;
feff6b5a 721 p->p_sigmask |= u.u_sigmask[sig] | mask;
dd012d1e 722 (void) spl0();
1e3738da 723 u.u_ru.ru_nsignals++;
dd012d1e
SL
724 sendsig(action, sig, returnmask);
725 p->p_cursig = 0;
687880f9
BJ
726 return;
727 }
728 u.u_acflag |= AXSIG;
dd012d1e 729 switch (sig) {
687880f9
BJ
730
731 case SIGILL:
732 case SIGIOT:
733 case SIGBUS:
734 case SIGQUIT:
735 case SIGTRAP:
736 case SIGEMT:
737 case SIGFPE:
738 case SIGSEGV:
739 case SIGSYS:
dd012d1e 740 u.u_arg[0] = sig;
687880f9 741 if (core())
dd012d1e 742 sig += 0200;
687880f9 743 }
dd012d1e 744 exit(sig);
687880f9
BJ
745}
746
687880f9
BJ
747/*
748 * Create a core image on the file "core"
749 * If you are looking for protection glitches,
750 * there are probably a wealth of them here
751 * when this occurs to a suid command.
752 *
753 * It writes UPAGES block of the
754 * user.h area followed by the entire
755 * data+stack segments.
756 */
757core()
758{
759 register struct inode *ip;
715baff1 760 register struct nameidata *ndp = &u.u_nd;
687880f9 761
be6bd5b8 762 if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid)
7b0cb7cb 763 return (0);
1e3738da
BJ
764 if (ctob(UPAGES+u.u_dsize+u.u_ssize) >=
765 u.u_rlimit[RLIMIT_CORE].rlim_cur)
687880f9 766 return (0);
362072cf
KM
767 if (u.u_procp->p_textp && access(u.u_procp->p_textp->x_iptr, IREAD))
768 return (0);
687880f9 769 u.u_error = 0;
715baff1
KM
770 ndp->ni_nameiop = CREATE | FOLLOW;
771 ndp->ni_segflg = UIO_SYSSPACE;
772 ndp->ni_dirp = "core";
773 ip = namei(ndp);
687880f9
BJ
774 if (ip == NULL) {
775 if (u.u_error)
776 return (0);
715baff1 777 ip = maknode(0644, ndp);
687880f9
BJ
778 if (ip==NULL)
779 return (0);
780 }
7b0cb7cb
BJ
781 if (access(ip, IWRITE) ||
782 (ip->i_mode&IFMT) != IFREG ||
783 ip->i_nlink != 1) {
687880f9 784 u.u_error = EFAULT;
7b0cb7cb
BJ
785 goto out;
786 }
728df0db
SL
787#ifdef MMAP
788 { register int fd;
789 /* unmasp funky devices in the user's address space */
790 for (fd = 0; fd < u.u_lastfile; fd++)
791 if (u.u_ofile[fd] && (u.u_pofile[fd] & UF_MAPPED))
792 munmapfd(fd);
793 }
794#endif
4f083fd7 795 itrunc(ip, (u_long)0);
7b0cb7cb 796 u.u_acflag |= ACORE;
dd012d1e
SL
797 u.u_error = rdwri(UIO_WRITE, ip,
798 (caddr_t)&u,
799 ctob(UPAGES),
8011f5df 800 (off_t)0, 1, (int *)0);
1edb1cf8 801 if (u.u_error == 0)
a1edc12b 802 u.u_error = rdwri(UIO_WRITE, ip,
e0fc9a90 803 (caddr_t)ctob(dptov(u.u_procp, 0)),
8011f5df
MK
804 (int)ctob(u.u_dsize),
805 (off_t)ctob(UPAGES), 0, (int *)0);
1edb1cf8 806 if (u.u_error == 0)
a1edc12b 807 u.u_error = rdwri(UIO_WRITE, ip,
e0fc9a90 808 (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)),
8011f5df
MK
809 (int)ctob(u.u_ssize),
810 (off_t)ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0);
7b0cb7cb 811out:
687880f9 812 iput(ip);
7b0cb7cb 813 return (u.u_error == 0);
687880f9 814}