Home | History | Annotate | Download | only in toolbox
      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 
     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;
     25     uint8_t *ioctl_argp;
     26     uint8_t *ioctl_argp_save;
     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     fd = open(argv[optind], O_RDWR | O_SYNC);
     67     if (fd < 0) {
     68         fprintf(stderr, "cannot open %s\n", argv[optind]);
     69         return 1;
     70     }
     71     optind++;
     72 
     73     ioctl_nr = strtol(argv[optind], NULL, 0);
     74     optind++;
     75 
     76     if(direct_arg) {
     77         arg_size = 4;
     78         length = 4;
     79     }
     80 
     81     if(length < 0) {
     82         length = (argc - optind) * arg_size;
     83     }
     84     if(length) {
     85         ioctl_args = calloc(1, length);
     86 
     87         ioctl_argp_save = ioctl_argp = ioctl_args;
     88         rem = length;
     89         while(optind < argc) {
     90             uint64_t tmp = strtoull(argv[optind], NULL, 0);
     91             if(rem < arg_size) {
     92                 fprintf(stderr, "%s: too many arguments\n", argv[0]);
     93                 exit(1);
     94             }
     95             memcpy(ioctl_argp, &tmp, arg_size);
     96             ioctl_argp += arg_size;
     97             rem -= arg_size;
     98             optind++;
     99         }
    100     }
    101     printf("sending ioctl 0x%x", ioctl_nr);
    102     rem = length;
    103     while(rem--) {
    104         printf(" 0x%02x", *ioctl_argp_save++);
    105     }
    106     printf("\n");
    107 
    108     if(direct_arg)
    109         res = ioctl(fd, ioctl_nr, *(uint32_t*)ioctl_args);
    110     else if(length)
    111         res = ioctl(fd, ioctl_nr, ioctl_args);
    112     else
    113         res = ioctl(fd, ioctl_nr, 0);
    114     if (res < 0) {
    115         fprintf(stderr, "ioctl 0x%x failed, %d\n", ioctl_nr, res);
    116         return 1;
    117     }
    118     if(length) {
    119         printf("return buf:");
    120         ioctl_argp = ioctl_args;
    121         rem = length;
    122         while(rem--) {
    123             printf(" %02x", *ioctl_argp++);
    124         }
    125         printf("\n");
    126     }
    127     return 0;
    128 }
    129