1 /* 2 * This file is part of ioctl_evdev strace test. 3 * 4 * Copyright (c) 2016 Dmitry V. Levin <ldv (at) 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 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 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 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