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