1 /*
2 * This file is part of ioctl_evdev strace test.
3 *
4 * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
5 * Copyright (c) 2016-2018 The strace developers.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "tests.h"
32
33 #ifdef HAVE_LINUX_INPUT_H
34
35 # include <errno.h>
36 # include <inttypes.h>
37 # include <stdio.h>
38 # include <string.h>
39 # include <sys/ioctl.h>
40 # include <linux/input.h>
41
42 # ifndef EV_SW
43 # define EV_SW 5
44 # endif
45 # ifndef ABS_MT_TOOL_Y
46 # define ABS_MT_TOOL_Y 0x3d
47 # endif
48
49 static const unsigned int magic = 0xdeadbeef;
50 static const unsigned long lmagic = (unsigned long) 0xdeadbeefbadc0dedULL;
51
52 # if VERBOSE
53 static void
print_envelope(const struct ff_envelope * const e)54 print_envelope(const struct ff_envelope *const e)
55 {
56 printf(", envelope={attack_length=%hu, attack_level=%hu"
57 ", fade_length=%hu, fade_level=%#hx}",
58 e->attack_length, e->attack_level,
59 e->fade_length, e->fade_level);
60 }
61 # endif /* VERBOSE */
62
63 static void
print_ffe_common(const struct ff_effect * const ffe,const char * const type_str)64 print_ffe_common(const struct ff_effect *const ffe, const char *const type_str)
65 {
66 printf("ioctl(-1, EVIOCSFF, {type=%s, id=%" PRIu16
67 ", direction=%" PRIu16 ", ",
68 type_str, ffe->id, ffe->direction);
69 # if VERBOSE
70 printf("trigger={button=%hu, interval=%hu}"
71 ", replay={length=%hu, delay=%hu}",
72 ffe->trigger.button, ffe->trigger.interval,
73 ffe->replay.length, ffe->replay.delay);
74 # endif /* VERBOSE */
75 }
76
77 # define TEST_NULL_ARG_EX(cmd, str) \
78 do { \
79 ioctl(-1, cmd, 0); \
80 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", str); \
81 } while (0)
82
83 # define TEST_NULL_ARG(cmd) TEST_NULL_ARG_EX(cmd, #cmd)
84
85 int
main(void)86 main(void)
87 {
88 TEST_NULL_ARG(EVIOCGVERSION);
89 TEST_NULL_ARG(EVIOCGEFFECTS);
90 TEST_NULL_ARG(EVIOCGID);
91 TEST_NULL_ARG(EVIOCGKEYCODE);
92 TEST_NULL_ARG(EVIOCSKEYCODE);
93 TEST_NULL_ARG(EVIOCSFF);
94 # ifdef EVIOCGKEYCODE_V2
95 TEST_NULL_ARG(EVIOCGKEYCODE_V2);
96 # endif
97 # ifdef EVIOCSKEYCODE_V2
98 TEST_NULL_ARG(EVIOCSKEYCODE_V2);
99 # endif
100 # ifdef EVIOCGREP
101 TEST_NULL_ARG(EVIOCGREP);
102 # endif
103 # ifdef EVIOCSREP
104 TEST_NULL_ARG(EVIOCSREP);
105 # endif
106 # ifdef EVIOCSCLOCKID
107 TEST_NULL_ARG(EVIOCSCLOCKID);
108 # endif
109
110 TEST_NULL_ARG(EVIOCGNAME(0));
111 TEST_NULL_ARG(EVIOCGPHYS(0));
112 TEST_NULL_ARG(EVIOCGUNIQ(0));
113 TEST_NULL_ARG(EVIOCGKEY(0));
114 TEST_NULL_ARG(EVIOCGLED(0));
115 # ifdef EVIOCGMTSLOTS
116 TEST_NULL_ARG(EVIOCGMTSLOTS(0));
117 TEST_NULL_ARG(EVIOCGMTSLOTS(8));
118 # endif
119 # ifdef EVIOCGPROP
120 TEST_NULL_ARG(EVIOCGPROP(0));
121 # endif
122 TEST_NULL_ARG(EVIOCGSND(0));
123 # ifdef EVIOCGSW
124 TEST_NULL_ARG(EVIOCGSW(0));
125 # endif
126
127 TEST_NULL_ARG(EVIOCGABS(ABS_X));
128 TEST_NULL_ARG(EVIOCSABS(ABS_X));
129
130 TEST_NULL_ARG_EX(EVIOCGABS(0xe), "EVIOCGABS(0xe /* ABS_??? */)");
131 TEST_NULL_ARG_EX(EVIOCSABS(0xe), "EVIOCSABS(0xe /* ABS_??? */)");
132
133 TEST_NULL_ARG(EVIOCGABS(ABS_MT_TOOL_Y));
134 TEST_NULL_ARG(EVIOCSABS(ABS_MT_TOOL_Y));
135
136 TEST_NULL_ARG_EX(EVIOCGABS(0x3e), "EVIOCGABS(0x3e /* ABS_??? */)");
137 TEST_NULL_ARG_EX(EVIOCSABS(0x3e), "EVIOCSABS(0x3e /* ABS_??? */)");
138
139 TEST_NULL_ARG_EX(EVIOCGABS(0x3f), "EVIOCGABS(0x3f /* ABS_??? */)");
140 TEST_NULL_ARG_EX(EVIOCSABS(0x3f), "EVIOCSABS(0x3f /* ABS_??? */)");
141
142 TEST_NULL_ARG(EVIOCGBIT(0, 0));
143 TEST_NULL_ARG(EVIOCGBIT(EV_KEY, 1));
144 TEST_NULL_ARG(EVIOCGBIT(EV_REL, 2));
145 TEST_NULL_ARG(EVIOCGBIT(EV_ABS, 3));
146 TEST_NULL_ARG(EVIOCGBIT(EV_MSC, 4));
147 TEST_NULL_ARG(EVIOCGBIT(EV_SW, 5));
148 TEST_NULL_ARG(EVIOCGBIT(EV_LED, 6));
149 TEST_NULL_ARG(EVIOCGBIT(EV_SND, 7));
150 TEST_NULL_ARG(EVIOCGBIT(EV_REP, 8));
151 TEST_NULL_ARG(EVIOCGBIT(EV_FF, 9));
152 TEST_NULL_ARG(EVIOCGBIT(EV_PWR, 10));
153 TEST_NULL_ARG(EVIOCGBIT(EV_FF_STATUS, 11));
154
155 TEST_NULL_ARG_EX(EVIOCGBIT(0x6, 12), "EVIOCGBIT(0x6 /* EV_??? */, 12)");
156 TEST_NULL_ARG_EX(EVIOCGBIT(0x18, 13),
157 "EVIOCGBIT(0x18 /* EV_??? */, 13)");
158 TEST_NULL_ARG_EX(EVIOCGBIT(0x1f, 14),
159 "EVIOCGBIT(0x1f /* EV_??? */, 14)");
160
161 ioctl(-1, EVIOCGBIT(EV_MAX, 42), 0);
162 printf("ioctl(-1, EVIOCGBIT(%#x /* EV_??? */, 42), NULL)"
163 " = -1 EBADF (%m)\n", EV_MAX);
164
165 ioctl(-1, EVIOCRMFF, lmagic);
166 printf("ioctl(-1, EVIOCRMFF, %d) = -1 EBADF (%m)\n", (int) lmagic);
167
168 ioctl(-1, EVIOCGRAB, lmagic);
169 printf("ioctl(-1, EVIOCGRAB, %lu) = -1 EBADF (%m)\n", lmagic);
170
171 # ifdef EVIOCREVOKE
172 ioctl(-1, EVIOCREVOKE, lmagic);
173 printf("ioctl(-1, EVIOCREVOKE, %lu) = -1 EBADF (%m)\n", lmagic);
174 # endif
175
176 const unsigned int size = get_page_size();
177 void *const page = tail_alloc(size);
178 fill_memory(page, size);
179
180 TAIL_ALLOC_OBJECT_CONST_PTR(int, val_int);
181 *val_int = magic;
182
183 # ifdef EVIOCSCLOCKID
184 ioctl(-1, EVIOCSCLOCKID, val_int);
185 printf("ioctl(-1, EVIOCSCLOCKID, [%u]) = -1 EBADF (%m)\n", *val_int);
186 # endif
187
188 int *pair_int = tail_alloc(sizeof(*pair_int) * 2);
189 pair_int[0] = 0xdeadbeef;
190 pair_int[1] = 0xbadc0ded;
191
192 # ifdef EVIOSGREP
193 ioctl(-1, EVIOCSREP, pair_int);
194 printf("ioctl(-1, EVIOCSREP, [%u, %u]) = -1 EBADF (%m)\n",
195 pair_int[0], pair_int[1]);
196 # endif
197
198 pair_int[1] = 1;
199 ioctl(-1, EVIOCSKEYCODE, pair_int);
200 printf("ioctl(-1, EVIOCSKEYCODE, [%u, %s]) = -1 EBADF (%m)\n",
201 pair_int[0], "KEY_ESC");
202
203 # ifdef EVIOCSKEYCODE_V2
204 TAIL_ALLOC_OBJECT_CONST_PTR(struct input_keymap_entry, ike);
205 fill_memory(ike, sizeof(*ike));
206 ike->keycode = 2;
207
208 ioctl(-1, EVIOCSKEYCODE_V2, ike);
209 printf("ioctl(-1, EVIOCSKEYCODE_V2, {flags=%" PRIu8
210 ", len=%" PRIu8 ", ", ike->flags, ike->len);
211 # if VERBOSE
212 printf("index=%" PRIu16 ", keycode=%s, scancode=[",
213 ike->index, "KEY_1");
214 unsigned int i;
215 for (i = 0; i < ARRAY_SIZE(ike->scancode); ++i) {
216 if (i > 0)
217 printf(", ");
218 printf("%" PRIx8, ike->scancode[i]);
219 }
220 printf("]");
221 # else
222 printf("...");
223 # endif
224 errno = EBADF;
225 printf("}) = -1 EBADF (%m)\n");
226 # endif
227
228 TAIL_ALLOC_OBJECT_CONST_PTR(struct ff_effect, ffe);
229 fill_memory(ffe, sizeof(*ffe));
230
231 ffe->type = FF_CONSTANT;
232 ioctl(-1, EVIOCSFF, ffe);
233 print_ffe_common(ffe, "FF_CONSTANT");
234
235 # if VERBOSE
236 printf(", constant={level=%hd", ffe->u.constant.level);
237 print_envelope(&ffe->u.constant.envelope);
238 printf("}");
239 # else
240 printf("...");
241 # endif
242 errno = EBADF;
243 printf("}) = -1 EBADF (%m)\n");
244
245 # if VERBOSE
246 ffe->type = FF_RAMP;
247 ioctl(-1, EVIOCSFF, ffe);
248 print_ffe_common(ffe, "FF_RAMP");
249 printf(", ramp={start_level=%hd, end_level=%hd",
250 ffe->u.ramp.start_level, ffe->u.ramp.end_level);
251 print_envelope(&ffe->u.ramp.envelope);
252 errno = EBADF;
253 printf("}}) = -1 EBADF (%m)\n");
254
255 ffe->type = FF_PERIODIC;
256 ioctl(-1, EVIOCSFF, ffe);
257 print_ffe_common(ffe, "FF_PERIODIC");
258 printf(", periodic={waveform=%hu, period=%hu, magnitude=%hd"
259 ", offset=%hd, phase=%hu",
260 ffe->u.periodic.waveform, ffe->u.periodic.period,
261 ffe->u.periodic.magnitude, ffe->u.periodic.offset,
262 ffe->u.periodic.phase);
263 print_envelope(&ffe->u.periodic.envelope);
264 printf(", custom_len=%u, custom_data=%p}",
265 ffe->u.periodic.custom_len, ffe->u.periodic.custom_data);
266 errno = EBADF;
267 printf("}) = -1 EBADF (%m)\n");
268
269 ffe->type = FF_RUMBLE;
270 ioctl(-1, EVIOCSFF, ffe);
271 print_ffe_common(ffe, "FF_RUMBLE");
272 printf(", rumble={strong_magnitude=%hu, weak_magnitude=%hu}",
273 ffe->u.rumble.strong_magnitude, ffe->u.rumble.weak_magnitude);
274 errno = EBADF;
275 printf("}) = -1 EBADF (%m)\n");
276
277 ffe->type = 0xff;
278 ioctl(-1, EVIOCSFF, ffe);
279 print_ffe_common(ffe, "0xff /* FF_??? */");
280 errno = EBADF;
281 printf("}) = -1 EBADF (%m)\n");
282 # endif
283
284 ioctl(-1, _IOC(_IOC_READ, 0x45, 0x1, 0xff), lmagic);
285 printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n",
286 "_IOC(_IOC_READ, 0x45, 0x1, 0xff)", lmagic);
287
288 ioctl(-1, _IOC(_IOC_WRITE, 0x45, 0x1, 0xff), lmagic);
289 printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n",
290 "_IOC(_IOC_WRITE, 0x45, 0x1, 0xff)", lmagic);
291
292 ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, 0x45, 0xfe, 0xff), lmagic);
293 printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n",
294 "_IOC(_IOC_READ|_IOC_WRITE, 0x45, 0xfe, 0xff)", lmagic);
295
296 ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, 0x45, 0, 0), lmagic);
297 printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n",
298 "_IOC(_IOC_READ|_IOC_WRITE, 0x45, 0, 0)", lmagic);
299
300 puts("+++ exited with 0 +++");
301 return 0;
302 }
303 #else
304
305 SKIP_MAIN_UNDEFINED("HAVE_LINUX_INPUT_H")
306
307 #endif
308