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-2017 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 static const unsigned int magic = 0xdeadbeef; 43 static const unsigned long lmagic = (unsigned long) 0xdeadbeefbadc0dedULL; 44 45 # if VERBOSE 46 static void 47 print_envelope(const struct ff_envelope *const e) 48 { 49 printf(", envelope={attack_length=%hu, attack_level=%hu" 50 ", fade_length=%hu, fade_level=%#hx}", 51 e->attack_length, e->attack_level, 52 e->fade_length, e->fade_level); 53 } 54 # endif /* VERBOSE */ 55 56 static void 57 print_ffe_common(const struct ff_effect *const ffe, const char *const type_str) 58 { 59 printf("ioctl(-1, EVIOCSFF, {type=%s, id=%" PRIu16 60 ", direction=%" PRIu16 ", ", 61 type_str, ffe->id, ffe->direction); 62 # if VERBOSE 63 printf("trigger={button=%hu, interval=%hu}" 64 ", replay={length=%hu, delay=%hu}", 65 ffe->trigger.button, ffe->trigger.interval, 66 ffe->replay.length, ffe->replay.delay); 67 # endif /* VERBOSE */ 68 } 69 70 # define TEST_NULL_ARG(cmd) \ 71 do { \ 72 ioctl(-1, cmd, 0); \ 73 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", #cmd); \ 74 } while (0) 75 76 int 77 main(void) 78 { 79 TEST_NULL_ARG(EVIOCGVERSION); 80 TEST_NULL_ARG(EVIOCGEFFECTS); 81 TEST_NULL_ARG(EVIOCGID); 82 TEST_NULL_ARG(EVIOCGKEYCODE); 83 TEST_NULL_ARG(EVIOCSKEYCODE); 84 TEST_NULL_ARG(EVIOCSFF); 85 # ifdef EVIOCGKEYCODE_V2 86 TEST_NULL_ARG(EVIOCGKEYCODE_V2); 87 # endif 88 # ifdef EVIOCSKEYCODE_V2 89 TEST_NULL_ARG(EVIOCSKEYCODE_V2); 90 # endif 91 # ifdef EVIOCGREP 92 TEST_NULL_ARG(EVIOCGREP); 93 # endif 94 # ifdef EVIOCSREP 95 TEST_NULL_ARG(EVIOCSREP); 96 # endif 97 # ifdef EVIOCSCLOCKID 98 TEST_NULL_ARG(EVIOCSCLOCKID); 99 # endif 100 101 TEST_NULL_ARG(EVIOCGNAME(0)); 102 TEST_NULL_ARG(EVIOCGPHYS(0)); 103 TEST_NULL_ARG(EVIOCGUNIQ(0)); 104 TEST_NULL_ARG(EVIOCGKEY(0)); 105 TEST_NULL_ARG(EVIOCGLED(0)); 106 # ifdef EVIOCGMTSLOTS 107 TEST_NULL_ARG(EVIOCGMTSLOTS(0)); 108 # endif 109 # ifdef EVIOCGPROP 110 TEST_NULL_ARG(EVIOCGPROP(0)); 111 # endif 112 TEST_NULL_ARG(EVIOCGSND(0)); 113 # ifdef EVIOCGSW 114 TEST_NULL_ARG(EVIOCGSW(0)); 115 # endif 116 117 TEST_NULL_ARG(EVIOCGABS(ABS_X)); 118 TEST_NULL_ARG(EVIOCSABS(ABS_X)); 119 120 TEST_NULL_ARG(EVIOCGBIT(EV_SYN, 0)); 121 TEST_NULL_ARG(EVIOCGBIT(EV_KEY, 1)); 122 TEST_NULL_ARG(EVIOCGBIT(EV_REL, 2)); 123 TEST_NULL_ARG(EVIOCGBIT(EV_ABS, 3)); 124 TEST_NULL_ARG(EVIOCGBIT(EV_MSC, 4)); 125 # ifdef EV_SW 126 TEST_NULL_ARG(EVIOCGBIT(EV_SW, 5)); 127 # endif 128 TEST_NULL_ARG(EVIOCGBIT(EV_LED, 6)); 129 TEST_NULL_ARG(EVIOCGBIT(EV_SND, 7)); 130 TEST_NULL_ARG(EVIOCGBIT(EV_REP, 8)); 131 TEST_NULL_ARG(EVIOCGBIT(EV_FF, 9)); 132 TEST_NULL_ARG(EVIOCGBIT(EV_PWR, 10)); 133 TEST_NULL_ARG(EVIOCGBIT(EV_FF_STATUS, 11)); 134 135 ioctl(-1, EVIOCGBIT(EV_MAX, 42), 0); 136 printf("ioctl(-1, EVIOCGBIT(%#x /* EV_??? */, 42), NULL)" 137 " = -1 EBADF (%m)\n", EV_MAX); 138 139 ioctl(-1, EVIOCRMFF, lmagic); 140 printf("ioctl(-1, EVIOCRMFF, %d) = -1 EBADF (%m)\n", (int) lmagic); 141 142 ioctl(-1, EVIOCGRAB, lmagic); 143 printf("ioctl(-1, EVIOCGRAB, %lu) = -1 EBADF (%m)\n", lmagic); 144 145 # ifdef EVIOCREVOKE 146 ioctl(-1, EVIOCREVOKE, lmagic); 147 printf("ioctl(-1, EVIOCREVOKE, %lu) = -1 EBADF (%m)\n", lmagic); 148 # endif 149 150 const unsigned int size = get_page_size(); 151 void *const page = tail_alloc(size); 152 fill_memory(page, size); 153 154 TAIL_ALLOC_OBJECT_CONST_PTR(int, val_int); 155 *val_int = magic; 156 157 # ifdef EVIOCSCLOCKID 158 ioctl(-1, EVIOCSCLOCKID, val_int); 159 printf("ioctl(-1, EVIOCSCLOCKID, [%u]) = -1 EBADF (%m)\n", *val_int); 160 # endif 161 162 int *pair_int = tail_alloc(sizeof(*pair_int) * 2); 163 pair_int[0] = 0xdeadbeef; 164 pair_int[1] = 0xbadc0ded; 165 166 # ifdef EVIOSGREP 167 ioctl(-1, EVIOCSREP, pair_int); 168 printf("ioctl(-1, EVIOCSREP, [%u, %u]) = -1 EBADF (%m)\n", 169 pair_int[0], pair_int[1]); 170 # endif 171 172 pair_int[1] = 1; 173 ioctl(-1, EVIOCSKEYCODE, pair_int); 174 printf("ioctl(-1, EVIOCSKEYCODE, [%u, %s]) = -1 EBADF (%m)\n", 175 pair_int[0], "KEY_ESC"); 176 177 # ifdef EVIOCSKEYCODE_V2 178 TAIL_ALLOC_OBJECT_CONST_PTR(struct input_keymap_entry, ike); 179 fill_memory(ike, sizeof(*ike)); 180 ike->keycode = 2; 181 182 ioctl(-1, EVIOCSKEYCODE_V2, ike); 183 printf("ioctl(-1, EVIOCSKEYCODE_V2, {flags=%" PRIu8 184 ", len=%" PRIu8 ", ", ike->flags, ike->len); 185 # if VERBOSE 186 printf("index=%" PRIu16 ", keycode=%s, scancode=[", 187 ike->index, "KEY_1"); 188 unsigned int i; 189 for (i = 0; i < ARRAY_SIZE(ike->scancode); ++i) { 190 if (i > 0) 191 printf(", "); 192 printf("%" PRIx8, ike->scancode[i]); 193 } 194 printf("]"); 195 # else 196 printf("..."); 197 # endif 198 errno = EBADF; 199 printf("}) = -1 EBADF (%m)\n"); 200 # endif 201 202 TAIL_ALLOC_OBJECT_CONST_PTR(struct ff_effect, ffe); 203 fill_memory(ffe, sizeof(*ffe)); 204 205 ffe->type = FF_CONSTANT; 206 ioctl(-1, EVIOCSFF, ffe); 207 print_ffe_common(ffe, "FF_CONSTANT"); 208 209 # if VERBOSE 210 printf(", constant={level=%hd", ffe->u.constant.level); 211 print_envelope(&ffe->u.constant.envelope); 212 printf("}"); 213 # else 214 printf("..."); 215 # endif 216 errno = EBADF; 217 printf("}) = -1 EBADF (%m)\n"); 218 219 # if VERBOSE 220 ffe->type = FF_RAMP; 221 ioctl(-1, EVIOCSFF, ffe); 222 print_ffe_common(ffe, "FF_RAMP"); 223 printf(", ramp={start_level=%hd, end_level=%hd", 224 ffe->u.ramp.start_level, ffe->u.ramp.end_level); 225 print_envelope(&ffe->u.ramp.envelope); 226 errno = EBADF; 227 printf("}}) = -1 EBADF (%m)\n"); 228 229 ffe->type = FF_PERIODIC; 230 ioctl(-1, EVIOCSFF, ffe); 231 print_ffe_common(ffe, "FF_PERIODIC"); 232 printf(", periodic={waveform=%hu, period=%hu, magnitude=%hd" 233 ", offset=%hd, phase=%hu", 234 ffe->u.periodic.waveform, ffe->u.periodic.period, 235 ffe->u.periodic.magnitude, ffe->u.periodic.offset, 236 ffe->u.periodic.phase); 237 print_envelope(&ffe->u.periodic.envelope); 238 printf(", custom_len=%u, custom_data=%p}", 239 ffe->u.periodic.custom_len, ffe->u.periodic.custom_data); 240 errno = EBADF; 241 printf("}) = -1 EBADF (%m)\n"); 242 243 ffe->type = FF_RUMBLE; 244 ioctl(-1, EVIOCSFF, ffe); 245 print_ffe_common(ffe, "FF_RUMBLE"); 246 printf(", rumble={strong_magnitude=%hu, weak_magnitude=%hu}", 247 ffe->u.rumble.strong_magnitude, ffe->u.rumble.weak_magnitude); 248 errno = EBADF; 249 printf("}) = -1 EBADF (%m)\n"); 250 251 ffe->type = 0xff; 252 ioctl(-1, EVIOCSFF, ffe); 253 print_ffe_common(ffe, "0xff /* FF_??? */"); 254 errno = EBADF; 255 printf("}) = -1 EBADF (%m)\n"); 256 # endif 257 258 ioctl(-1, _IOC(_IOC_READ, 0x45, 0x1, 0xff), lmagic); 259 printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", 260 "_IOC(_IOC_READ, 0x45, 0x1, 0xff)", lmagic); 261 262 ioctl(-1, _IOC(_IOC_WRITE, 0x45, 0x1, 0xff), lmagic); 263 printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", 264 "_IOC(_IOC_WRITE, 0x45, 0x1, 0xff)", lmagic); 265 266 ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, 0x45, 0xfe, 0xff), lmagic); 267 printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", 268 "_IOC(_IOC_READ|_IOC_WRITE, 0x45, 0xfe, 0xff)", lmagic); 269 270 ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, 0x45, 0, 0), lmagic); 271 printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", 272 "_IOC(_IOC_READ|_IOC_WRITE, 0x45, 0, 0)", lmagic); 273 274 puts("+++ exited with 0 +++"); 275 return 0; 276 } 277 #else 278 279 SKIP_MAIN_UNDEFINED("HAVE_LINUX_INPUT_H") 280 281 #endif 282