|
9 | 9 | */
|
10 | 10 |
|
11 | 11 | #include "config.h"
|
12 |
| -#include "tst_test.h" |
13 |
| -#include "lapi/syscalls.h" |
14 | 12 | #include "tst_timer.h"
|
15 | 13 | #include "tst_safe_clocks.h"
|
| 14 | +#include "lapi/abisize.h" |
16 | 15 |
|
17 | 16 | #define DELTA_SEC 10
|
18 | 17 | #define NSEC_PER_SEC (1000000000L)
|
19 | 18 |
|
| 19 | +static void *bad_addr; |
| 20 | + |
20 | 21 | struct test_case {
|
21 | 22 | clockid_t type;
|
22 |
| - struct timespec newtime; |
23 | 23 | int exp_err;
|
24 | 24 | int replace;
|
| 25 | + long tv_sec; |
| 26 | + long tv_nsec; |
25 | 27 | };
|
26 | 28 |
|
27 | 29 | struct test_case tc[] = {
|
28 | 30 | { /* case 01: REALTIME: timespec NULL */
|
29 | 31 | .type = CLOCK_REALTIME,
|
30 | 32 | .exp_err = EFAULT,
|
31 | 33 | .replace = 1,
|
| 34 | + .tv_sec = 0, |
| 35 | + .tv_nsec = 0, |
32 | 36 | },
|
33 | 37 | { /* case 02: REALTIME: tv_sec = -1 */
|
34 | 38 | .type = CLOCK_REALTIME,
|
35 |
| - .newtime.tv_sec = -1, |
36 | 39 | .exp_err = EINVAL,
|
37 | 40 | .replace = 1,
|
| 41 | + .tv_sec = -1, |
| 42 | + .tv_nsec = 0, |
38 | 43 | },
|
39 | 44 | { /* case 03: REALTIME: tv_nsec = -1 */
|
40 | 45 | .type = CLOCK_REALTIME,
|
41 |
| - .newtime.tv_nsec = -1, |
42 | 46 | .exp_err = EINVAL,
|
43 | 47 | .replace = 1,
|
| 48 | + .tv_sec = 0, |
| 49 | + .tv_nsec = -1, |
44 | 50 | },
|
45 | 51 | { /* case 04: REALTIME: tv_nsec = 1s+1 */
|
46 | 52 | .type = CLOCK_REALTIME,
|
47 |
| - .newtime.tv_nsec = NSEC_PER_SEC + 1, |
48 | 53 | .exp_err = EINVAL,
|
49 | 54 | .replace = 1,
|
| 55 | + .tv_sec = 0, |
| 56 | + .tv_nsec = NSEC_PER_SEC + 1, |
50 | 57 | },
|
51 | 58 | { /* case 05: MONOTONIC */
|
52 | 59 | .type = CLOCK_MONOTONIC,
|
@@ -83,64 +90,87 @@ struct test_case tc[] = {
|
83 | 90 | },
|
84 | 91 | };
|
85 | 92 |
|
86 |
| -/* |
87 |
| - * Some tests may cause libc to segfault when passing bad arguments. |
88 |
| - */ |
89 |
| -static int sys_clock_settime(clockid_t clk_id, struct timespec *tp) |
| 93 | +static struct tst_ts spec; |
| 94 | + |
| 95 | +static struct test_variants { |
| 96 | + int (*gettime)(clockid_t clk_id, void *ts); |
| 97 | + int (*settime)(clockid_t clk_id, void *ts); |
| 98 | + enum tst_ts_type type; |
| 99 | + char *desc; |
| 100 | +} variants[] = { |
| 101 | +#if defined(TST_ABI32) |
| 102 | + { .gettime = sys_clock_gettime, .settime = sys_clock_settime, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"}, |
| 103 | + { .gettime = sys_clock_gettime, .settime = sys_clock_settime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"}, |
| 104 | +#endif |
| 105 | + |
| 106 | +#if defined(TST_ABI64) |
| 107 | + { .gettime = sys_clock_gettime, .settime = sys_clock_settime, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"}, |
| 108 | +#endif |
| 109 | + |
| 110 | +#if (__NR_clock_settime64 != __LTP__NR_INVALID_SYSCALL) |
| 111 | + { .gettime = sys_clock_gettime64, .settime = sys_clock_settime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"}, |
| 112 | +#endif |
| 113 | +}; |
| 114 | + |
| 115 | +static void setup(void) |
90 | 116 | {
|
91 |
| - return tst_syscall(__NR_clock_settime, clk_id, tp); |
| 117 | + tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc); |
| 118 | + |
| 119 | + bad_addr = tst_get_bad_addr(NULL); |
92 | 120 | }
|
93 | 121 |
|
94 | 122 | static void verify_clock_settime(unsigned int i)
|
95 | 123 | {
|
96 |
| - struct timespec spec, *specptr; |
| 124 | + struct test_variants *tv = &variants[tst_variant]; |
| 125 | + void *ts; |
97 | 126 |
|
98 |
| - specptr = &spec; |
| 127 | + spec.type = tv->type; |
99 | 128 |
|
100 | 129 | if (tc[i].replace == 0) {
|
101 |
| - |
102 |
| - SAFE_CLOCK_GETTIME(CLOCK_REALTIME, specptr); |
| 130 | + TEST(tv->gettime(CLOCK_REALTIME, tst_ts_get(&spec))); |
| 131 | + if (TST_RET == -1) { |
| 132 | + tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s", |
| 133 | + tst_clock_name(CLOCK_REALTIME)); |
| 134 | + return; |
| 135 | + } |
103 | 136 |
|
104 | 137 | /* add 1 sec to wall clock */
|
105 |
| - specptr->tv_sec += 1; |
106 |
| - |
| 138 | + spec = tst_ts_add_us(spec, 1000000); |
107 | 139 | } else {
|
108 |
| - |
109 | 140 | /* use given time spec */
|
110 |
| - *specptr = tc[i].newtime; |
| 141 | + tst_ts_set_sec(&spec, tc[i].tv_sec); |
| 142 | + tst_ts_set_nsec(&spec, tc[i].tv_nsec); |
111 | 143 | }
|
112 | 144 |
|
113 | 145 | /* bad pointer case */
|
114 | 146 | if (tc[i].exp_err == EFAULT)
|
115 |
| - specptr = tst_get_bad_addr(NULL); |
116 |
| - |
117 |
| - TEST(sys_clock_settime(tc[i].type, specptr)); |
118 |
| - |
119 |
| - if (TST_RET == -1) { |
| 147 | + ts = bad_addr; |
| 148 | + else |
| 149 | + ts = tst_ts_get(&spec); |
120 | 150 |
|
121 |
| - if (tc[i].exp_err == TST_ERR) { |
122 |
| - tst_res(TPASS | TTERRNO, |
123 |
| - "clock_settime(%s): failed as expected", |
124 |
| - tst_clock_name(tc[i].type)); |
125 |
| - return; |
126 |
| - } |
| 151 | + TEST(tv->settime(tc[i].type, ts)); |
127 | 152 |
|
128 |
| - tst_res(TFAIL | TTERRNO, "clock_settime(2): clock %s " |
129 |
| - "expected to fail with %s", |
| 153 | + if (TST_RET != -1) { |
| 154 | + tst_res(TFAIL | TTERRNO, "clock_settime(2): clock %s passed unexpectedly, expected %s", |
130 | 155 | tst_clock_name(tc[i].type),
|
131 | 156 | tst_strerrno(tc[i].exp_err));
|
| 157 | + return; |
| 158 | + } |
132 | 159 |
|
| 160 | + if (tc[i].exp_err == TST_ERR) { |
| 161 | + tst_res(TPASS | TTERRNO, "clock_settime(%s): failed as expected", |
| 162 | + tst_clock_name(tc[i].type)); |
133 | 163 | return;
|
134 | 164 | }
|
135 | 165 |
|
136 |
| - tst_res(TFAIL | TTERRNO, "clock_settime(2): clock %s passed " |
137 |
| - "unexpectedly, expected %s", |
138 |
| - tst_clock_name(tc[i].type), |
139 |
| - tst_strerrno(tc[i].exp_err)); |
| 166 | + tst_res(TFAIL | TTERRNO, "clock_settime(2): clock %s " "expected to fail with %s", |
| 167 | + tst_clock_name(tc[i].type), tst_strerrno(tc[i].exp_err)); |
140 | 168 | }
|
141 | 169 |
|
142 | 170 | static struct tst_test test = {
|
143 | 171 | .test = verify_clock_settime,
|
| 172 | + .test_variants = ARRAY_SIZE(variants), |
| 173 | + .setup = setup, |
144 | 174 | .tcnt = ARRAY_SIZE(tc),
|
145 | 175 | .needs_root = 1,
|
146 | 176 | .restore_wallclock = 1,
|
|
0 commit comments