projects
/
oweals
/
busybox.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
This directory was fallout from the great feature freeze of 2003, which led
[oweals/busybox.git]
/
util-linux
/
mdev.c
diff --git
a/util-linux/mdev.c
b/util-linux/mdev.c
index aef84ac458204fbe5ab0d62f4684951d6ea9c18e..73a82314c3cf3ef572ffcdf7b697898c83c2c06f 100644
(file)
--- a/
util-linux/mdev.c
+++ b/
util-linux/mdev.c
@@
-16,6
+16,7
@@
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
@@
-27,6
+28,13
@@
#include <busybox.h>
#include <busybox.h>
+struct mdev_globals
+{
+ int root_major, root_minor;
+} mdev_globals;
+
+#define bbg mdev_globals
+
/* mknod in /dev based on a path like "/sys/block/hda/hda1" */
static void make_device(char *path)
{
/* mknod in /dev based on a path like "/sys/block/hda/hda1" */
static void make_device(char *path)
{
@@
-35,23
+43,25
@@
static void make_device(char *path)
int mode = 0660;
uid_t uid = 0;
gid_t gid = 0;
int mode = 0660;
uid_t uid = 0;
gid_t gid = 0;
+ char *temp = path + strlen(path);
- RESERVE_CONFIG_BUFFER(temp, PATH_MAX);
+ /* Try to read major/minor string. Note that the kernel puts \n after
+ * the data, so we don't need to worry about null terminating the string
+ * because sscanf() will stop at the first nondigit, which \n is. We
+ * also depend on path having writeable space after it. */
- /* Try to read major/minor string */
-
- snprintf(temp, PATH_MAX, "%s/dev", path);
- fd = open(temp, O_RDONLY);
- len = read(fd, temp, PATH_MAX-1);
+ strcat(path, "/dev");
+ fd = open(path, O_RDONLY);
+ len = read(fd, temp + 1, 64);
+ *temp++ = 0;
close(fd);
close(fd);
- if (len < 1)
goto end
;
+ if (len < 1)
return
;
/* Determine device name, type, major and minor */
device_name = strrchr(path, '/') + 1;
/* Determine device name, type, major and minor */
device_name = strrchr(path, '/') + 1;
- type = strncmp(path+5, "block/", 6) ? S_IFCHR : S_IFBLK;
- if (sscanf(temp, "%d:%d", &major, &minor) != 2)
- goto end;
+ type = path[5]=='c' ? S_IFCHR : S_IFBLK;
+ if (sscanf(temp, "%d:%d", &major, &minor) != 2) return;
/* If we have a config file, look up permissions for this device */
/* If we have a config file, look up permissions for this device */
@@
-164,15
+174,14
@@
found_device:
}
}
}
}
- sprintf(temp, "%s/%s", DEV_PATH, device_name);
umask(0);
umask(0);
- if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST)
- bb_perror_msg_and_die("mknod %s failed", temp);
-
- if (ENABLE_FEATURE_MDEV_CONF) chown(temp,uid,gid);
+ if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST)
+ bb_perror_msg_and_die("mknod %s failed", device_name);
-end:
- RELEASE_CONFIG_BUFFER(temp);
+ if (major==bbg.root_major && minor==bbg.root_minor)
+ symlink(device_name, "root");
+
+ if (ENABLE_FEATURE_MDEV_CONF) chown(device_name, uid, gid);
}
/* Recursive search of /sys/block or /sys/class. path must be a writeable
}
/* Recursive search of /sys/block or /sys/class. path must be a writeable
@@
-188,16
+197,18
@@
static void find_dev(char *path)
return;
while ((entry = readdir(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;
/* Skip "." and ".." (also skips hidden files, which is ok) */
if (entry->d_name[0] == '.')
continue;
- if (entry->d_type == DT_DIR) {
- snprintf(path+len, PATH_MAX-len, "/%s", entry->d_name);
- find_dev(path);
- }
+ // uClibc doesn't fill out entry->d_type reliably. so we use lstat().
+
+ 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 there's a dev entry, mknod it */
@@
-213,9
+224,16
@@
int mdev_main(int argc, char *argv[])
char *env_path;
RESERVE_CONFIG_BUFFER(temp,PATH_MAX);
char *env_path;
RESERVE_CONFIG_BUFFER(temp,PATH_MAX);
+ bb_xchdir(DEV_PATH);
+
/* Scan */
if (argc == 2 && !strcmp(argv[1],"-s")) {
/* Scan */
if (argc == 2 && !strcmp(argv[1],"-s")) {
+ struct stat st;
+
+ stat("/", &st); // If this fails, we have bigger problems.
+ 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");
strcpy(temp,"/sys/block");
find_dev(temp);
strcpy(temp,"/sys/class");
@@
-233,8
+251,7
@@
int mdev_main(int argc, char *argv[])
sprintf(temp, "/sys%s", env_path);
make_device(temp);
} else if (!strcmp(action, "remove")) {
sprintf(temp, "/sys%s", env_path);
make_device(temp);
} else if (!strcmp(action, "remove")) {
- sprintf(temp, "%s/%s", DEV_PATH, strrchr(env_path, '/') + 1);
- unlink(temp);
+ unlink(strrchr(env_path, '/') + 1);
}
}
}
}