--- /dev/null
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <signal.h>
+#include <time.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+
+#define MAXCREDIT 5
+#define MAXNTH 2
+
+static time_t now, last;
+static struct rlimit rlcpu;
+static struct sigaction saxcpu;
+
+static void gnow(void) { time(&now); }
+
+static void makepending(void) {
+ int r;
+ last= now;
+ r= sigaction(SIGXCPU, &saxcpu, 0); assert(!r);
+ r= setrlimit(RLIMIT_CPU, &rlcpu); assert(!r);
+}
+
+static void exceeded(void) {
+ const char m[]= "cpu limit exceeded\n";
+ write(2,m,sizeof(m)-1);
+ raise(SIGXCPU);
+}
+
+static void xcpuhandler(int ignored) {
+ int credit;
+ gnow();
+ credit= (now - last)/MAXNTH;
+ if (credit <= 0) exceeded();
+ if (credit > MAXCREDIT) credit= MAXCREDIT;
+ rlcpu.rlim_cur += credit;
+ makepending();
+}
+
+int main(void) {
+ int r;
+
+ memset(&saxcpu,0,sizeof(saxcpu));
+ saxcpu.sa_handler= xcpuhandler;
+ sigemptyset(&saxcpu.sa_mask);
+ saxcpu.sa_flags= SA_RESETHAND | SA_RESTART | SA_NODEFER;
+
+ r= getrlimit(RLIMIT_CPU, &rlcpu); assert(!r);
+
+ gnow();
+ rlcpu.rlim_cur= MAXCREDIT;
+ makepending();
+
+ for (;;);
+}