ioctl.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <fcntl.h>
  5. #include <getopt.h>
  6. #include <string.h>
  7. #include <linux/kd.h>
  8. #include <linux/vt.h>
  9. #include <errno.h>
  10. #include <pthread.h>
  11. #include <sys/ioctl.h>
  12. int main(int argc, char *argv[])
  13. {
  14. int c;
  15. int fd;
  16. int res;
  17. int length = -1;
  18. int arg_size = 4;
  19. int direct_arg = 0;
  20. uint32_t ioctl_nr;
  21. void *ioctl_args = NULL;
  22. uint8_t *ioctl_argp;
  23. uint8_t *ioctl_argp_save = NULL;
  24. int rem;
  25. do {
  26. c = getopt(argc, argv, "rdl:a:h");
  27. if (c == EOF)
  28. break;
  29. switch (c) {
  30. case 'd':
  31. direct_arg = 1;
  32. break;
  33. case 'l':
  34. length = strtol(optarg, NULL, 0);
  35. break;
  36. case 'a':
  37. arg_size = strtol(optarg, NULL, 0);
  38. break;
  39. case 'h':
  40. fprintf(stderr, "%s [-l <length>] [-a <argsize>] [-rdh] <device> <ioctlnr>\n"
  41. " -l <lenght> Length of io buffer\n"
  42. " -a <argsize> Size of each argument (1-8)\n"
  43. " -r Open device in read only mode\n"
  44. " -d Direct argument (no iobuffer)\n"
  45. " -h Print help\n", argv[0]);
  46. return -1;
  47. case '?':
  48. fprintf(stderr, "%s: invalid option -%c\n",
  49. argv[0], optopt);
  50. exit(1);
  51. }
  52. } while (1);
  53. if(optind + 2 > argc) {
  54. fprintf(stderr, "%s: too few arguments\n", argv[0]);
  55. exit(1);
  56. }
  57. fd = open(argv[optind], O_RDWR | O_SYNC);
  58. if (fd < 0) {
  59. fprintf(stderr, "cannot open %s\n", argv[optind]);
  60. return 1;
  61. }
  62. optind++;
  63. ioctl_nr = strtol(argv[optind], NULL, 0);
  64. optind++;
  65. if(direct_arg) {
  66. arg_size = 4;
  67. length = 4;
  68. }
  69. if(length < 0) {
  70. length = (argc - optind) * arg_size;
  71. }
  72. if(length) {
  73. ioctl_args = calloc(1, length);
  74. ioctl_argp_save = ioctl_argp = ioctl_args;
  75. rem = length;
  76. while(optind < argc) {
  77. uint64_t tmp = strtoull(argv[optind], NULL, 0);
  78. if(rem < arg_size) {
  79. fprintf(stderr, "%s: too many arguments\n", argv[0]);
  80. exit(1);
  81. }
  82. memcpy(ioctl_argp, &tmp, arg_size);
  83. ioctl_argp += arg_size;
  84. rem -= arg_size;
  85. optind++;
  86. }
  87. }
  88. printf("sending ioctl 0x%x", ioctl_nr);
  89. rem = length;
  90. while(rem--) {
  91. printf(" 0x%02x", *ioctl_argp_save++);
  92. }
  93. printf("\n");
  94. if(direct_arg)
  95. res = ioctl(fd, ioctl_nr, *(uint32_t*)ioctl_args);
  96. else if(length)
  97. res = ioctl(fd, ioctl_nr, ioctl_args);
  98. else
  99. res = ioctl(fd, ioctl_nr, 0);
  100. if (res < 0) {
  101. fprintf(stderr, "ioctl 0x%x failed, %d\n", ioctl_nr, res);
  102. return 1;
  103. }
  104. if(length) {
  105. printf("return buf:");
  106. ioctl_argp = ioctl_args;
  107. rem = length;
  108. while(rem--) {
  109. printf(" %02x", *ioctl_argp++);
  110. }
  111. printf("\n");
  112. }
  113. return 0;
  114. }