1 /* Tests for getitimer(2)/setitimer(2) - by D.C. van Moolenbroek */ 2 /* Warning: this test deals with (real and virtual) time, and, lacking a proper 3 * point of reference, its correctness depends on circumstances like CPU speed 4 * and system load. A succeeding test run says a lot - failure not so much. */ 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <time.h> 9 #include <minix/config.h> 10 #include <sys/types.h> 11 #include <sys/time.h> 12 #include <sys/wait.h> 13 #include <sys/syslimits.h> 14 #include <signal.h> 15 #include <unistd.h> 16 #include <errno.h> 17 18 #define ITERATIONS 3 19 int max_error = 4; 20 #include "common.h" 21 22 23 24 /* we have to keep in mind the millisecond values are rounded up */ 25 #define UPPERUSEC(us) ((us)+(1000000/system_hz)) 26 #define EQUSEC(l,r) \ 27 ((l) <= ((r) + (1000000/system_hz)) && (l) >= ((r) - (1000000/system_hz))) 28 29 #define FILLITIMER(it, vs, vu, is, iu) \ 30 (it).it_value.tv_sec = (vs); \ 31 (it).it_value.tv_usec = (vu); \ 32 (it).it_interval.tv_sec = (is); \ 33 (it).it_interval.tv_usec = (iu); 34 35 /* these two macros are not fully working for all possible values; 36 * the tests only use values that the macros can deal with, though. */ 37 #define EQITIMER(it, vs, vu, is, iu) \ 38 ((it).it_value.tv_sec == (vs) && EQUSEC((it).it_value.tv_usec,vu) && \ 39 (it).it_interval.tv_sec == (is) && (it).it_interval.tv_usec == (iu)) 40 41 #define LEITIMER(it, vs, vu, is, iu) \ 42 ((it).it_value.tv_sec > 0 && ((it).it_value.tv_sec < (vs) || \ 43 ((it).it_value.tv_sec == (vs) && (it).it_value.tv_usec <= \ 44 UPPERUSEC(vu))) && \ 45 (it).it_interval.tv_sec == (is) && EQUSEC((it).it_interval.tv_usec,iu)) 46 47 int main(int argc, char **argv); 48 void test(int m, int t); 49 void test_which(void); 50 void test_getset(void); 51 void test_neglarge(void); 52 void test_zero(void); 53 void test_timer(void); 54 void test_alarm(void); 55 void test_fork(void); 56 void test_exec(void); 57 int do_check(void); 58 void got_alarm(int sig); 59 void busy_wait(int secs); 60 #define my_e(n) do { printf("Timer %s, ", names[timer]); e(n); } while(0) 61 62 static char *executable; 63 static int signals; 64 static int timer; 65 static long system_hz; 66 67 static int sigs[] = { SIGALRM, SIGVTALRM, SIGPROF }; 68 static const char *names[] = { "REAL", "VIRTUAL", "PROF" }; 69 70 int main(argc, argv) 71 int argc; 72 char **argv; 73 { 74 int i, m = 0xFFFF, n = 0xF; 75 char cp_cmd[NAME_MAX+10]; 76 77 system_hz = sysconf(_SC_CLK_TCK); 78 79 if (strcmp(argv[0], "DO CHECK") == 0) { 80 timer = atoi(argv[1]); 81 82 exit(do_check()); 83 } 84 85 executable = argv[0]; 86 87 start(41); 88 89 snprintf(cp_cmd, sizeof(cp_cmd), "cp ../%s .", executable); 90 system(cp_cmd); 91 92 if (argc >= 2) m = atoi(argv[1]); 93 if (argc >= 3) n = atoi(argv[2]); 94 95 for (i = 0; i < ITERATIONS; i++) { 96 if (n & 1) test(m, ITIMER_REAL); 97 if (n & 2) test(m, ITIMER_VIRTUAL); 98 if (n & 4) test(m, ITIMER_PROF); 99 } 100 101 quit(); 102 return(-1); /* impossible */ 103 } 104 105 void test(m, t) 106 int m; 107 int t; 108 { 109 timer = t; 110 111 if (m & 0001) test_which(); 112 if (m & 0002) test_getset(); 113 if (m & 0004) test_neglarge(); 114 if (m & 0010) test_zero(); 115 if (m & 0020) test_timer(); 116 if (m & 0040) test_alarm(); 117 if (m & 0100) test_fork(); 118 if (m & 0200) test_exec(); 119 } 120 121 /* test invalid and unsupported 'which' values */ 122 void test_which() 123 { 124 struct itimerval it; 125 126 subtest = 0; 127 128 errno = 0; if (!getitimer(-1, &it) || errno != EINVAL) my_e(1); 129 errno = 0; if ( getitimer(timer, &it) ) my_e(2); 130 errno = 0; if (!getitimer( 3, &it) || errno != EINVAL) my_e(3); 131 } 132 133 /* test if we get back what we set */ 134 void test_getset() 135 { 136 struct itimerval it, oit; 137 138 subtest = 1; 139 140 /* no alarm should be set initially */ 141 if (getitimer(timer, &it)) my_e(1); 142 if (!EQITIMER(it, 0, 0, 0, 0)) my_e(2); 143 144 if (setitimer(timer, &it, &oit)) my_e(3); 145 if (setitimer(timer, &oit, NULL)) my_e(4); 146 if (!EQITIMER(oit, 0, 0, 0, 0)) my_e(5); 147 148 FILLITIMER(it, 123, 0, 456, 0); 149 if (setitimer(timer, &it, NULL)) my_e(6); 150 151 FILLITIMER(it, 987, 0, 654, 0); 152 if (setitimer(timer, &it, &oit)) my_e(7); 153 if (!LEITIMER(oit, 123, 0, 456, 0)) my_e(8); 154 155 if (getitimer(timer, &oit)) my_e(9); 156 if (!LEITIMER(oit, 987, 0, 654, 0)) my_e(10); 157 158 FILLITIMER(it, 0, 0, 0, 0); 159 if (setitimer(timer, &it, &oit)) my_e(11); 160 if (!LEITIMER(oit, 987, 0, 654, 0)) my_e(12); 161 162 if (getitimer(timer, &oit)) my_e(13); 163 if (!EQITIMER(oit, 0, 0, 0, 0)) my_e(14); 164 } 165 166 /* test negative/large values */ 167 void test_neglarge() 168 { 169 struct itimerval it; 170 171 subtest = 2; 172 173 FILLITIMER(it, 4, 0, 5, 0); 174 if (setitimer(timer, &it, NULL)) my_e(1); 175 176 FILLITIMER(it, 1000000000, 0, 0, 0); 177 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(2); 178 179 FILLITIMER(it, 0, 1000000, 0, 0); 180 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(3); 181 182 FILLITIMER(it, 0, 0, 0, 1000000); 183 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(4); 184 185 FILLITIMER(it, -1, 0, 0, 0); 186 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(5); 187 188 FILLITIMER(it, 0, -1, 0, 0); 189 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(6); 190 191 FILLITIMER(it, 0, 0, -1, 0); 192 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(7); 193 194 FILLITIMER(it, 0, 0, 0, -1); 195 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(8); 196 197 if (getitimer(timer, &it)) my_e(9); 198 if (!LEITIMER(it, 4, 0, 5, 0)) my_e(10); 199 } 200 201 /* setitimer with a zero timer has to set the interval to zero as well */ 202 void test_zero() 203 { 204 struct itimerval it; 205 206 subtest = 3; 207 208 it.it_value.tv_sec = 0; 209 it.it_value.tv_usec = 0; 210 it.it_interval.tv_sec = 1; 211 it.it_interval.tv_usec = 1; 212 213 if (setitimer(timer, &it, NULL)) my_e(1); 214 if (getitimer(timer, &it)) my_e(2); 215 if (!EQITIMER(it, 0, 0, 0, 0)) my_e(3); 216 } 217 218 /* test actual timer functioning */ 219 void test_timer() 220 { 221 struct itimerval it; 222 223 subtest = 4; 224 225 if (signal(sigs[timer], got_alarm) == SIG_ERR) my_e(1); 226 227 FILLITIMER(it, 0, 100000, 0, 100000); 228 229 if (setitimer(timer, &it, NULL)) my_e(2); 230 231 signals = 0; 232 busy_wait(1); 233 234 FILLITIMER(it, 0, 0, 0, 0); 235 if (setitimer(timer, &it, NULL)) my_e(3); 236 237 /* we don't know how many signals we'll actually get in practice, 238 * so these checks more or less cover the extremes of the acceptable */ 239 if (signals < 2) my_e(4); 240 if (signals > system_hz * 2) my_e(5); 241 242 /* only for REAL timer can we check against the clock */ 243 if (timer == ITIMER_REAL) { 244 FILLITIMER(it, 1, 0, 0, 0); 245 if (setitimer(timer, &it, NULL)) my_e(6); 246 247 signals = 0; 248 busy_wait(1); 249 250 FILLITIMER(it, 0, 0, 0, 0); 251 if (setitimer(timer, &it, NULL)) my_e(7); 252 253 if (signals != 1) my_e(8); 254 } 255 256 signals = 0; 257 busy_wait(1); 258 259 if (signals != 0) my_e(9); 260 } 261 262 /* test itimer/alarm interaction */ 263 void test_alarm(void) { 264 struct itimerval it; 265 266 /* only applicable for ITIMER_REAL */ 267 if (timer != ITIMER_REAL) return; 268 269 subtest = 5; 270 271 if (signal(SIGALRM, got_alarm) == SIG_ERR) my_e(1); 272 273 FILLITIMER(it, 3, 0, 1, 0); 274 if (setitimer(timer, &it, NULL)) my_e(2); 275 276 if (alarm(2) != 3) my_e(3); 277 278 if (getitimer(timer, &it)) my_e(4); 279 if (!LEITIMER(it, 2, 0, 0, 0)) my_e(5); 280 281 signals = 0; 282 busy_wait(5); 283 284 if (signals != 1) my_e(6); 285 286 if (getitimer(timer, &it)) my_e(7); 287 if (!EQITIMER(it, 0, 0, 0, 0)) my_e(8); 288 } 289 290 /* test that the timer is reset on forking */ 291 void test_fork(void) { 292 struct itimerval it, oit; 293 pid_t pid; 294 int status; 295 296 subtest = 6; 297 298 FILLITIMER(it, 12, 34, 56, 78); 299 300 if (setitimer(timer, &it, NULL)) my_e(1); 301 302 pid = fork(); 303 if (pid < 0) my_e(2); 304 305 if (pid == 0) { 306 if (getitimer(timer, &it)) exit(5); 307 if (!EQITIMER(it, 0, 0, 0, 0)) exit(6); 308 309 exit(0); 310 } 311 312 if (wait(&status) != pid) my_e(3); 313 if (!WIFEXITED(status)) my_e(4); 314 if (WEXITSTATUS(status) != 0) my_e(WEXITSTATUS(status)); 315 316 FILLITIMER(it, 0, 0, 0, 0); 317 if (setitimer(timer, &it, &oit)) my_e(7); 318 if (!LEITIMER(oit, 12, 34, 56, 78)) my_e(8); 319 } 320 321 /* test if timer is carried over to exec()'ed process */ 322 void test_exec(void) { 323 struct itimerval it; 324 pid_t pid; 325 int status; 326 char buf[2]; 327 328 subtest = 7; 329 330 pid = fork(); 331 if (pid < 0) my_e(1); 332 333 if (pid == 0) { 334 FILLITIMER(it, 3, 0, 1, 0); 335 if (setitimer(timer, &it, NULL)) exit(2); 336 337 sprintf(buf, "%d", timer); 338 execl(executable, "DO CHECK", buf, NULL); 339 340 exit(3); 341 } 342 343 if (wait(&status) != pid) my_e(4); 344 if (WIFSIGNALED(status)) { 345 /* process should have died from corresponding signal */ 346 if (WTERMSIG(status) != sigs[timer]) my_e(5); 347 } 348 else { 349 if (WIFEXITED(status)) my_e(WEXITSTATUS(status)); 350 else my_e(6); 351 } 352 } 353 354 /* procedure of the exec()'ed process */ 355 int do_check() 356 { 357 struct itimerval it; 358 359 if (getitimer(timer, &it)) return(81); 360 if (!LEITIMER(it, 3, 0, 1, 0)) return(82); 361 362 busy_wait(60); 363 364 return(83); 365 } 366 367 void busy_wait(secs) 368 int secs; 369 { 370 time_t now, exp; 371 int i; 372 373 exp = time(&now) + secs + 1; 374 375 while (now < exp) { 376 for (i = 0; i < 100000; i++); 377 378 time(&now); 379 } 380 } 381 382 void got_alarm(sig) 383 int sig; 384 { 385 if (sig != sigs[timer]) my_e(1001); 386 387 signals++; 388 } 389 390