chiark / gitweb /
hostside: hidraw-ioctl: much improved, now a useful utility
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 30 Jan 2011 17:55:50 +0000 (17:55 +0000)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 30 Jan 2011 19:22:06 +0000 (19:22 +0000)
hostside/Makefile
hostside/hidraw-ioctl.c

index 64fa270ae6fa1ab0ebe413268529e557f9985178..7429f515097ee864255bbd1c90a0511715c15e73 100644 (file)
@@ -39,7 +39,7 @@ topology-dump:        topology-dump.o utils.o $(LAYOUT_DATA).o
 
 evdev-manip:   evdev-manip.o utils.o $(LIBOOP_OBJS)
 
-hidraw-ioctl:  hidraw-ioctl.o
+hidraw-ioctl:  hidraw-ioctl.o utils.o
 hiddev-ioctl:  hiddev-ioctl.o utils.o
 kdled-ioctl:   kdled-ioctl.o
 
index 027e953e66fd677982aa09b9742d25d1b53d6294..4da6171c7c22a12b5b96b898b7e8e3d11ec0b90f 100644 (file)
@@ -1,4 +1,18 @@
-/**/
+/*
+ * usage:
+ *   .../hidraw-ioctl </dev/hidrawN -a
+ *   .../hidraw-ioctl </dev/hidrawN -[drnp]
+ * where -a means all, and the other letters are:
+ *   -d   descriptors (in hex)
+ *   -D   descriptors length (decimal), descriptors (in hex)
+ *   -i   HIDIOCGRAWINFO: bustype, vendor, product (all in hex)
+ *   -n   HIDIOCGRAWNAME
+ *   -p   HIDIOCGRAWPATHPHYS
+ * exit status:
+ *   0      all ok
+ *   2      at least one ioctl on the device failed
+ *   other  some other problem
+ */
 
 #include <stdio.h>
 #include <stdint.h>
 
 #include "common.h"
 
+void die_vprintf_hook(const char *fmt, va_list al) { }
+void die_hook(void) { }
+const char *progname= "hidraw-ioctl";
+
+static void prerror(const char *what) {
+  printf("%s: %s\n", what, strerror(errno));
+}
+
+#define ERR(s) do{ prerror(s); e=1; goto next_opt; }while(0)
+
 int main(int argc, char **argv) {
-  int r, descsz;
-
-  r= ioctl(0, HIDIOCGRDESCSIZE, &descsz);
-  if (r) {
-    perror("HIDIOCGRDESCSIZE");
-  } else {
-    printf("%d\n",descsz);
-    struct {
-      struct hidraw_report_descriptor d;
-      unsigned char buf[descsz];
-    } d;
-    d.d.size = descsz;
-    r= ioctl(0, HIDIOCGRDESC, &d);
-    if (r) perror("HIDIOCGRDESC");
-    else { dump(d.d.value, d.d.size); putchar('\n'); }
-  }
+  static const char allopts[]= "Dinp";
+  int r, opt, e=0;
+  const char *opts;
 
-  struct hidraw_devinfo di;
-  r= ioctl(0, HIDIOCGRAWINFO, &di);
-  if (r) perror("HIDIOCGRAWINFO");
-  else {
-    printf("%08"PRIx32" %04"PRIx16" %04"PRIx16"\n",
-          di.bustype, di.vendor, di.product);
-  }
+  if (!*argv || !(opts=*++argv) || *opts++!='-' || *++argv)
+    badusage("need exactly one argument, containing options");
+  if (!strcmp(opts,"a")) opts= allopts;
+
+  while ((opt= *opts++)) {
+    switch (opt) {
 
-  unsigned char buf[PATH_MAX];
+    case 'd': case 'D':;
+      int descsz;
+      r= ioctl(0, HIDIOCGRDESCSIZE, &descsz);
+      if (r) ERR("HIDIOCGRDESCSIZE");
 
-  r= ioctl(0, HIDIOCGRAWNAME(PATH_MAX), buf);
-  if (r<0) perror("HIDIOCGRAWNAME");
-  else printf("%d %.*s\n", r, r,buf);
+      if (opt=='D') printf("%d\n",descsz);
 
-  r= ioctl(0, HIDIOCGRAWPHYS(PATH_MAX), buf);
-  if (r<0) perror("HIDIOCGRAWPHYS");
-  else printf("%d %.*s\n", r, r,buf);
+      {
+       struct {
+         struct hidraw_report_descriptor d;
+         unsigned char buf[descsz];
+       } d;
+       d.d.size = descsz;
+       r= ioctl(0, HIDIOCGRDESC, &d);
+       if (r) ERR("HIDIOCGRDESC");
+
+       dumphex(stdout, d.d.value, d.d.size);
+      }
+      putchar('\n');
+      break;
+
+    case 'i':;
+      struct hidraw_devinfo di;
+      r= ioctl(0, HIDIOCGRAWINFO, &di);
+      if (r) ERR("HIDIOCGRAWINFO");
+      printf("%08"PRIx32" %04"PRIx16" %04"PRIx16"\n",
+            di.bustype, di.vendor, di.product);
+      break;
+      
+    case 'n':;
+      unsigned char buf[PATH_MAX];
+      r= ioctl(0, HIDIOCGRAWNAME(PATH_MAX), buf);
+      if (r<0) ERR("HIDIOCGRAWNAME");
+      printf("%d %.*s\n", r, r,buf);
+      break;
+
+    case 'p':
+      r= ioctl(0, HIDIOCGRAWPHYS(PATH_MAX), buf);
+      if (r<0) ERR("HIDIOCGRAWPHYS");
+      printf("%d %.*s\n", r, r,buf);
+      break;
+
+    default:
+      badusage("unknown option");
+    }
+
+  next_opt:;
+    if (ferror(stdout) || fflush(stdout))
+      diee("write/flush stdout");
+  }
 
-  return 0;
+  return e;
 }