9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

await.c (2937B)


      1 #define NOPLAN9DEFINES
      2 #include <u.h>
      3 #include <libc.h>
      4 
      5 #include <signal.h>
      6 #include <sys/types.h>
      7 #include <sys/wait.h>
      8 #include <sys/time.h>
      9 #include <sys/resource.h>
     10 
     11 #ifndef WCOREDUMP	/* not on Mac OS X Tiger */
     12 #define WCOREDUMP(status) 0
     13 #endif
     14 
     15 static struct {
     16 	int sig;
     17 	char *str;
     18 } tab[] = {
     19 	SIGHUP,		"hangup",
     20 	SIGINT,		"interrupt",
     21 	SIGQUIT,		"quit",
     22 	SIGILL,		"sys: illegal instruction",
     23 	SIGTRAP,		"sys: breakpoint",
     24 	SIGABRT,		"sys: abort",
     25 #ifdef SIGEMT
     26 	SIGEMT,		"sys: emulate instruction executed",
     27 #endif
     28 	SIGFPE,		"sys: fp: trap",
     29 	SIGKILL,		"sys: kill",
     30 	SIGBUS,		"sys: bus error",
     31 	SIGSEGV,		"sys: segmentation violation",
     32 	SIGALRM,		"alarm",
     33 	SIGTERM,		"kill",
     34 	SIGURG,		"sys: urgent condition on socket",
     35 	SIGSTOP,		"sys: stop",
     36 	SIGTSTP,		"sys: tstp",
     37 	SIGCONT,		"sys: cont",
     38 	SIGCHLD,		"sys: child",
     39 	SIGTTIN,		"sys: ttin",
     40 	SIGTTOU,		"sys: ttou",
     41 #ifdef SIGIO	/* not on Mac OS X Tiger */
     42 	SIGIO,		"sys: i/o possible on fd",
     43 #endif
     44 	SIGXCPU,		"sys: cpu time limit exceeded",
     45 	SIGXFSZ,		"sys: file size limit exceeded",
     46 	SIGVTALRM,	"sys: virtual time alarm",
     47 	SIGPROF,		"sys: profiling timer alarm",
     48 #ifdef SIGWINCH	/* not on Mac OS X Tiger */
     49 	SIGWINCH,	"sys: window size change",
     50 #endif
     51 #ifdef SIGINFO
     52 	SIGINFO,		"sys: status request",
     53 #endif
     54 	SIGUSR1,		"sys: usr1",
     55 	SIGUSR2,		"sys: usr2",
     56 	SIGPIPE,		"sys: write on closed pipe",
     57 };
     58 	
     59 char*
     60 _p9sigstr(int sig, char *tmp)
     61 {
     62 	int i;
     63 
     64 	for(i=0; i<nelem(tab); i++)
     65 		if(tab[i].sig == sig)
     66 			return tab[i].str;
     67 	if(tmp == nil)
     68 		return nil;
     69 	sprint(tmp, "sys: signal %d", sig);
     70 	return tmp;
     71 }
     72 
     73 int
     74 _p9strsig(char *s)
     75 {
     76 	int i;
     77 
     78 	for(i=0; i<nelem(tab); i++)
     79 		if(strcmp(s, tab[i].str) == 0)
     80 			return tab[i].sig;
     81 	return 0;
     82 }
     83 
     84 static int
     85 _await(int pid4, char *str, int n, int opt)
     86 {
     87 	int pid, status, cd;
     88 	struct rusage ru;
     89 	char buf[128], tmp[64];
     90 	ulong u, s;
     91 
     92 	for(;;){
     93 		/* On Linux, pid==-1 means anyone; on SunOS, it's pid==0. */
     94 		if(pid4 == -1)
     95 			pid = wait3(&status, opt, &ru);
     96 		else
     97 			pid = wait4(pid4, &status, opt, &ru);
     98 		if(pid <= 0)
     99 			return -1;
    100 		u = ru.ru_utime.tv_sec*1000+((ru.ru_utime.tv_usec+500)/1000);
    101 		s = ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1000);
    102 		if(WIFEXITED(status)){
    103 			status = WEXITSTATUS(status);
    104 			if(status)
    105 				snprint(buf, sizeof buf, "%d %lud %lud %lud %d", pid, u, s, u+s, status);
    106 			else
    107 				snprint(buf, sizeof buf, "%d %lud %lud %lud ''", pid, u, s, u+s, status);
    108 			strecpy(str, str+n, buf);
    109 			return strlen(str);
    110 		}
    111 		if(WIFSIGNALED(status)){
    112 			cd = WCOREDUMP(status);
    113 			snprint(buf, sizeof buf, "%d %lud %lud %lud 'signal: %s%s'", pid, u, s, u+s, _p9sigstr(WTERMSIG(status), tmp), cd ? " (core dumped)" : "");
    114 			strecpy(str, str+n, buf);
    115 			return strlen(str);
    116 		}
    117 	}
    118 }
    119 
    120 int
    121 await(char *str, int n)
    122 {
    123 	return _await(-1, str, n, 0);
    124 }
    125 
    126 int
    127 awaitnohang(char *str, int n)
    128 {
    129 	return _await(-1, str, n, WNOHANG);
    130 }
    131 
    132 int
    133 awaitfor(int pid, char *str, int n)
    134 {
    135 	return _await(pid, str, n, 0);
    136 }
    137