OSDN Git Service

Update mdev to work around the newest sysfs api breakage in the 2.6.25 kernel.
authorRob Landley <rob@landley.net>
Mon, 12 May 2008 05:52:27 +0000 (00:52 -0500)
committerRob Landley <rob@landley.net>
Mon, 12 May 2008 05:52:27 +0000 (00:52 -0500)
(Yeah, I know sysfs hasn't actually got an API, but I like to pretend...)

lib/dirtree.c
lib/lib.c
lib/lib.h
toys/mdev.c
toys/toysh.c

index 45ee139..a695bb3 100644 (file)
@@ -58,6 +58,7 @@ struct dirtree *dirtree_read(char *path, struct dirtree *parent,
 
        if (!(dir = opendir(path))) perror_msg("No %s", path);
        else for (;;) {
+               int norecurse = 0;
                struct dirent *entry = readdir(dir);
                if (!entry) {
                        closedir(dir);
@@ -74,8 +75,9 @@ struct dirtree *dirtree_read(char *path, struct dirtree *parent,
                *ddt = dirtree_add_node(path);
                if (!*ddt) continue;
                (*ddt)->parent = parent;
-               if (callback) callback(path, *ddt);
-               if (entry->d_type == DT_DIR)
+               (*ddt)->depth = parent ? parent->depth + 1 : 1;
+               if (callback) norecurse = callback(path, *ddt);
+               if (!norecurse && entry->d_type == DT_DIR)
                        (*ddt)->child = dirtree_read(path, *ddt, callback);
                if (callback) free(*ddt);
                else ddt = &((*ddt)->next);
index 6102e1b..0e3fe02 100644 (file)
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -326,6 +326,11 @@ char *xabspath(char *path)
        return path;
 }
 
+void xchdir(char *path)
+{
+       if (chdir(path)) error_exit("chdir '%s'");
+}
+
 // Ensure entire path exists.
 // If mode != -1 set permissions on newly created dirs.
 // Requires that path string be writable (for temporary null terminators).
index 8ffd103..f8f52e6 100644 (file)
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -36,6 +36,7 @@ void get_optflags(void);
 struct dirtree {
        struct dirtree *next, *child, *parent;
        struct stat st;
+       int depth;
        char name[];
 };
 
@@ -75,6 +76,7 @@ void xwrite(int fd, void *buf, size_t len);
 char *xgetcwd(void);
 void xstat(char *path, struct stat *st);
 char *xabspath(char *path);
+void xchdir(char *path);
 void xmkpath(char *path, int mode);
 struct string_list *find_in_path(char *path, char *filename);
 void utoa_to_buf(unsigned n, char *buf, unsigned buflen);
index 6e69a77..63c5082 100644 (file)
@@ -2,7 +2,7 @@
  *
  * mdev - Mini udev for busybox
  *
- * Copyright 2005, 2007 Rob Landley <rob@landley.net>
+ * Copyright 2005, 2008 Rob Landley <rob@landley.net>
  * Copyright 2005 Frank Sorenson <frank@tuxrocks.com>
  *
  * Not in SUSv3.
@@ -11,7 +11,7 @@ USE_MDEV(NEWTOY(mdev, "s", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_UMASK))
 
 config MDEV
        bool "mdev"
-       default n
+       default y
        help
          usage: mdev [-s]
 
@@ -21,7 +21,7 @@ config MDEV
 
 config MDEV_CONF
        bool "Configuration file for mdev"
-       default n
+       default y
        depends on MDEV
        help
          The mdev config file (/etc/mdev.conf) contains lines that look like:
@@ -47,8 +47,7 @@ static void make_device(char *path)
 
        // Try to read major/minor string
 
-       temp = path+strlen(path);
-       strcpy(temp, "/dev");
+       temp = strrchr(path, '/');
        fd = open(path, O_RDONLY);
        *temp=0;
        temp++;
@@ -172,49 +171,43 @@ found_device:
        if (CFG_MDEV_CONF) chown(temp, uid, gid);
 }
 
-// Recursive search of /sys/block or /sys/class.  path must be a writeable
-// buffer of size PATH_MAX containing the directory string to start at.
-
-static void find_dev(char *path)
+static int callback(char *path, struct dirtree *node)
 {
-       DIR *dir;
-       int len=strlen(path);
-
-       if (!(dir = opendir(path)))
-               perror_exit("No %s",path);
-
-       for (;;) {
-               struct dirent *entry = readdir(dir);
-
-               if (!entry) break;
-
-               // Skip "." and ".." (also skips hidden files, which is ok)
-
-               if (entry->d_name[0]=='.') continue;
-
-               if (entry->d_type == DT_DIR) {
-                       snprintf(path+len, sizeof(toybuf)-len, "/%s", entry->d_name);
-                       find_dev(path);
-                       path[len] = 0;
-               }
-
-               // If there's a dev entry, mknod it
-
-               if (strcmp(entry->d_name, "dev")) make_device(path);
+       // Entries in /sys/class/block aren't char devices, so skip 'em.  (We'll
+       // get block devices out of /sys/block.)
+       if(!strcmp(node->name, "block")) return 1;
+
+       // Does this directory have a "dev" entry in it?
+       if (S_ISDIR(node->st.st_mode) || S_ISLNK(node->st.st_mode)) {
+               char *dest = path+strlen(path);
+               strcpy(dest, "/dev");
+               if (!access(path, R_OK)) make_device(path);
+               *dest = 0;
        }
 
-       closedir(dir);
+       // Circa 2.6.25 the entries more than 2 deep are all either redundant
+       // (mouse#, event#) or unnamed (every usb_* entry is called "device").
+       return node->depth>1;
 }
 
 void mdev_main(void)
 {
+       // Handle -s
+
        if (toys.optflags) {
-               strcpy(toybuf, "/sys/block");
-               find_dev(toybuf);
+               xchdir("/sys/class");
                strcpy(toybuf, "/sys/class");
-               find_dev(toybuf);
-               return;
+               dirtree_read(toybuf, NULL, callback);
+               strcpy(toybuf+5, "block");
+               dirtree_read(toybuf, NULL, callback);
        }
+//     if (toys.optflags) {
+//             strcpy(toybuf, "/sys/block");
+//             find_dev(toybuf);
+//             strcpy(toybuf, "/sys/class");
+//             find_dev(toybuf);
+//             return;
+//     }
 
        // hotplug support goes here
 }
index 17467fa..d1ef683 100644 (file)
@@ -349,7 +349,7 @@ static void handle(char *command)
 void cd_main(void)
 {
        char *dest = *toys.optargs ? *toys.optargs : getenv("HOME");
-       if (chdir(dest)) error_exit("chdir %s",dest);
+       xchdir(dest);
 }
 
 void exit_main(void)