#define NOPLAN9DEFINES #include <u.h> #include <libc.h> #include <signal.h> #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> #include <sys/wait.h> static struct { int sig; char *str; } tab[] = { SIGHUP, "hangup", SIGINT, "interrupt", SIGQUIT, "quit", SIGILL, "sys: trap: illegal instruction", SIGTRAP, "sys: trace trap", 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", SIGIO, "sys: i/o possible on fd", SIGXCPU, "sys: cpu time limit exceeded", SIGXFSZ, "sys: file size limit exceeded", SIGVTALRM, "sys: virtual time alarm", SIGPROF, "sys: profiling timer alarm", SIGWINCH, "sys: window size change", #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 int _await(char *str, int n, int opt) { int pid, status, cd; struct rusage ru; char buf[128], tmp[64]; ulong u, s; for(;;){ pid = wait3(&status, opt, &ru); if(pid <= 0) return -1; u = ru.ru_utime.tv_sec*1000+((ru.ru_utime.tv_usec+500)/1000); s = ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1000); if(WIFEXITED(status)){ status = WEXITSTATUS(status); if(status) snprint(buf, sizeof buf, "%d %lud %lud %lud %d", pid, u, s, u+s, status); else snprint(buf, sizeof buf, "%d %lud %lud %lud ''", pid, u, s, u+s, status); strecpy(str, str+n, buf); return strlen(str); } if(WIFSIGNALED(status)){ cd = WCOREDUMP(status); USED(cd); snprint(buf, sizeof buf, "%d %lud %lud %lud '%s'", pid, u, s, u+s, _p9sigstr(WTERMSIG(status), tmp)); strecpy(str, str+n, buf); return strlen(str); } } } int await(char *str, int n) { return _await(str, n, 0); } int awaitnohang(char *str, int n) { return _await(str, n, WNOHANG); }