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