1 /* $OpenBSD: itimer.c,v 1.2 2013/09/12 23:06:44 krw Exp $ */ 2 /* 3 * Written by Artur Grabowski <art@openbsd.org> 2004 Public Domain. 4 */ 5 #include <sys/types.h> 6 #include <sys/time.h> 7 #include <sys/resource.h> 8 9 #include <stdlib.h> 10 #include <stdio.h> 11 #include <unistd.h> 12 #include <time.h> 13 #include <err.h> 14 #include <signal.h> 15 16 void sighand(int); 17 18 volatile sig_atomic_t ticks; 19 20 #define TIMEOUT 2 21 22 int 23 main(int argc, char **argv) 24 { 25 struct timeval stv, tv; 26 struct itimerval itv; 27 struct rusage ru; 28 int which, sig; 29 int ch; 30 31 while ((ch = getopt(argc, argv, "rvp")) != -1) { 32 switch (ch) { 33 case 'r': 34 which = ITIMER_REAL; 35 sig = SIGALRM; 36 break; 37 case 'v': 38 which = ITIMER_VIRTUAL; 39 sig = SIGVTALRM; 40 break; 41 case 'p': 42 which = ITIMER_PROF; 43 sig = SIGPROF; 44 break; 45 default: 46 fprintf(stderr, "Usage: itimer [-rvp]\n"); 47 exit(1); 48 } 49 } 50 51 signal(sig, sighand); 52 53 itv.it_value.tv_sec = 0; 54 itv.it_value.tv_usec = 100000; 55 itv.it_interval = itv.it_value; 56 57 if (setitimer(which, &itv, NULL) != 0) 58 err(1, "setitimer"); 59 60 gettimeofday(&stv, NULL); 61 while (ticks != TIMEOUT * 10) 62 ; 63 64 switch (which) { 65 case ITIMER_REAL: 66 gettimeofday(&tv, NULL); 67 timersub(&tv, &stv, &tv); 68 break; 69 case ITIMER_VIRTUAL: 70 case ITIMER_PROF: 71 if (getrusage(RUSAGE_SELF, &ru) != 0) 72 err(1, "getrusage"); 73 tv = ru.ru_utime; 74 break; 75 } 76 stv.tv_sec = TIMEOUT; 77 stv.tv_usec = 0; 78 79 if (timercmp(&stv, &tv, <)) 80 timersub(&tv, &stv, &tv); 81 else 82 timersub(&stv, &tv, &tv); 83 84 if (tv.tv_sec != 0 || tv.tv_usec > 100000) 85 errx(1, "timer difference too big: %lld.%ld", 86 (long long)tv.tv_sec, tv.tv_usec); 87 88 return (0); 89 } 90 91 void 92 sighand(int signum) 93 { 94 ticks++; 95 } 96