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