|
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