| 583 | } |
| 584 | |
| 585 | static void |
| 586 | box_keeper(void) |
| 587 | { |
| 588 | read_errors_from_fd = error_pipes[0]; |
| 589 | close(error_pipes[1]); |
| 590 | close(status_pipes[1]); |
| 591 | |
| 592 | clock_gettime(CLOCK_MONOTONIC, &start_time); |
| 593 | ticks_per_sec = sysconf(_SC_CLK_TCK); |
| 594 | if (ticks_per_sec <= 0) |
| 595 | die("Invalid ticks_per_sec!"); |
| 596 | |
| 597 | if (timeout || wall_timeout) |
| 598 | { |
| 599 | struct sigaction sa; |
| 600 | bzero(&sa, sizeof(sa)); |
| 601 | sa.sa_handler = signal_alarm; |
| 602 | sigaction(SIGALRM, &sa, NULL); |
| 603 | struct itimerval timer = { |
| 604 | .it_interval = { .tv_usec = TIMER_INTERVAL_US }, |
| 605 | .it_value = { .tv_usec = TIMER_INTERVAL_US }, |
| 606 | }; |
| 607 | setitimer(ITIMER_REAL, &timer, NULL); |
| 608 | } |
| 609 | |
| 610 | for(;;) |
| 611 | { |
| 612 | struct rusage rus; |
| 613 | int stat; |
| 614 | pid_t p; |
| 615 | if (interrupt) |
| 616 | { |
| 617 | meta_printf("exitsig:%d\n", interrupt); |
| 618 | err("SG: Interrupted"); |
| 619 | } |
| 620 | if (timer_tick) |
| 621 | { |
| 622 | check_timeout(); |
| 623 | timer_tick = 0; |
| 624 | } |
| 625 | p = wait4(proxy_pid, &stat, 0, &rus); |
| 626 | if (p < 0) |
| 627 | { |
| 628 | if (errno == EINTR) |
| 629 | continue; |
| 630 | die("wait4: %m"); |
| 631 | } |
| 632 | if (p != proxy_pid) |
| 633 | die("wait4: unknown pid %d exited!", p); |
| 634 | proxy_pid = 0; |
| 635 | |
| 636 | // Check error pipe if there is an internal error passed from inside the box |
| 637 | char interr[1024]; |
| 638 | int n = read(read_errors_from_fd, interr, sizeof(interr) - 1); |
| 639 | if (n > 0) |
| 640 | { |
| 641 | interr[n] = 0; |
| 642 | die("%s", interr); |
no test coverage detected
searching dependent graphs…