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 = 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