mirror of
https://github.com/golang/go
synced 2024-11-20 04:34:41 -07:00
174b8c95f5
This change depends on CL 57170052. LGTM=rsc R=rsc, bradfitz CC=golang-codereviews https://golang.org/cl/60840049
183 lines
4.1 KiB
C
183 lines
4.1 KiB
C
// +build !plan9
|
|
// +build !windows
|
|
|
|
/*
|
|
Plan 9 from User Space src/lib9/await.c
|
|
http://code.swtch.com/plan9port/src/tip/src/lib9/await.c
|
|
|
|
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
|
Portions Copyright 2009 The Go Authors. All Rights Reserved.
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
*/
|
|
|
|
#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 /* not on Mac OS X Tiger */
|
|
#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 /* not on Mac OS X Tiger */
|
|
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 /* not on Mac OS X Tiger */
|
|
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(;;){
|
|
/* On Linux, pid==-1 means anyone; on SunOS, it's pid==0. */
|
|
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);
|
|
}
|