blob: e28f2a4668af9146f99234423a6022ec3a44848f [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001#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
10int 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}