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
ioctl_main(int argc,char * argv[])13 int ioctl_main(int argc, char *argv[])
14 {
15 int c;
16 int fd;
17 int res;
18
19 int read_only = 0;
20 int length = -1;
21 int arg_size = 4;
22 int direct_arg = 0;
23 uint32_t ioctl_nr;
24 void *ioctl_args = NULL;
25 uint8_t *ioctl_argp;
26 uint8_t *ioctl_argp_save = NULL;
27 int rem;
28
29 do {
30 c = getopt(argc, argv, "rdl:a:h");
31 if (c == EOF)
32 break;
33 switch (c) {
34 case 'r':
35 read_only = 1;
36 break;
37 case 'd':
38 direct_arg = 1;
39 break;
40 case 'l':
41 length = strtol(optarg, NULL, 0);
42 break;
43 case 'a':
44 arg_size = strtol(optarg, NULL, 0);
45 break;
46 case 'h':
47 fprintf(stderr, "%s [-l <length>] [-a <argsize>] [-rdh] <device> <ioctlnr>\n"
48 " -l <lenght> Length of io buffer\n"
49 " -a <argsize> Size of each argument (1-8)\n"
50 " -r Open device in read only mode\n"
51 " -d Direct argument (no iobuffer)\n"
52 " -h Print help\n", argv[0]);
53 return -1;
54 case '?':
55 fprintf(stderr, "%s: invalid option -%c\n",
56 argv[0], optopt);
57 exit(1);
58 }
59 } while (1);
60
61 if(optind + 2 > argc) {
62 fprintf(stderr, "%s: too few arguments\n", argv[0]);
63 exit(1);
64 }
65
66 if (!strcmp(argv[optind], "-")) {
67 fd = STDIN_FILENO;
68 } else {
69 fd = open(argv[optind], read_only ? O_RDONLY : (O_RDWR | O_SYNC));
70 if (fd < 0) {
71 fprintf(stderr, "cannot open %s\n", argv[optind]);
72 return 1;
73 }
74 }
75 optind++;
76
77 ioctl_nr = strtol(argv[optind], NULL, 0);
78 optind++;
79
80 if(direct_arg) {
81 arg_size = 4;
82 length = 4;
83 }
84
85 if(length < 0) {
86 length = (argc - optind) * arg_size;
87 }
88 if(length) {
89 ioctl_args = calloc(1, length);
90
91 ioctl_argp_save = ioctl_argp = ioctl_args;
92 rem = length;
93 while(optind < argc) {
94 uint64_t tmp = strtoull(argv[optind], NULL, 0);
95 if(rem < arg_size) {
96 fprintf(stderr, "%s: too many arguments\n", argv[0]);
97 exit(1);
98 }
99 memcpy(ioctl_argp, &tmp, arg_size);
100 ioctl_argp += arg_size;
101 rem -= arg_size;
102 optind++;
103 }
104 }
105 printf("sending ioctl 0x%x", ioctl_nr);
106 rem = length;
107 while(rem--) {
108 printf(" 0x%02x", *ioctl_argp_save++);
109 }
110 printf("\n");
111
112 if(direct_arg)
113 res = ioctl(fd, ioctl_nr, *(uint32_t*)ioctl_args);
114 else if(length)
115 res = ioctl(fd, ioctl_nr, ioctl_args);
116 else
117 res = ioctl(fd, ioctl_nr, 0);
118 if (res < 0) {
119 free(ioctl_args);
120 fprintf(stderr, "ioctl 0x%x failed, %d\n", ioctl_nr, res);
121 return 1;
122 }
123 if(length) {
124 printf("return buf:");
125 ioctl_argp = ioctl_args;
126 rem = length;
127 while(rem--) {
128 printf(" %02x", *ioctl_argp++);
129 }
130 printf("\n");
131 }
132 free(ioctl_args);
133 return 0;
134 }
135