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