aboutsummaryrefslogtreecommitdiff
path: root/util-linux/mdev.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2007-06-13 09:24:50 +0000
committerMike Frysinger <vapier@gentoo.org>2007-06-13 09:24:50 +0000
commitb51fd3525e48c79ef9e854dd357a9cdfdfeef72b (patch)
tree9c26f4fa46961b3cca2a0eda7d0c6e1e4cd28dd5 /util-linux/mdev.c
parenta78ef2ccf14a0b3bc50b8fd8fd3239ca1385ee2b (diff)
downloadbusybox-w32-b51fd3525e48c79ef9e854dd357a9cdfdfeef72b.tar.gz
busybox-w32-b51fd3525e48c79ef9e854dd357a9cdfdfeef72b.tar.bz2
busybox-w32-b51fd3525e48c79ef9e854dd357a9cdfdfeef72b.zip
as suggested by Renaud Cerrato and Souf, switch over to recursive_action() for some nice shrinkage and so we work even when CONFIG_SYSFS_DEPRECATED is off
Diffstat (limited to 'util-linux/mdev.c')
-rw-r--r--util-linux/mdev.c59
1 files changed, 27 insertions, 32 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 8e5b8a94b..fca4fd052 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -19,6 +19,8 @@ struct globals {
19#define root_major (G.root_major) 19#define root_major (G.root_major)
20#define root_minor (G.root_minor) 20#define root_minor (G.root_minor)
21 21
22#define MAX_SYSFS_DEPTH 3 /* prevent infinite loops in /sys symlinks */
23
22/* mknod in /dev based on a path like "/sys/block/hda/hda1" */ 24/* mknod in /dev based on a path like "/sys/block/hda/hda1" */
23static void make_device(char *path, int delete) 25static void make_device(char *path, int delete)
24{ 26{
@@ -191,39 +193,28 @@ static void make_device(char *path, int delete)
191 if (delete) unlink(device_name); 193 if (delete) unlink(device_name);
192} 194}
193 195
194/* Recursive search of /sys/block or /sys/class. path must be a writeable 196/* File callback for /sys/ traversal */
195 * buffer of size PATH_MAX containing the directory string to start at. */ 197static int fileAction(const char *fileName, struct stat *statbuf,
196 198 void *userData, int depth)
197static void find_dev(char *path)
198{ 199{
199 DIR *dir; 200 size_t len = strlen(fileName) - 4;
200 size_t len = strlen(path); 201 char *scratch = userData;
201 struct dirent *entry;
202
203 dir = opendir(path);
204 if (dir == NULL)
205 return;
206
207 while ((entry = readdir(dir)) != NULL) {
208 struct stat st;
209
210 /* Skip "." and ".." (also skips hidden files, which is ok) */
211
212 if (entry->d_name[0] == '.')
213 continue;
214 202
215 // uClibc doesn't fill out entry->d_type reliably. so we use lstat(). 203 if (strcmp(fileName + len, "/dev"))
204 return FALSE;
216 205
217 snprintf(path+len, PATH_MAX-len, "/%s", entry->d_name); 206 strcpy(scratch, fileName);
218 if (!lstat(path, &st) && S_ISDIR(st.st_mode)) find_dev(path); 207 scratch[len] = 0;
219 path[len] = 0; 208 make_device(scratch, 0);
220 209
221 /* If there's a dev entry, mknod it */ 210 return TRUE;
222 211}
223 if (!strcmp(entry->d_name, "dev")) make_device(path, 0);
224 }
225 212
226 closedir(dir); 213/* Directory callback for /sys/ traversal */
214static int dirAction(const char *fileName, struct stat *statbuf,
215 void *userData, int depth)
216{
217 return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE);
227} 218}
228 219
229/* For the full gory details, see linux/Documentation/firmware_class/README 220/* For the full gory details, see linux/Documentation/firmware_class/README
@@ -308,10 +299,14 @@ int mdev_main(int argc, char **argv)
308 xstat("/", &st); 299 xstat("/", &st);
309 root_major = major(st.st_dev); 300 root_major = major(st.st_dev);
310 root_minor = minor(st.st_dev); 301 root_minor = minor(st.st_dev);
311 strcpy(temp,"/sys/block"); 302
312 find_dev(temp); 303 recursive_action("/sys/block",
313 strcpy(temp,"/sys/class"); 304 ACTION_RECURSE | ACTION_FOLLOWLINKS,
314 find_dev(temp); 305 fileAction, dirAction, temp, 0);
306
307 recursive_action("/sys/class",
308 ACTION_RECURSE | ACTION_FOLLOWLINKS,
309 fileAction, dirAction, temp, 0);
315 310
316 /* Hotplug */ 311 /* Hotplug */
317 312