(root)/
strace-6.5/
tests/
ioctl_tiocm.c
       1  /*
       2   * Check decoding of ioctl TIOCM* commands.
       3   *
       4   * Copyright (c) 2020-2022 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  #include <errno.h>
      12  #include <stdio.h>
      13  #include <sys/ioctl.h>
      14  
      15  static const char *errstr;
      16  
      17  static int
      18  do_ioctl(kernel_ulong_t cmd, kernel_ulong_t arg)
      19  {
      20  	int rc = ioctl(-1, cmd, arg);
      21  	errstr = sprintrc(rc);
      22  	return rc;
      23  }
      24  
      25  static int
      26  do_ioctl_ptr(kernel_ulong_t cmd, const void *arg)
      27  {
      28  	return do_ioctl(cmd, (uintptr_t) arg);
      29  }
      30  
      31  int
      32  main(int argc, const char *argv[])
      33  {
      34  	static const struct {
      35  		uint32_t cmd;
      36  		const char *str;
      37  		bool on_enter;
      38  		bool on_exit;
      39  	} cmds[] = {
      40  		{ ARG_STR(TIOCMGET), false, true },
      41  		{ ARG_STR(TIOCMBIS), true, false },
      42  		{ ARG_STR(TIOCMBIC), true, false },
      43  		{ ARG_STR(TIOCMSET), true, false },
      44  	};
      45  
      46  	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, p_flags);
      47  	const void *const efault = p_flags + 1;
      48  
      49  	for (size_t i = 0; i < ARRAY_SIZE(cmds); ++i) {
      50  		do_ioctl(cmds[i].cmd, 0);
      51  		printf("ioctl(-1, " XLAT_FMT ", NULL) = %s\n",
      52  		       XLAT_SEL(cmds[i].cmd, cmds[i].str), errstr);
      53  
      54  		do_ioctl_ptr(cmds[i].cmd, efault);
      55  		printf("ioctl(-1, " XLAT_FMT ", %p) = %s\n",
      56  		       XLAT_SEL(cmds[i].cmd, cmds[i].str),
      57  		       efault, errstr);
      58  
      59  #ifdef __mips__
      60  # define VALID_FLAGS 0xe777
      61  # define INVALID_FLAGS  0xffff1888
      62  #else
      63  # define VALID_FLAGS 0xe1ff
      64  # define INVALID_FLAGS  0xffff1e00
      65  #endif
      66  		*p_flags = INVALID_FLAGS;
      67  
      68  		if (cmds[i].on_enter) {
      69  			do_ioctl_ptr(cmds[i].cmd, p_flags);
      70  			printf("ioctl(-1, " XLAT_FMT ", [%s]) = %s\n",
      71  			       XLAT_SEL(cmds[i].cmd, cmds[i].str),
      72  			       XLAT_UNKNOWN(INVALID_FLAGS, "TIOCM_???"),
      73  			       errstr);
      74  
      75  			*p_flags = ~*p_flags;
      76  			do_ioctl_ptr(cmds[i].cmd, p_flags);
      77  			printf("ioctl(-1, " XLAT_FMT ", [%s]) = %s\n",
      78  			       XLAT_SEL(cmds[i].cmd, cmds[i].str),
      79  			       XLAT_KNOWN(VALID_FLAGS,
      80  					  "TIOCM_LE|"
      81  					  "TIOCM_DTR|"
      82  					  "TIOCM_RTS|"
      83  					  "TIOCM_ST|"
      84  					  "TIOCM_SR|"
      85  					  "TIOCM_CTS|"
      86  					  "TIOCM_CAR|"
      87  					  "TIOCM_RNG|"
      88  					  "TIOCM_DSR|"
      89  					  "TIOCM_OUT1|"
      90  					  "TIOCM_OUT2|"
      91  					  "TIOCM_LOOP"),
      92  			       errstr);
      93  		} else if (cmds[i].on_exit) {
      94  			do_ioctl_ptr(cmds[i].cmd, p_flags);
      95  			printf("ioctl(-1, " XLAT_FMT ", %p) = %s\n",
      96  			       XLAT_SEL(cmds[i].cmd, cmds[i].str),
      97  			       p_flags, errstr);
      98  		}
      99  
     100  	}
     101  
     102  	puts("+++ exited with 0 +++");
     103  	return 0;
     104  }