xref: /aosp_15_r20/external/strace/tests-m32/ioctl_evdev-success.c (revision cf84ac9a129d8ea9952db616b4e9b904c4bdde56)
1*cf84ac9aSAndroid Build Coastguard Worker #include "tests.h"
2*cf84ac9aSAndroid Build Coastguard Worker 
3*cf84ac9aSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_INPUT_H
4*cf84ac9aSAndroid Build Coastguard Worker 
5*cf84ac9aSAndroid Build Coastguard Worker # include <inttypes.h>
6*cf84ac9aSAndroid Build Coastguard Worker # include <stdio.h>
7*cf84ac9aSAndroid Build Coastguard Worker # include <stdlib.h>
8*cf84ac9aSAndroid Build Coastguard Worker # include <sys/ioctl.h>
9*cf84ac9aSAndroid Build Coastguard Worker # include <linux/input.h>
10*cf84ac9aSAndroid Build Coastguard Worker # include "print_fields.h"
11*cf84ac9aSAndroid Build Coastguard Worker 
12*cf84ac9aSAndroid Build Coastguard Worker static const char *errstr;
13*cf84ac9aSAndroid Build Coastguard Worker 
14*cf84ac9aSAndroid Build Coastguard Worker struct evdev_check {
15*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long cmd;
16*cf84ac9aSAndroid Build Coastguard Worker 	const char *cmd_str;
17*cf84ac9aSAndroid Build Coastguard Worker 	void *arg_ptr;
18*cf84ac9aSAndroid Build Coastguard Worker 	void (*print_arg)(long rc, void *ptr, void *arg);
19*cf84ac9aSAndroid Build Coastguard Worker };
20*cf84ac9aSAndroid Build Coastguard Worker 
21*cf84ac9aSAndroid Build Coastguard Worker static long
invoke_test_syscall(unsigned long cmd,void * p)22*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(unsigned long cmd, void *p)
23*cf84ac9aSAndroid Build Coastguard Worker {
24*cf84ac9aSAndroid Build Coastguard Worker 	long rc = ioctl(-1, cmd, p);
25*cf84ac9aSAndroid Build Coastguard Worker 	errstr = sprintrc(rc);
26*cf84ac9aSAndroid Build Coastguard Worker 	static char inj_errstr[4096];
27*cf84ac9aSAndroid Build Coastguard Worker 
28*cf84ac9aSAndroid Build Coastguard Worker 	snprintf(inj_errstr, sizeof(inj_errstr), "%s (INJECTED)", errstr);
29*cf84ac9aSAndroid Build Coastguard Worker 	errstr = inj_errstr;
30*cf84ac9aSAndroid Build Coastguard Worker 	return rc;
31*cf84ac9aSAndroid Build Coastguard Worker }
32*cf84ac9aSAndroid Build Coastguard Worker 
33*cf84ac9aSAndroid Build Coastguard Worker static void
test_evdev(struct evdev_check * check,void * arg)34*cf84ac9aSAndroid Build Coastguard Worker test_evdev(struct evdev_check *check, void *arg)
35*cf84ac9aSAndroid Build Coastguard Worker {
36*cf84ac9aSAndroid Build Coastguard Worker 	long rc = invoke_test_syscall(check->cmd, check->arg_ptr);
37*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(-1, %s, ", check->cmd_str);
38*cf84ac9aSAndroid Build Coastguard Worker 	if (check->print_arg)
39*cf84ac9aSAndroid Build Coastguard Worker 		check->print_arg(rc, check->arg_ptr, arg);
40*cf84ac9aSAndroid Build Coastguard Worker 	else
41*cf84ac9aSAndroid Build Coastguard Worker 		printf("%p", check->arg_ptr);
42*cf84ac9aSAndroid Build Coastguard Worker 	printf(") = %s\n", errstr);
43*cf84ac9aSAndroid Build Coastguard Worker }
44*cf84ac9aSAndroid Build Coastguard Worker 
45*cf84ac9aSAndroid Build Coastguard Worker static void
print_input_absinfo(long rc,void * ptr,void * arg)46*cf84ac9aSAndroid Build Coastguard Worker print_input_absinfo(long rc, void *ptr, void *arg)
47*cf84ac9aSAndroid Build Coastguard Worker {
48*cf84ac9aSAndroid Build Coastguard Worker 	struct input_absinfo *absinfo = ptr;
49*cf84ac9aSAndroid Build Coastguard Worker 
50*cf84ac9aSAndroid Build Coastguard Worker 	if (rc < 0) {
51*cf84ac9aSAndroid Build Coastguard Worker 		printf("%p", absinfo);
52*cf84ac9aSAndroid Build Coastguard Worker 		return;
53*cf84ac9aSAndroid Build Coastguard Worker 	}
54*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U("{", *absinfo, value);
55*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", *absinfo, minimum);
56*cf84ac9aSAndroid Build Coastguard Worker # if VERBOSE
57*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", *absinfo, maximum);
58*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", *absinfo, fuzz);
59*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", *absinfo, flat);
60*cf84ac9aSAndroid Build Coastguard Worker #  ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
61*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", *absinfo, resolution);
62*cf84ac9aSAndroid Build Coastguard Worker #  endif
63*cf84ac9aSAndroid Build Coastguard Worker # else
64*cf84ac9aSAndroid Build Coastguard Worker 	printf(", ...");
65*cf84ac9aSAndroid Build Coastguard Worker # endif
66*cf84ac9aSAndroid Build Coastguard Worker 	printf("}");
67*cf84ac9aSAndroid Build Coastguard Worker }
68*cf84ac9aSAndroid Build Coastguard Worker 
69*cf84ac9aSAndroid Build Coastguard Worker static void
print_input_id(long rc,void * ptr,void * arg)70*cf84ac9aSAndroid Build Coastguard Worker print_input_id(long rc, void *ptr, void *arg)
71*cf84ac9aSAndroid Build Coastguard Worker {
72*cf84ac9aSAndroid Build Coastguard Worker 	struct input_id *id = ptr;
73*cf84ac9aSAndroid Build Coastguard Worker 
74*cf84ac9aSAndroid Build Coastguard Worker 	if (rc < 0) {
75*cf84ac9aSAndroid Build Coastguard Worker 		printf("%p", id);
76*cf84ac9aSAndroid Build Coastguard Worker 		return;
77*cf84ac9aSAndroid Build Coastguard Worker 	}
78*cf84ac9aSAndroid Build Coastguard Worker 	printf("{ID_BUS=%" PRIu16
79*cf84ac9aSAndroid Build Coastguard Worker 	       ", ID_VENDOR=%" PRIu16
80*cf84ac9aSAndroid Build Coastguard Worker 	       ", ID_PRODUCT=%" PRIu16
81*cf84ac9aSAndroid Build Coastguard Worker 	       ", ID_VERSION=%" PRIu16 "}",
82*cf84ac9aSAndroid Build Coastguard Worker 	       id->bustype, id->vendor, id->product, id->version);
83*cf84ac9aSAndroid Build Coastguard Worker }
84*cf84ac9aSAndroid Build Coastguard Worker 
85*cf84ac9aSAndroid Build Coastguard Worker # ifdef EVIOCGMTSLOTS
86*cf84ac9aSAndroid Build Coastguard Worker static void
print_mtslots(long rc,void * ptr,void * arg)87*cf84ac9aSAndroid Build Coastguard Worker print_mtslots(long rc, void *ptr, void *arg)
88*cf84ac9aSAndroid Build Coastguard Worker {
89*cf84ac9aSAndroid Build Coastguard Worker 	int *buffer = ptr;
90*cf84ac9aSAndroid Build Coastguard Worker 	const char **str = arg;
91*cf84ac9aSAndroid Build Coastguard Worker 	int num = atoi(*(str + 1));
92*cf84ac9aSAndroid Build Coastguard Worker 
93*cf84ac9aSAndroid Build Coastguard Worker 	if (rc < 0) {
94*cf84ac9aSAndroid Build Coastguard Worker 		printf("%p", buffer);
95*cf84ac9aSAndroid Build Coastguard Worker 		return;
96*cf84ac9aSAndroid Build Coastguard Worker 	}
97*cf84ac9aSAndroid Build Coastguard Worker 
98*cf84ac9aSAndroid Build Coastguard Worker 	printf("{code=%s", *str);
99*cf84ac9aSAndroid Build Coastguard Worker 	printf(", values=[");
100*cf84ac9aSAndroid Build Coastguard Worker 	for (unsigned int i = 1; i <= (unsigned) num; i++)
101*cf84ac9aSAndroid Build Coastguard Worker 		printf("%s%s", i > 1 ? ", " : "", *(str + i + 1));
102*cf84ac9aSAndroid Build Coastguard Worker 	printf("]}");
103*cf84ac9aSAndroid Build Coastguard Worker }
104*cf84ac9aSAndroid Build Coastguard Worker # endif
105*cf84ac9aSAndroid Build Coastguard Worker 
106*cf84ac9aSAndroid Build Coastguard Worker static void
print_getbit(long rc,void * ptr,void * arg)107*cf84ac9aSAndroid Build Coastguard Worker print_getbit(long rc, void *ptr, void *arg)
108*cf84ac9aSAndroid Build Coastguard Worker {
109*cf84ac9aSAndroid Build Coastguard Worker 	const char **str = arg;
110*cf84ac9aSAndroid Build Coastguard Worker 	int num = atoi(*str);
111*cf84ac9aSAndroid Build Coastguard Worker 
112*cf84ac9aSAndroid Build Coastguard Worker 	if (rc < 0) {
113*cf84ac9aSAndroid Build Coastguard Worker 		printf("%p", ptr);
114*cf84ac9aSAndroid Build Coastguard Worker 		return;
115*cf84ac9aSAndroid Build Coastguard Worker 	}
116*cf84ac9aSAndroid Build Coastguard Worker 
117*cf84ac9aSAndroid Build Coastguard Worker 	printf("[");
118*cf84ac9aSAndroid Build Coastguard Worker 	printf("%s", *(str + 1));
119*cf84ac9aSAndroid Build Coastguard Worker 	for (unsigned int i = 2; i <= (unsigned) num; i++) {
120*cf84ac9aSAndroid Build Coastguard Worker # if ! VERBOSE
121*cf84ac9aSAndroid Build Coastguard Worker 		if (i > 4) {
122*cf84ac9aSAndroid Build Coastguard Worker 			printf(", ...");
123*cf84ac9aSAndroid Build Coastguard Worker 			break;
124*cf84ac9aSAndroid Build Coastguard Worker 		}
125*cf84ac9aSAndroid Build Coastguard Worker # endif
126*cf84ac9aSAndroid Build Coastguard Worker 		printf(", ");
127*cf84ac9aSAndroid Build Coastguard Worker 		printf("%s", *(str + i));
128*cf84ac9aSAndroid Build Coastguard Worker 	}
129*cf84ac9aSAndroid Build Coastguard Worker 	printf("]");
130*cf84ac9aSAndroid Build Coastguard Worker }
131*cf84ac9aSAndroid Build Coastguard Worker 
132*cf84ac9aSAndroid Build Coastguard Worker int
main(int argc,char ** argv)133*cf84ac9aSAndroid Build Coastguard Worker main(int argc, char **argv)
134*cf84ac9aSAndroid Build Coastguard Worker {
135*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long num_skip;
136*cf84ac9aSAndroid Build Coastguard Worker 	long inject_retval;
137*cf84ac9aSAndroid Build Coastguard Worker 	bool locked = false;
138*cf84ac9aSAndroid Build Coastguard Worker 
139*cf84ac9aSAndroid Build Coastguard Worker 	if (argc == 1)
140*cf84ac9aSAndroid Build Coastguard Worker 		return 0;
141*cf84ac9aSAndroid Build Coastguard Worker 
142*cf84ac9aSAndroid Build Coastguard Worker 	if (argc < 3)
143*cf84ac9aSAndroid Build Coastguard Worker 		error_msg_and_fail("Usage: %s NUM_SKIP INJECT_RETVAL", argv[0]);
144*cf84ac9aSAndroid Build Coastguard Worker 
145*cf84ac9aSAndroid Build Coastguard Worker 	num_skip = strtoul(argv[1], NULL, 0);
146*cf84ac9aSAndroid Build Coastguard Worker 	inject_retval = strtol(argv[2], NULL, 0);
147*cf84ac9aSAndroid Build Coastguard Worker 
148*cf84ac9aSAndroid Build Coastguard Worker 	if (inject_retval < 0)
149*cf84ac9aSAndroid Build Coastguard Worker 		error_msg_and_fail("Expected non-negative INJECT_RETVAL, "
150*cf84ac9aSAndroid Build Coastguard Worker 				   "but got %ld", inject_retval);
151*cf84ac9aSAndroid Build Coastguard Worker 
152*cf84ac9aSAndroid Build Coastguard Worker 	for (unsigned int i = 0; i < num_skip; i++) {
153*cf84ac9aSAndroid Build Coastguard Worker 		long rc = ioctl(-1, EVIOCGID, NULL);
154*cf84ac9aSAndroid Build Coastguard Worker 		printf("ioctl(-1, EVIOCGID, NULL) = %s%s\n",
155*cf84ac9aSAndroid Build Coastguard Worker 		       sprintrc(rc),
156*cf84ac9aSAndroid Build Coastguard Worker 		       rc == inject_retval ? " (INJECTED)" : "");
157*cf84ac9aSAndroid Build Coastguard Worker 
158*cf84ac9aSAndroid Build Coastguard Worker 		if (rc != inject_retval)
159*cf84ac9aSAndroid Build Coastguard Worker 			continue;
160*cf84ac9aSAndroid Build Coastguard Worker 
161*cf84ac9aSAndroid Build Coastguard Worker 		locked = true;
162*cf84ac9aSAndroid Build Coastguard Worker 		break;
163*cf84ac9aSAndroid Build Coastguard Worker 	}
164*cf84ac9aSAndroid Build Coastguard Worker 
165*cf84ac9aSAndroid Build Coastguard Worker 	if (!locked)
166*cf84ac9aSAndroid Build Coastguard Worker 		error_msg_and_fail("Hasn't locked on ioctl(-1"
167*cf84ac9aSAndroid Build Coastguard Worker 				   ", EVIOCGID, NULL) returning %lu",
168*cf84ac9aSAndroid Build Coastguard Worker 				   inject_retval);
169*cf84ac9aSAndroid Build Coastguard Worker 
170*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(struct input_id, id);
171*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(struct input_absinfo, absinfo);
172*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(int, bad_addr_slot);
173*cf84ac9aSAndroid Build Coastguard Worker # ifdef EVIOCGMTSLOTS
174*cf84ac9aSAndroid Build Coastguard Worker 	int mtslots[] = { ABS_MT_SLOT, 1, 3 };
175*cf84ac9aSAndroid Build Coastguard Worker 	/* we use the second element to indicate the number of values */
176*cf84ac9aSAndroid Build Coastguard Worker 	/* mtslots_str[1] is "2" so the number of values is 2 */
177*cf84ac9aSAndroid Build Coastguard Worker 	const char *mtslots_str[] = { "ABS_MT_SLOT", "2", "1", "3" };
178*cf84ac9aSAndroid Build Coastguard Worker 
179*cf84ac9aSAndroid Build Coastguard Worker 	/* invalid flag */
180*cf84ac9aSAndroid Build Coastguard Worker 	int invalid_mtslot[] = { -1, 1 };
181*cf84ac9aSAndroid Build Coastguard Worker 	char invalid_str[4096];
182*cf84ac9aSAndroid Build Coastguard Worker 	snprintf(invalid_str, sizeof(invalid_str), "%#x /* ABS_MT_??? */", invalid_mtslot[0]);
183*cf84ac9aSAndroid Build Coastguard Worker 	const char *invalid_mtslot_str[] = { invalid_str, "1", "1" };
184*cf84ac9aSAndroid Build Coastguard Worker # endif
185*cf84ac9aSAndroid Build Coastguard Worker 
186*cf84ac9aSAndroid Build Coastguard Worker 	/* set more than 4 bits */
187*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long ev_more[] = { 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED | 1 << EV_SND | 1 << EV_PWR };
188*cf84ac9aSAndroid Build Coastguard Worker 	/* we use the first element to indicate the number of set bits */
189*cf84ac9aSAndroid Build Coastguard Worker 	/* ev_more_str[0] is "5" so the number of set bits is 5 */
190*cf84ac9aSAndroid Build Coastguard Worker 	const char *ev_more_str[] = { "5", "EV_ABS", "EV_MSC", "EV_LED", "EV_SND", "EV_PWR" };
191*cf84ac9aSAndroid Build Coastguard Worker 
192*cf84ac9aSAndroid Build Coastguard Worker 	/* set less than 4 bits */
193*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long ev_less[] = { 1 << EV_ABS | 1 << EV_MSC | 1 << EV_LED };
194*cf84ac9aSAndroid Build Coastguard Worker 	const char *ev_less_str[] = { "3", "EV_ABS", "EV_MSC", "EV_LED" };
195*cf84ac9aSAndroid Build Coastguard Worker 
196*cf84ac9aSAndroid Build Coastguard Worker 	/* set zero bit */
197*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long ev_zero[] = { 0x0 };
198*cf84ac9aSAndroid Build Coastguard Worker 	const char *ev_zero_str[] = { "0", " 0 " };
199*cf84ac9aSAndroid Build Coastguard Worker 
200*cf84ac9aSAndroid Build Coastguard Worker 	/* KEY_MAX is 0x2ff which is greater than retval * 8 */
201*cf84ac9aSAndroid Build Coastguard Worker 	unsigned long key[] = { 1 << KEY_1 | 1 << KEY_2, 0 };
202*cf84ac9aSAndroid Build Coastguard Worker 	const char *key_str[] = { "2", "KEY_1", "KEY_2" };
203*cf84ac9aSAndroid Build Coastguard Worker 
204*cf84ac9aSAndroid Build Coastguard Worker 	struct {
205*cf84ac9aSAndroid Build Coastguard Worker 		struct evdev_check check;
206*cf84ac9aSAndroid Build Coastguard Worker 		void *ptr;
207*cf84ac9aSAndroid Build Coastguard Worker 	} a[] = {
208*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGID), id, print_input_id }, NULL },
209*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo }, NULL },
210*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL },
211*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL },
212*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit }, &ev_more_str },
213*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGBIT(0, 0)), ev_less, print_getbit }, &ev_less_str },
214*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGBIT(0, 0)), ev_zero, print_getbit }, &ev_zero_str },
215*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGBIT(EV_KEY, 0)), key, print_getbit }, &key_str},
216*cf84ac9aSAndroid Build Coastguard Worker # ifdef EVIOCGMTSLOTS
217*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGMTSLOTS(12)), mtslots, print_mtslots }, &mtslots_str },
218*cf84ac9aSAndroid Build Coastguard Worker 		{ { ARG_STR(EVIOCGMTSLOTS(8)), invalid_mtslot, print_mtslots }, &invalid_mtslot_str }
219*cf84ac9aSAndroid Build Coastguard Worker # endif
220*cf84ac9aSAndroid Build Coastguard Worker 	};
221*cf84ac9aSAndroid Build Coastguard Worker 	for (unsigned int i = 0; i < ARRAY_SIZE(a); i++) {
222*cf84ac9aSAndroid Build Coastguard Worker 		test_evdev(&a[i].check, a[i].ptr);
223*cf84ac9aSAndroid Build Coastguard Worker 	}
224*cf84ac9aSAndroid Build Coastguard Worker 
225*cf84ac9aSAndroid Build Coastguard Worker 	puts("+++ exited with 0 +++");
226*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
227*cf84ac9aSAndroid Build Coastguard Worker }
228*cf84ac9aSAndroid Build Coastguard Worker #else
229*cf84ac9aSAndroid Build Coastguard Worker 
230*cf84ac9aSAndroid Build Coastguard Worker SKIP_MAIN_UNDEFINED("HAVE_LINUX_INPUT_H")
231*cf84ac9aSAndroid Build Coastguard Worker 
232*cf84ac9aSAndroid Build Coastguard Worker #endif
233