| #include <stdio.h> | 
 | #include <stdlib.h> | 
 | #include <stdint.h> | 
 | #include <fcntl.h> | 
 | #include <getopt.h> | 
 | #include <string.h> | 
 | #include <linux/kd.h> | 
 | #include <linux/vt.h> | 
 | #include <errno.h> | 
 | #include <pthread.h> | 
 | #include <sys/ioctl.h> | 
 |  | 
 | int ioctl_main(int argc, char *argv[]) | 
 | { | 
 |     int c; | 
 |     int fd; | 
 |     int res; | 
 |  | 
 |     int read_only = 0; | 
 |     int length = -1; | 
 |     int arg_size = 4; | 
 |     int direct_arg = 0; | 
 |     uint32_t ioctl_nr; | 
 |     void *ioctl_args; | 
 |     uint8_t *ioctl_argp; | 
 |     uint8_t *ioctl_argp_save; | 
 |     int rem; | 
 |  | 
 |     do { | 
 |         c = getopt(argc, argv, "rdl:a:h"); | 
 |         if (c == EOF) | 
 |             break; | 
 |         switch (c) { | 
 |         case 'r': | 
 |             read_only = 1; | 
 |             break; | 
 |         case 'd': | 
 |             direct_arg = 1; | 
 |             break; | 
 |         case 'l': | 
 |             length = strtol(optarg, NULL, 0); | 
 |             break; | 
 |         case 'a': | 
 |             arg_size = strtol(optarg, NULL, 0); | 
 |             break; | 
 |         case 'h': | 
 |             fprintf(stderr, "%s [-l <length>] [-a <argsize>] [-rdh] <device> <ioctlnr>\n" | 
 |                     "  -l <lenght>   Length of io buffer\n" | 
 |                     "  -a <argsize>  Size of each argument (1-8)\n" | 
 |                     "  -r            Open device in read only mode\n" | 
 |                     "  -d            Direct argument (no iobuffer)\n" | 
 |                     "  -h            Print help\n", argv[0]); | 
 |             return -1; | 
 |         case '?': | 
 |             fprintf(stderr, "%s: invalid option -%c\n", | 
 |                 argv[0], optopt); | 
 |             exit(1); | 
 |         } | 
 |     } while (1); | 
 |  | 
 |     if(optind + 2 > argc) { | 
 |         fprintf(stderr, "%s: too few arguments\n", argv[0]); | 
 |         exit(1); | 
 |     } | 
 |  | 
 |     fd = open(argv[optind], O_RDWR | O_SYNC); | 
 |     if (fd < 0) { | 
 |         fprintf(stderr, "cannot open %s\n", argv[optind]); | 
 |         return 1; | 
 |     } | 
 |     optind++; | 
 |      | 
 |     ioctl_nr = strtol(argv[optind], NULL, 0); | 
 |     optind++; | 
 |  | 
 |     if(direct_arg) { | 
 |         arg_size = 4; | 
 |         length = 4; | 
 |     } | 
 |  | 
 |     if(length < 0) { | 
 |         length = (argc - optind) * arg_size; | 
 |     } | 
 |     if(length) { | 
 |         ioctl_args = calloc(1, length); | 
 |  | 
 |         ioctl_argp_save = ioctl_argp = ioctl_args; | 
 |         rem = length; | 
 |         while(optind < argc) { | 
 |             uint64_t tmp = strtoull(argv[optind], NULL, 0); | 
 |             if(rem < arg_size) { | 
 |                 fprintf(stderr, "%s: too many arguments\n", argv[0]); | 
 |                 exit(1); | 
 |             } | 
 |             memcpy(ioctl_argp, &tmp, arg_size); | 
 |             ioctl_argp += arg_size; | 
 |             rem -= arg_size; | 
 |             optind++; | 
 |         } | 
 |     } | 
 |     printf("sending ioctl 0x%x", ioctl_nr); | 
 |     rem = length; | 
 |     while(rem--) { | 
 |         printf(" 0x%02x", *ioctl_argp_save++); | 
 |     } | 
 |     printf("\n"); | 
 |  | 
 |     if(direct_arg) | 
 |         res = ioctl(fd, ioctl_nr, *(uint32_t*)ioctl_args); | 
 |     else if(length) | 
 |         res = ioctl(fd, ioctl_nr, ioctl_args); | 
 |     else | 
 |         res = ioctl(fd, ioctl_nr, 0); | 
 |     if (res < 0) { | 
 |         fprintf(stderr, "ioctl 0x%x failed, %d\n", ioctl_nr, res); | 
 |         return 1; | 
 |     } | 
 |     if(length) { | 
 |         printf("return buf:"); | 
 |         ioctl_argp = ioctl_args; | 
 |         rem = length; | 
 |         while(rem--) { | 
 |             printf(" %02x", *ioctl_argp++); | 
 |         } | 
 |         printf("\n"); | 
 |     } | 
 |     return 0; | 
 | } |