stepback.c 1.52 KB
Newer Older
1 2 3 4 5 6 7
/* Checks for the RS/6000 AIX adjtime() bug, in which if a negative
 * offset is given, the system gets messed up and never completes the
 * adjustment.  If the problem is fixed, this program will print the
 * time, sit there for 10 seconds, and exit.  If the problem isn't fixed,
 * the program will print an occasional "result=nnnnnn" (the residual
 * slew from adjtime()).
 *
8 9 10
 * This version is in modern ANSI C rather than the archaic dialect of
 * the RS6000's day.
 *
11
 * Run this as root!
12 13 14
 *
 * Copyright 2015 by the NTPsec project contributors
 * SPDX-License-Identifier: BSD-2-Clause
15
 */
16 17
#include <stdlib.h>
#include <unistd.h>
18 19 20 21 22 23 24
#include <signal.h>
#include <sys/time.h>
#include <time.h>
#include <stdio.h>

struct timeval adjustment, result;

25 26 27 28 29 30 31 32 33 34 35 36
static void
timeout(int sig)
{
	if (adjtime(&adjustment, &result))
	    printf("adjtime call failed\n");
	if (result.tv_sec != 0 || result.tv_usec != 0) {
		printf("result = %d.%6d  ",
		       (int) result.tv_sec,
		       (int) result.tv_usec);
	}
}

37
void stepback(void)
38 39 40 41
{
	struct itimerval value, oldvalue;
	int i;
	time_t curtime;
42
	char ascbuf[BUFSIZ];
43
	struct sigaction sa;
44 45

	curtime = time(0);
46
	printf("Starting: %s", ctime_r(&curtime, ascbuf));
47 48 49 50
	value.it_interval.tv_sec = value.it_value.tv_sec = 1;
	value.it_interval.tv_usec = value.it_value.tv_usec = 0;
	adjustment.tv_sec = 0;
	adjustment.tv_usec = -2000;
51 52 53
	sa.sa_handler = timeout;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;
54 55 56 57 58 59
	signal(SIGALRM, timeout);
	setitimer(ITIMER_REAL, &value, &oldvalue);
	for (i=0; i<10; i++) {
		pause();
	}
}
60