2 * by: John Stultz <john.stultz@linaro.org>
3 * (C) Copyright Linaro 2015
4 * Licensed under the GPLv2
6 * This test validates adjtimex interface with valid
7 * and invalid test data.
9 * Usage: valid-adjtimex
12 * $ gcc valid-adjtimex.c -o valid-adjtimex -lrt
14 * This program is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
31 #include <sys/timex.h>
36 #include "../kselftest.h"
38 static inline int ksft_exit_pass(void)
42 static inline int ksft_exit_fail(void)
48 #define NSEC_PER_SEC 1000000000LL
49 #define USEC_PER_SEC 1000000LL
51 #define ADJ_SETOFFSET 0x0100
53 #include <sys/syscall.h>
54 static int clock_adjtime(clockid_t id
, struct timex
*tx
)
56 return syscall(__NR_clock_adjtime
, id
, tx
);
60 /* clear NTP time_status & time_state */
61 int clear_time_state(void)
66 tx
.modes
= ADJ_STATUS
;
72 #define NUM_FREQ_VALID 32
73 #define NUM_FREQ_OUTOFRANGE 4
74 #define NUM_FREQ_INVALID 2
76 long valid_freq
[NUM_FREQ_VALID
] = {
110 long outofrange_freq
[NUM_FREQ_OUTOFRANGE
] = {
117 #define LONG_MAX (~0UL>>1)
118 #define LONG_MIN (-LONG_MAX - 1)
120 long invalid_freq
[NUM_FREQ_INVALID
] = {
125 int validate_freq(void)
133 memset(&tx
, 0, sizeof(struct timex
));
134 /* Set the leap second insert flag */
136 printf("Testing ADJ_FREQ... ");
137 for (i
= 0; i
< NUM_FREQ_VALID
; i
++) {
138 tx
.modes
= ADJ_FREQUENCY
;
139 tx
.freq
= valid_freq
[i
];
144 printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
145 valid_freq
[i
], valid_freq
[i
]>>16);
151 if (tx
.freq
!= valid_freq
[i
]) {
152 printf("Warning: freq value %ld not what we set it (%ld)!\n",
153 tx
.freq
, valid_freq
[i
]);
156 for (i
= 0; i
< NUM_FREQ_OUTOFRANGE
; i
++) {
157 tx
.modes
= ADJ_FREQUENCY
;
158 tx
.freq
= outofrange_freq
[i
];
163 printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
164 outofrange_freq
[i
], outofrange_freq
[i
]>>16);
170 if (tx
.freq
== outofrange_freq
[i
]) {
172 printf("ERROR: out of range value %ld actually set!\n",
180 if (sizeof(long) == 8) { /* this case only applies to 64bit systems */
181 for (i
= 0; i
< NUM_FREQ_INVALID
; i
++) {
182 tx
.modes
= ADJ_FREQUENCY
;
183 tx
.freq
= invalid_freq
[i
];
187 printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n",
197 /* reset freq to zero */
198 tx
.modes
= ADJ_FREQUENCY
;
206 int set_offset(long long offset
, int use_nano
)
208 struct timex tmx
= {};
211 tmx
.modes
= ADJ_SETOFFSET
;
213 tmx
.modes
|= ADJ_NANO
;
215 tmx
.time
.tv_sec
= offset
/ NSEC_PER_SEC
;
216 tmx
.time
.tv_usec
= offset
% NSEC_PER_SEC
;
218 if (offset
< 0 && tmx
.time
.tv_usec
) {
219 tmx
.time
.tv_sec
-= 1;
220 tmx
.time
.tv_usec
+= NSEC_PER_SEC
;
223 tmx
.time
.tv_sec
= offset
/ USEC_PER_SEC
;
224 tmx
.time
.tv_usec
= offset
% USEC_PER_SEC
;
226 if (offset
< 0 && tmx
.time
.tv_usec
) {
227 tmx
.time
.tv_sec
-= 1;
228 tmx
.time
.tv_usec
+= USEC_PER_SEC
;
232 ret
= clock_adjtime(CLOCK_REALTIME
, &tmx
);
234 printf("(sec: %ld usec: %ld) ", tmx
.time
.tv_sec
, tmx
.time
.tv_usec
);
241 int set_bad_offset(long sec
, long usec
, int use_nano
)
243 struct timex tmx
= {};
246 tmx
.modes
= ADJ_SETOFFSET
;
248 tmx
.modes
|= ADJ_NANO
;
250 tmx
.time
.tv_sec
= sec
;
251 tmx
.time
.tv_usec
= usec
;
252 ret
= clock_adjtime(CLOCK_REALTIME
, &tmx
);
254 printf("Invalid (sec: %ld usec: %ld) did not fail! ", tmx
.time
.tv_sec
, tmx
.time
.tv_usec
);
261 int validate_set_offset(void)
263 printf("Testing ADJ_SETOFFSET... ");
265 /* Test valid values */
266 if (set_offset(NSEC_PER_SEC
- 1, 1))
269 if (set_offset(-NSEC_PER_SEC
+ 1, 1))
272 if (set_offset(-NSEC_PER_SEC
- 1, 1))
275 if (set_offset(5 * NSEC_PER_SEC
, 1))
278 if (set_offset(-5 * NSEC_PER_SEC
, 1))
281 if (set_offset(5 * NSEC_PER_SEC
+ NSEC_PER_SEC
/ 2, 1))
284 if (set_offset(-5 * NSEC_PER_SEC
- NSEC_PER_SEC
/ 2, 1))
287 if (set_offset(USEC_PER_SEC
- 1, 0))
290 if (set_offset(-USEC_PER_SEC
+ 1, 0))
293 if (set_offset(-USEC_PER_SEC
- 1, 0))
296 if (set_offset(5 * USEC_PER_SEC
, 0))
299 if (set_offset(-5 * USEC_PER_SEC
, 0))
302 if (set_offset(5 * USEC_PER_SEC
+ USEC_PER_SEC
/ 2, 0))
305 if (set_offset(-5 * USEC_PER_SEC
- USEC_PER_SEC
/ 2, 0))
308 /* Test invalid values */
309 if (set_bad_offset(0, -1, 1))
311 if (set_bad_offset(0, -1, 0))
313 if (set_bad_offset(0, 2 * NSEC_PER_SEC
, 1))
315 if (set_bad_offset(0, 2 * USEC_PER_SEC
, 0))
317 if (set_bad_offset(0, NSEC_PER_SEC
, 1))
319 if (set_bad_offset(0, USEC_PER_SEC
, 0))
321 if (set_bad_offset(0, -NSEC_PER_SEC
, 1))
323 if (set_bad_offset(0, -USEC_PER_SEC
, 0))
330 int main(int argc
, char **argv
)
333 return ksft_exit_fail();
335 if (validate_set_offset())
336 return ksft_exit_fail();
338 return ksft_exit_pass();