DF-2913 / cpulimit_fg.c
/* * DF-2913 — standalone instrumented child. Runs in the foreground. * soft=2s, hard=RLIM_INFINITY (the default hard limit). */ #include <sys/resource.h> #include <sys/time.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> static volatile sig_atomic_t got_xcpu; static volatile sig_atomic_t got_kill_probe; static void xcpu_handler(int sig) { got_xcpu = 1; write(2, "SIGNAL: SIGXCPU received\n", 25); } static double now(void) { struct timeval tv; gettimeofday(&tv, NULL); return (tv.tv_sec + tv.tv_usec / 1e6); } int main(void) { struct rlimit rl, verify; struct sigaction sa; double t0 = now(); unsigned long n = 0; memset(&sa, 0, sizeof(sa)); sa.sa_handler = xcpu_handler; sigemptyset(&sa.sa_mask); sigaction(SIGXCPU, &sa, NULL); rl.rlim_cur = 2; rl.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_CPU, &rl) < 0) { perror("setrlimit"); exit(9); } memset(&verify, 0, sizeof(verify)); getrlimit(RLIMIT_CPU, &verify); fprintf(stderr, "limits: cur=%lld max=%lld (0x%016llx)\n", (long long)verify.rlim_cur, (long long)verify.rlim_max, (unsigned long long)verify.rlim_max); for (;;) { if ((++n & 0xFFFFFFF) == 0) { fprintf(stderr, "beat +%.1fs xcpu=%d\n", now() - t0, (int)got_xcpu); if (got_xcpu && now() - t0 > 7.0) { fprintf(stderr, "SURVIVED 5s past soft limit\n"); exit(0); } } } } |