/* kern_exit.c 6.3 84/06/10 */
#include "../machine/reg.h"
#include "../machine/psl.h"
* Exit system call: pass back caller's arg
uap
= (struct a
*)u
.u_ap
;
exit((uap
->rval
& 0377) << 8);
* Save u. area for parent to look at.
* Wake up parent and init processes,
* and dispose of children.
register struct proc
*p
, *q
, *nq
;
struct mbuf
*m
= m_getclr(M_WAIT
, MT_ZOMBIE
);
p
->p_flag
&= ~(STRC
|SULOCK
);
for (i
= 0; i
< NSIG
; i
++)
untimeout(realitexpire
, (caddr_t
)p
);
* Release virtual memory. If we resulted from
* a vfork(), instead give the resources back to
if ((p
->p_flag
& SVFORK
) == 0)
while ((p
->p_flag
& SVFDONE
) == 0)
sleep((caddr_t
)p
, PZERO
- 1);
for (i
= 0; i
< NOFILE
; i
++) {
u
.u_rlimit
[RLIMIT_FSIZE
].rlim_cur
= RLIM_INFINITY
;
(void) spl5(); /* hack for mem alloc race XXX */
if (*p
->p_prev
= p
->p_nxt
) /* off allproc queue */
p
->p_nxt
->p_prev
= p
->p_prev
;
if (p
->p_nxt
= zombproc
) /* onto zombproc */
p
->p_nxt
->p_prev
= &p
->p_nxt
;
pidhash
[i
] = p
->p_idhash
;
for (i
= pidhash
[i
]; i
!= 0; i
= proc
[i
].p_idhash
)
if (proc
[i
].p_idhash
== x
) {
proc
[i
].p_idhash
= p
->p_idhash
;
p
->p_ru
= mtod(m
, struct rusage
*);
ruadd(p
->p_ru
, &u
.u_cru
);
if (p
->p_cptr
) /* only need this if any child is S_ZOMB */
wakeup((caddr_t
)&proc
[1]);
for (q
= p
->p_cptr
; q
!= NULL
; q
= nq
) {
proc
[1].p_cptr
->p_ysptr
= q
;
q
->p_osptr
= proc
[1].p_cptr
;
* Traced processes are killed
* since their existence means someone is screwing up.
* Stopped processes are sent a hangup and a continue.
* This is designed to be ``safe'' for setuid
* processes since they must be willing to tolerate
} else if (q
->p_stat
== SSTOP
) {
* Protect this process from future
* tty signals, clear TSTP/TTIN/TTOU if pending.
psignal(p
->p_pptr
, SIGCHLD
);
wakeup((caddr_t
)p
->p_pptr
);
if ((u
.u_ar0
[PS
] & PSL_ALLCC
) != PSL_ALLCC
) {
u
.u_error
= wait1(0, (struct rusage
*)0);
rup
= (struct rusage
*)u
.u_ar0
[R1
];
u
.u_error
= wait1(u
.u_ar0
[R0
], &ru
);
if (rup
!= (struct rusage
*)0)
u
.u_error
= copyout((caddr_t
)&ru
, (caddr_t
)rup
,
* Search for a terminated (zombie) child,
* finally lay it to rest, and collect its status.
* Look also for stopped (traced) children,
* and pass back status from them.
register struct proc
*p
, *q
;
for (p
= q
->p_cptr
; p
; p
= p
->p_osptr
) {
if (p
->p_stat
== SZOMB
) {
u
.u_r
.r_val2
= p
->p_xstat
;
ruadd(&u
.u_cru
, p
->p_ru
);
(void) m_free(dtom(p
->p_ru
));
if (*p
->p_prev
= p
->p_nxt
) /* off zombproc */
p
->p_nxt
->p_prev
= p
->p_prev
;
p
->p_nxt
= freeproc
; /* onto freeproc */
if ((q
= p
->p_pptr
)->p_cptr
== p
)
if (p
->p_stat
== SSTOP
&& (p
->p_flag
&SWTED
)==0 &&
(p
->p_flag
&STRC
|| options
&WUNTRACED
)) {
u
.u_r
.r_val2
= (p
->p_cursig
<<8) | WSTOPPED
;
if ((u
.u_procp
->p_flag
&SOUSIG
) == 0 && setjmp(&u
.u_qsave
)) {
sleep((caddr_t
)u
.u_procp
, PWAIT
);