summaryrefslogtreecommitdiff
path: root/package/toolbox/src/src/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/toolbox/src/src/ioctl.c')
-rw-r--r--package/toolbox/src/src/ioctl.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/package/toolbox/src/src/ioctl.c b/package/toolbox/src/src/ioctl.c
new file mode 100644
index 000000000..abc1bec79
--- /dev/null
+++ b/package/toolbox/src/src/ioctl.c
@@ -0,0 +1,124 @@
+#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 main(int argc, char *argv[])
+{
+ int c;
+ int fd;
+ int res;
+
+ int length = -1;
+ int arg_size = 4;
+ int direct_arg = 0;
+ uint32_t ioctl_nr;
+ void *ioctl_args = NULL;
+ uint8_t *ioctl_argp;
+ uint8_t *ioctl_argp_save = NULL;
+ int rem;
+
+ do {
+ c = getopt(argc, argv, "rdl:a:h");
+ if (c == EOF)
+ break;
+ switch (c) {
+ 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;
+}