diff options
author | Mike Frysinger <vapier@gentoo.org> | 2008-02-01 09:53:50 +0300 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2008-02-01 09:53:50 +0300 |
commit | f0044c480c4da9c5818fe7a0973cd5529314d14b (patch) | |
tree | 8a1cf64b29dd2cae330a908c7881ed90f06cf545 /util-linux | |
parent | c348e0bc7bb104c9e2385a0d1c29099a7033adf8 (diff) |
add support for renaming/relocating device nodes
Diffstat (limited to 'util-linux')
-rw-r--r-- | util-linux/Config.in | 9 | ||||
-rw-r--r-- | util-linux/mdev.c | 48 |
2 files changed, 52 insertions, 5 deletions
diff --git a/util-linux/Config.in b/util-linux/Config.in index 8ec466bb8..d236b77b6 100644 --- a/util-linux/Config.in +++ b/util-linux/Config.in @@ -301,6 +301,15 @@ config FEATURE_MDEV_CONF For more information, please see docs/mdev.txt +config FEATURE_MDEV_RENAME + bool "Support subdirs/symlinks" + default n + depends on FEATURE_MDEV_CONF + help + Add support for renaming devices and creating symlinks. + + For more information, please see docs/mdev.txt + config FEATURE_MDEV_EXEC bool "Support command execution at device addition/removal" default n diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 65b4da4f4..a18fc0916 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -31,6 +31,10 @@ static void make_device(char *path, int delete) gid_t gid = 0; char *temp = path + strlen(path); char *command = NULL; + char *alias = NULL; + + /* Force the configuration file settings exactly. */ + umask(0); /* 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 @@ -70,7 +74,7 @@ static void make_device(char *path, int delete) ++lineno; /* Three fields: regex, uid:gid, mode */ - for (field = 0; field < (3 + ENABLE_FEATURE_MDEV_EXEC); ++field) { + for (field = 0; field < (3 + ENABLE_FEATURE_MDEV_RENAME + ENABLE_FEATURE_MDEV_EXEC); ++field) { /* Find a non-empty field */ char *val; @@ -131,7 +135,16 @@ static void make_device(char *path, int delete) /* Mode device permissions */ mode = strtoul(val, NULL, 8); - } else if (ENABLE_FEATURE_MDEV_EXEC && field == 3) { + } else if (ENABLE_FEATURE_MDEV_RENAME && field == 3) { + + if (*val != '>') + ++field; + else + alias = xstrdup(val + 1); + + } + + if (ENABLE_FEATURE_MDEV_EXEC && field == 3 + ENABLE_FEATURE_MDEV_RENAME) { /* Optional command to run */ const char *s = "@$*"; @@ -167,20 +180,45 @@ static void make_device(char *path, int delete) end_parse: /* nothing */ ; } - umask(0); if (!delete) { if (sscanf(temp, "%d:%d", &major, &minor) != 2) return; + + if (ENABLE_FEATURE_MDEV_RENAME) + unlink(device_name); + if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST) bb_perror_msg_and_die("mknod %s", device_name); if (major == root_major && minor == root_minor) symlink(device_name, "root"); - if (ENABLE_FEATURE_MDEV_CONF) + if (ENABLE_FEATURE_MDEV_CONF) { chown(device_name, uid, gid); + + if (ENABLE_FEATURE_MDEV_RENAME && alias) { + char *dest; + + temp = strrchr(alias, '/'); + if (temp) { + if (temp[1] != '\0') + /* given a file name, so rename it */ + *temp = '\0'; + bb_make_directory(alias, 0755, FILEUTILS_RECUR); + dest = concat_path_file(alias, device_name); + } else + dest = alias; + + rename(device_name, dest); + symlink(dest, device_name); + + if (alias != dest) + free(alias); + free(dest); + } + } } - if (command) { + if (ENABLE_FEATURE_MDEV_EXEC && command) { /* setenv will leak memory, so use putenv */ char *s = xasprintf("MDEV=%s", device_name); putenv(s); |