/* Like the csh builtin time, but from any shell Copyright 2008, David Bremner Distributed under the new BSD license*/#include <stdio.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#include <signal.h>#include <unistd.h>#include <errno.h>#include <time.h>#include <stdarg.h>#include <time.h>#include <stdio.h>#define errcheck(e) if ((long)(e)==-1L){ perror(progname);exit(1);}#define errcheck2(s,e) if ((long)(e)==-1L){ fprintf(stderr,"%s:",progname);\ perror(s);exit(1);}#define double_time(t) ((double)(t.tv_sec)+(double)(t.tv_usec)/1000000) #if 1 #define fmttime(buf,timer) strftime(buf,sizeof(buf),"%d/%m/%y %T",localtime(timer))#else#define fmttime(buf,timer) cftime(buf,"%d/%m/%y %T",timer)#endifstatic pid_t child_pid;void shutdown_rmon();void ptimes();void job_done();void errlog(char *,...);static char* progname;int main(int argc,char *argv[]){ int status; progname=argv[0]; /* Set up signal handlers: SIGTERM,SIGINT: Shutdown gracefully We use sysv signal handling here, in the hopes that it will work on both Irix and SunOS */ errcheck(signal(SIGTERM,shutdown_rmon)); errcheck(signal(SIGINT,shutdown_rmon)); errcheck(child_pid=fork()); if (!child_pid) { /* Create a new process group so that we can kill grandchildren */ errcheck2("setpgid",setpgid(0,0)); errcheck(execvp(argv[1],&argv[1])); } errcheck(waitpid(child_pid, &status,0)); ptimes(); exit(0);}void print_rusage(struct rusage *r){ fprintf(stderr,"%0.3fu %0.3fs %ldKb %ld flts %ld swaps %ld blks-in %ld blks-out\n", double_time(r->ru_utime), double_time(r->ru_stime), r->ru_maxrss,r->ru_majflt,r->ru_nswap, r->ru_inblock,r->ru_oublock);}void shutdown_rmon(){ int status; errlog("shutting down\n\n"); errcheck(kill(-1*child_pid,SIGTERM)); errcheck(waitpid(child_pid, &status,0)); ptimes(); exit(1);}void ptimes(){ struct rusage rusage; getrusage(RUSAGE_CHILDREN,&rusage); print_rusage(&rusage);}void errlog(char *format,...){ va_list args; char buf[80]; time_t t; va_start(args,format); t=time(0); fmttime(buf,&t); fprintf(stderr,"%s: <%s> ",progname,buf); vfprintf(stderr, format, args); va_end(args);}