chiark / gitweb /
New --expect-sysfs option for evdev-manip
authorian <ian>
Fri, 6 Jun 2008 19:59:09 +0000 (19:59 +0000)
committerian <ian>
Fri, 6 Jun 2008 19:59:09 +0000 (19:59 +0000)
hostside/evdev-manip.c

index 886460a0a324bf8683cf7e5e476cf5a366e1015f..7d3c31a6413c878f3c26b45920a7fad25d81f732 100644 (file)
@@ -3,6 +3,7 @@
  *  options:
  *     --dump          default
  *     --[no-]grab     --nograb is default
+ *     --expect-sysfs /sys/class/input/inputX/eventY/dev
  */
 
 #include "common.h"
@@ -33,6 +34,7 @@ static Device *devices;
 
 static Mode mode;
 static int grab;
+static const char *expect_sysfs;
 
 static void pr_hex(unsigned long value) { printf("%#lx",value); }
 
@@ -160,6 +162,39 @@ static void mainloop(void) {
 
 static const ModeInfo mode_dump= { dump_event, dump_died, mainloop };
 
+static void check_expect_sysfs(int fd, const char *path, const char *efn) {
+  char buf[50], *ep;
+  unsigned long maj, min;
+  struct stat stab;
+  FILE *sysfs;
+  int r;
+    
+  r= fstat(fd, &stab);  if (r) diee("%s: fstat failed", path);
+  if (!S_ISCHR(stab.st_mode)) die("%s: not a character device", path);
+    
+  sysfs= fopen(efn,"r");
+  if (!sysfs) diee("%s: failed to open sysfs %s", path, efn);
+  if (!fgets(buf,sizeof(buf)-1,sysfs)) {
+    if (ferror(sysfs)) diee("%s: failed to read sysfs %s", path, efn);
+    assert(feof(sysfs)); die("%s: eof on sysfs %s", path, efn);
+  }
+  buf[sizeof(buf)-1]= 0;
+  errno=0; maj=strtoul(buf,&ep,0);
+  if (errno || *ep!=':') die("%s: bad major number or no colon in sysfs"
+                            " dev file %s", path, efn);
+  errno=0; min=strtoul(ep+1,&ep,0);
+  if (errno || *ep!='\n') die("%s: bad minor number or no colon in sysfs"
+                             " dev file %s", path, efn);
+
+  if (maj != major(stab.st_rdev) || min != minor(stab.st_rdev))
+    die("%s: is %lu:%lu, expected %lu:%lu", path,
+       (unsigned long)major(stab.st_rdev),
+       (unsigned long)minor(stab.st_rdev),
+       maj, min);
+
+  if (fclose(sysfs)) die("%s: failed to close sysfs %s", path, efn);
+}
+
 static void getdevice(const char *path) {
   int r;
   struct input_id iid;
@@ -171,6 +206,11 @@ static void getdevice(const char *path) {
   d->path= mstrdup(path);
   d->fd= open(path, O_RDONLY);  if (d->fd<0) diee("%s: failed to open",path);
 
+  if (expect_sysfs) {
+    check_expect_sysfs(d->fd, path, expect_sysfs);
+    expect_sysfs= 0;
+  }
+
   r= ioctl(d->fd, EVIOCGID, &iid);  if (r) diee("%s: failed to get id",path);
   printf("device %s bustype ", path);
   PR_TABLE_STR(bus, iid.bustype);
@@ -191,6 +231,9 @@ int main(int argc, const char **argv) {
     if (arg[0] != '-') {
       getdevice(arg);
     }
+    else if (!strcmp(arg,"--expect-sysfs")) {
+      if (!(expect_sysfs= *++argv)) badusage("missing arg for --expect-sysfs");
+    }
     else if (!strcmp(arg,"--dump")) { mode= &mode_dump; }
     else if (!strcmp(arg,"--grab")) { grab= 1; }
     else if (!strcmp(arg,"--no-grab")) { grab= 0; }