| The Android Open Source Project | dd7bc33 | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 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 |  | 
 | 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 | } |