'!' replaces '/' in the sysfs paths of older drivers, so properly
reverse that to get correct paths.
While we're here, reduce the duplication of initialization.

While this is enough for some drivers, it won't get 'input/' stuff
in the right folder.
---
It may seem hard to test this, but you just have to replace sysfs with
a fake one; for example,
 mkdir -p sys/class/block 'sys/block/rd!0' dev
 echo '1:0' >'sys/block/rd!0/dev'
#put sh and toybox into ./bin and chroot in
 toybox mdev -s
# check that dev/rd/0 exists and has the right mode

I'm guessing that the simplest way to deal with moving input is via
  if (strstr(path, "input/"))
but I'm wondering whether it would be better to do that or to add
support for Busybox-style 
regex  owner:group  mode  [=>]path

where >path means "move to path and leave a symlink in the old place"
and =path means "move to path".



 toys/pending/mdev.c | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/toys/pending/mdev.c b/toys/pending/mdev.c
index 0c49633..a13a53d 100644
--- a/toys/pending/mdev.c
+++ b/toys/pending/mdev.c
@@ -35,7 +35,7 @@ config MDEV_CONF
 static void make_device(char *path)
 {
   char *device_name = NULL, *s, *temp;
-  int major, minor, type, len, fd;
+  int major = 0, minor = 0, type, len, fd;
   int mode = 0660;
   uid_t uid = 0;
   gid_t gid = 0;
@@ -46,24 +46,21 @@ static void make_device(char *path)
     temp = strrchr(path, '/');
     fd = open(path, O_RDONLY);
     *temp=0;
-    temp = toybuf;
-    len = read(fd, temp, 64);
+    len = read(fd, toybuf, 64);
     close(fd);
     if (len<1) return;
-    temp[len] = 0;
+    toybuf[len] = 0;
 
     // Determine device type, major and minor
 
     type = path[5]=='c' ? S_IFCHR : S_IFBLK;
-    major = minor = 0;
-    sscanf(temp, "%u:%u", &major, &minor);
+    sscanf(toybuf, "%u:%u", &major, &minor);
   } else {
     // if (!path), do hotplug
 
     if (!(temp = getenv("SUBSYSTEM")))
       return;
     type = strcmp(temp, "block") ? S_IFCHR : S_IFBLK;
-    major = minor = 0;
     if (!(temp = getenv("MAJOR")))
       return;
     sscanf(temp, "%u", &major);
@@ -74,11 +71,15 @@ static void make_device(char *path)
     device_name = getenv("DEVNAME");
     if (!path)
       return;
-    temp = toybuf;
   }
   if (!device_name)
     device_name = strrchr(path, '/') + 1;
 
+  // as in linux/drivers/base/core.c, device_get_devnode()
+  while ((temp = strchr(device_name, '!'))) {
+    *temp = '/';
+  }
+
   // If we have a config file, look up permissions for this device
 
   if (CFG_MDEV_CONF) {
@@ -185,22 +186,22 @@ found_device:
     }
   }
 
-  sprintf(temp, "/dev/%s", device_name);
+  sprintf(toybuf, "/dev/%s", device_name);
 
-  if (getenv("ACTION") && !strcmp(getenv("ACTION"), "remove")) {
-    unlink(temp);
+  if ((temp=getenv("ACTION")) && !strcmp(temp, "remove")) {
+    unlink(toybuf);
     return;
   }
 
   if (strchr(device_name, '/'))
-    mkpathat(AT_FDCWD, temp, 0, 2);
-  if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST)
-    perror_exit("mknod %s failed", temp);
+    mkpathat(AT_FDCWD, toybuf, 0, 2);
+  if (mknod(toybuf, mode | type, makedev(major, minor)) && errno != EEXIST)
+    perror_exit("mknod %s failed", toybuf);
 
  
-  if (type == S_IFBLK) close(open(temp, O_RDONLY)); // scan for partitions
+  if (type == S_IFBLK) close(open(toybuf, O_RDONLY)); // scan for partitions
 
-  if (CFG_MDEV_CONF) mode=chown(temp, uid, gid);
+  if (CFG_MDEV_CONF) mode=chown(toybuf, uid, gid);
 }
 
 static int callback(struct dirtree *node)
-- 
2.5.0

_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to