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
main(int argc,char ** argv)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
sighand(int signum)92 sighand(int signum)
93 {
94 ticks++;
95 }
96