Damned. I was too hurry (too much job in same time!). Thanks for noticing.
Heres the correction.
2007/6/13, Mike Frysinger <[EMAIL PROTECTED]>:
On Monday 11 June 2007, Renaud Cerrato wrote:
> Here's the patch correcting mdev, using recursive_action :
>
> We noticed that some devices were not attached to /dev/ using "mdev -s".
> Looking at the source code, the function which walk through the /sys/
tree
> make use of lstat, but the /sys tree can use symlink as seen here :
>
> $ ls -l /sys/class/misc/
> lrwxrwxrwx 1 root root 0 Jan 1 1970 watchdog ->
> ../../devices/platform/at91sam9x_wdt/watchdog
>
> Doing so, the function can't walk through symbolic links. By replacing
> lstat by stat, the problem is corrected.
> To avoid infinite loop, we added a walking through depth limit to 2 (see
> udevstart.c).
almost ... you introduced a little memory corruption there and that's no
good ;)
(notice how make_dev() requires the string be writable and that there be
64
bytes to spare at the end)
but otherwise, recursive_action() is good stuff
try out current svn now please
-mike
diff -Nru busybox-1.4.1_original/util-linux/mdev.c busybox-1.4.1/util-linux/mdev.c
--- busybox-1.4.1_original/util-linux/mdev.c 2007-01-24 22:34:51.000000000 +0100
+++ busybox-1.4.1/util-linux/mdev.c 2007-06-13 11:30:59.643974472 +0200
@@ -14,6 +14,8 @@
#define DEV_PATH "/dev"
+#define MAX_DEPTH 3
+
struct mdev_globals
{
int root_major, root_minor;
@@ -194,41 +196,46 @@
if (delete) unlink(device_name);
}
-/* 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)
+/* File action callback.
+ *
+ */
+static int faction(const char *fileName,
+ struct stat *statbuf,
+ void* userData, int depth)
{
- DIR *dir;
- size_t len = strlen(path);
- struct dirent *entry;
-
- dir = opendir(path);
- if (dir == NULL)
- return;
-
- while ((entry = readdir(dir)) != NULL) {
- struct stat st;
-
- /* Skip "." and ".." (also skips hidden files, which is ok) */
-
- if (entry->d_name[0] == '.')
- continue;
-
- // uClibc doesn't fill out entry->d_type reliably. so we use lstat().
+ char *pt;
+
+ /* Remove path from fileName */
+ pt = strrchr(fileName,'/');
+
+ if(!pt || strcmp(pt, DEV_PATH))
+ return FALSE;
+
+ sprintf(userData,"%.*s",pt-fileName,fileName)
+ make_device(userData, 0);
- snprintf(path+len, PATH_MAX-len, "/%s", entry->d_name);
- if (!lstat(path, &st) && S_ISDIR(st.st_mode)) find_dev(path);
- path[len] = 0;
-
- /* If there's a dev entry, mknod it */
-
- if (!strcmp(entry->d_name, "dev")) make_device(path, 0);
- }
+ return TRUE;
+}
- closedir(dir);
+/* Directory callback.
+ * Should return SKIP to stop traversal.
+ */
+static int daction(const char *fileName,
+ struct stat *statbuf,
+ void* userData, int depth)
+{
+ /* Maximum depth */
+ if(depth>=MAX_DEPTH)
+ return SKIP;
+
+ return TRUE;
}
+/* Recursive search of /sys/block or /sys/class.
+ * The recursive depth is limited to avoid
+ * inifinite loop (circular symlinks)
+ * (see udevstart.c)
+ */
int mdev_main(int argc, char *argv[])
{
char *action;
@@ -245,10 +252,20 @@
xstat("/", &st);
bbg.root_major = major(st.st_dev);
bbg.root_minor = minor(st.st_dev);
- strcpy(temp,"/sys/block");
- find_dev(temp);
- strcpy(temp,"/sys/class");
- find_dev(temp);
+ recursive_action("/sys/block",
+ TRUE, TRUE, /* Recurse, follow links */
+ FALSE, /* no depth first */
+ faction, /* file action callback */
+ daction, /* dir action callback */
+ temp, 0);
+
+ recursive_action("/sys/class",
+ TRUE, TRUE, /* Recurse, follow links */
+ FALSE, /* no depth first */
+ faction, /* file action callback */
+ daction, /* dir action callback */
+ temp, 0);
+
/* Hotplug */
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox