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