1 /* Test 69. clock_getres(), clock_gettime(), clock_settime(), adjtime(). 2 * 3 * Note, any type of ntpd or software that calls adjtime() or settimeofday() 4 * should be disabled while running this test. This test takes ~40s to run. 5 */ 6 7 #include <time.h> 8 #include <sys/types.h> 9 #include <errno.h> 10 #include <fcntl.h> 11 #include <stdlib.h> 12 #include <unistd.h> 13 #include <stdio.h> 14 15 #define TRIALS 100 16 int max_error = 4; 17 #include "common.h" 18 19 #ifndef DEBUG 20 #define DEBUG 0 21 #endif 22 23 int subtest = 1; 24 25 26 int main(void); 27 void quit(void); 28 static void test_clock_getres(void); 29 static void test_clock_gettime(void); 30 static void test_clock_settime(void); 31 static void test_adjtime(void); 32 static void show_timespec(char *msg, struct timespec *ts); 33 34 static void test_clock_getres(void) 35 { 36 struct timespec res; 37 38 /* valid clock_id should succeed, invalid clock_id should fail */ 39 if (clock_getres(CLOCK_REALTIME, &res) == -1) e(10); 40 if (res.tv_sec < 0 || res.tv_nsec < 0) e(11); 41 show_timespec("res(CLOCK_REALTIME)", &res); 42 43 if (clock_getres(CLOCK_MONOTONIC, &res) == -1) e(12); 44 if (res.tv_sec < 0 || res.tv_nsec < 0) e(13); 45 show_timespec("res(CLOCK_MONOTONIC)", &res); 46 47 if (clock_getres(-1, &res) == 0) e(14); 48 } 49 50 static void test_clock_gettime(void) 51 { 52 struct timespec ts, ts2; 53 54 /* valid clock_id should succeed, invalid clock_id should fail */ 55 if (clock_gettime(CLOCK_REALTIME, &ts) == -1) e(21); 56 if (ts.tv_sec < 0 || ts.tv_nsec < 0) e(22); 57 show_timespec("time(CLOCK_REALTIME)", &ts); 58 sleep(2); 59 if (clock_gettime(CLOCK_REALTIME, &ts2) == -1) e(23); 60 if (ts2.tv_sec < 0 || ts2.tv_nsec < 0) e(24); 61 if (ts2.tv_sec <= ts.tv_sec) e(25); 62 63 if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) e(26); 64 if (ts.tv_sec < 0 || ts.tv_nsec < 0) e(27); 65 show_timespec("time(CLOCK_MONOTONIC)", &ts); 66 sleep(2); 67 if (clock_gettime(CLOCK_MONOTONIC, &ts2) == -1) e(28); 68 if (ts2.tv_sec < 0 || ts2.tv_nsec < 0) e(29); 69 if (ts2.tv_sec <= ts.tv_sec) e(30); 70 71 if (clock_gettime(-1, &ts) == 0) e(31); 72 } 73 74 static void test_clock_settime(void) 75 { 76 struct timespec ts; 77 struct timespec ts2; 78 79 /* shouldn't be able to set MONOTONIC */ 80 if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) e(50); 81 if (clock_settime(CLOCK_MONOTONIC, &ts) == 0) e(51); 82 if (errno != EINVAL) e(52); /* reponse should be EINVAL */ 83 84 /* set the time of REALTIME to that of MONOTONIC */ 85 if (clock_settime(CLOCK_REALTIME, &ts) == -1) e(53); 86 87 ts.tv_sec += 600; /* time travel 10 minutes into the future */ 88 if (clock_gettime(CLOCK_REALTIME, &ts2) == -1) e(54); 89 if (clock_settime(CLOCK_REALTIME, &ts) == -1) e(55); 90 if (clock_gettime(CLOCK_REALTIME, &ts) == -1) e(56); 91 92 /* get the value we set, if it's not about 10 minutes ahead, it failed */ 93 if (ts.tv_sec - ts2.tv_sec < 500 || 94 ts.tv_sec - ts2.tv_sec > 700) e(57); 95 96 /* back to current time - don't leave the system time 10 ahead */ 97 if (clock_gettime(CLOCK_REALTIME, &ts) == -1) e(58); 98 ts.tv_sec -= 600; 99 if (clock_settime(CLOCK_REALTIME, &ts) == -1) e(59); 100 101 /* Test with an invalid clock */ 102 if (clock_settime(-1, &ts) == 0) e(60); 103 } 104 105 static void test_adjtime(void) 106 { 107 struct timeval delta, olddelta; 108 struct timespec rt, mt; 109 110 /* set the realtime clock to the same value as the monotonic clock */ 111 if (clock_gettime(CLOCK_MONOTONIC, &mt) == -1) e(65); 112 if (clock_settime(CLOCK_REALTIME, &mt) == -1) e(66); 113 114 delta.tv_sec = 7; 115 delta.tv_usec = 0; 116 117 if (adjtime(&delta, &olddelta) != 0) e(70); /* adjust +7 seconds */ 118 sleep(15); /* should take 14 seconds to adjust the clock */ 119 120 /* check that the 7 second adjustment puts us between 5 and 10 seconds 121 * ahead of the monotonic clock. 122 */ 123 if (clock_gettime(CLOCK_MONOTONIC, &mt) == -1) e(71); 124 if (clock_gettime(CLOCK_REALTIME, &rt) == -1) e(72); 125 show_timespec("Monotonic", &mt); 126 show_timespec("Realtime (+7)", &rt); 127 if (rt.tv_sec - 5 < mt.tv_sec || rt.tv_sec - 10 > mt.tv_sec) e(73); 128 129 delta.tv_sec = -7; 130 if (adjtime(&delta, &olddelta) != 0) e(73); /* adjust -7 seconds */ 131 sleep(15); /* should take 14 seconds to adjust the clock */ 132 133 /* check that the 7 second adjustment puts us close to even with 134 * the monotonic clock. 135 */ 136 if (clock_gettime(CLOCK_MONOTONIC, &mt) == -1) e(74); 137 if (clock_gettime(CLOCK_REALTIME, &rt) == -1) e(75); 138 show_timespec("Monotonic", &mt); 139 show_timespec("Realtime (-7)", &rt); 140 if (abs(rt.tv_sec - mt.tv_sec) > 5) e(76); 141 142 } 143 144 static void show_timespec(char *msg, struct timespec *ts) 145 { 146 #if DEBUG == 1 147 printf("[%s] tv_sec=%d tv_nsec=%ld\n", msg, ts->tv_sec, ts->tv_nsec); 148 #endif /* DEBUG == 1 */ 149 } 150 151 int main(void) 152 { 153 start(69); 154 struct timespec starttime, endtime; 155 156 /* get test start time */ 157 if (clock_gettime(CLOCK_MONOTONIC, &starttime) == -1) e(1); 158 159 test_clock_getres(); 160 test_clock_gettime(); 161 test_clock_settime(); 162 test_adjtime(); 163 164 /* get test end time */ 165 if (clock_gettime(CLOCK_MONOTONIC, &endtime) == -1) e(2); 166 167 /* we shouldn't have gone backwards in time during this test */ 168 if ((starttime.tv_sec > endtime.tv_sec) || 169 (starttime.tv_sec == endtime.tv_sec && 170 starttime.tv_nsec > endtime.tv_nsec)) e(3); 171 172 quit(); 173 return(-1); /* impossible */ 174 } 175 176