This source file includes following definitions.
- _p9sigstr
- _p9strsig
- _wait
- p9wait
- p9waitfor
- p9waitnohang
- p9waitpid
#define NOPLAN9DEFINES
#include <u.h>
#include <libc.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#ifndef WCOREDUMP
#define WCOREDUMP(status) 0
#endif
static struct {
int sig;
char *str;
} tab[] = {
SIGHUP, "hangup",
SIGINT, "interrupt",
SIGQUIT, "quit",
SIGILL, "sys: illegal instruction",
SIGTRAP, "sys: breakpoint",
SIGABRT, "sys: abort",
#ifdef SIGEMT
SIGEMT, "sys: emulate instruction executed",
#endif
SIGFPE, "sys: fp: trap",
SIGKILL, "sys: kill",
SIGBUS, "sys: bus error",
SIGSEGV, "sys: segmentation violation",
SIGALRM, "alarm",
SIGTERM, "kill",
SIGURG, "sys: urgent condition on socket",
SIGSTOP, "sys: stop",
SIGTSTP, "sys: tstp",
SIGCONT, "sys: cont",
SIGCHLD, "sys: child",
SIGTTIN, "sys: ttin",
SIGTTOU, "sys: ttou",
#ifdef SIGIO
SIGIO, "sys: i/o possible on fd",
#endif
SIGXCPU, "sys: cpu time limit exceeded",
SIGXFSZ, "sys: file size limit exceeded",
SIGVTALRM, "sys: virtual time alarm",
SIGPROF, "sys: profiling timer alarm",
#ifdef SIGWINCH
SIGWINCH, "sys: window size change",
#endif
#ifdef SIGINFO
SIGINFO, "sys: status request",
#endif
SIGUSR1, "sys: usr1",
SIGUSR2, "sys: usr2",
SIGPIPE, "sys: write on closed pipe",
};
char*
_p9sigstr(int sig, char *tmp)
{
int i;
for(i=0; i<nelem(tab); i++)
if(tab[i].sig == sig)
return tab[i].str;
if(tmp == nil)
return nil;
sprint(tmp, "sys: signal %d", sig);
return tmp;
}
int
_p9strsig(char *s)
{
int i;
for(i=0; i<nelem(tab); i++)
if(strcmp(s, tab[i].str) == 0)
return tab[i].sig;
return 0;
}
static Waitmsg*
_wait(int pid4, int opt)
{
int pid, status, cd;
struct rusage ru;
char tmp[64];
ulong u, s;
Waitmsg *w;
w = malloc(sizeof *w + 200);
if(w == nil)
return nil;
memset(w, 0, sizeof *w);
w->msg = (char*)&w[1];
for(;;){
if(pid4 == -1)
pid = wait3(&status, opt, &ru);
else
pid = wait4(pid4, &status, opt, &ru);
if(pid <= 0) {
free(w);
return nil;
}
u = (ulong)(ru.ru_utime.tv_sec*1000+((ru.ru_utime.tv_usec+500)/1000));
s = (ulong)(ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1000));
w->pid = pid;
w->time[0] = u;
w->time[1] = s;
w->time[2] = u+s;
if(WIFEXITED(status)){
if(status)
sprint(w->msg, "%d", status);
return w;
}
if(WIFSIGNALED(status)){
cd = WCOREDUMP(status);
sprint(w->msg, "signal: %s", _p9sigstr(WTERMSIG(status), tmp));
if(cd)
strcat(w->msg, " (core dumped)");
return w;
}
}
}
Waitmsg*
p9wait(void)
{
return _wait(-1, 0);
}
Waitmsg*
p9waitfor(int pid)
{
return _wait(pid, 0);
}
Waitmsg*
p9waitnohang(void)
{
return _wait(-1, WNOHANG);
}
int
p9waitpid(void)
{
int status;
return wait(&status);
}