#pragma prototyped
#include "colib.h"
static void
hung(int sig)
{
NoP(sig);
kill(state.current->pid, SIGKILL);
}
static int
shut(register Coshell_t* co)
{
register Coshell_t* cs;
int n;
int status;
Coshell_t* ps;
Coservice_t* sv;
Sig_handler_t handler;
sfclose(co->msgfp);
close(co->cmdfd);
if (co->pid)
{
if (co->running > 0)
killpg(co->pid, SIGTERM);
state.current = co;
handler = signal(SIGALRM, hung);
n = alarm(3);
if (waitpid(co->pid, &status, 0) != co->pid)
status = -1;
alarm(n);
signal(SIGALRM, handler);
killpg(co->pid, SIGTERM);
}
else
status = 0;
if (co->flags & CO_DEBUG)
errormsg(state.lib, 2, "coshell %d jobs %d user %s sys %s", co->index, co->total, fmtelapsed(co->user, CO_QUANT), fmtelapsed(co->sys, CO_QUANT));
for (sv = co->service; sv; sv = sv->next)
{
if (sv->fd > 0)
close(sv->fd);
if (sv->pid)
waitpid(sv->pid, &status, 0);
}
cs = state.coshells;
ps = 0;
while (cs)
{
if (cs == co)
{
cs = cs->next;
if (ps)
ps->next = cs;
else
state.coshells = cs;
vmclose(co->vm);
break;
}
ps = cs;
cs = cs->next;
}
return status;
}
int
coclose(register Coshell_t* co)
{
if (co)
return shut(co);
while (state.coshells)
shut(state.coshells);
return 0;
}