• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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