⬢ DragonFlyBSD Kernel Audit
DF-2913 / cpulimit_fg.c
← back to finding ↓ download raw
/*
 * 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);
			}
		}
	}
}