aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util-linux/mdev.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index ca5eaca48..3b0ef351e 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -14,10 +14,12 @@
struct globals {
int root_major, root_minor;
+ char *subsystem;
};
#define G (*(struct globals*)&bb_common_bufsiz1)
#define root_major (G.root_major)
#define root_minor (G.root_minor)
+#define subsystem (G.subsystem)
/* Prevent infinite loops in /sys symlinks */
#define MAX_SYSFS_DEPTH 3
@@ -111,7 +113,7 @@ static void make_device(char *path, int delete)
/* If we have config file, look up user settings */
while (config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL)) {
regmatch_t off[1 + 9*ENABLE_FEATURE_MDEV_RENAME_REGEXP];
- char *val;
+ char *val = tokens[0];
/* Fields: regex uid:gid mode [alias] [cmd] */
@@ -134,10 +136,15 @@ static void make_device(char *path, int delete)
} else { /* ... or regex to match device name */
regex_t match;
int result;
+ const char *dev_name_or_subsystem = device_name;
+ if ('/' == val[0] && subsystem) {
+ dev_name_or_subsystem = subsystem;
+ val++;
+ }
/* Is this it? */
- xregcomp(&match, tokens[0], REG_EXTENDED);
- result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0);
+ xregcomp(&match, val, REG_EXTENDED);
+ result = regexec(&match, dev_name_or_subsystem, ARRAY_SIZE(off), off, 0);
regfree(&match);
//bb_error_msg("matches:");
@@ -151,7 +158,7 @@ static void make_device(char *path, int delete)
/* If not this device, skip rest of line */
/* (regexec returns whole pattern as "range" 0) */
if (result || off[0].rm_so
- || ((int)off[0].rm_eo != (int)strlen(device_name))
+ || ((int)off[0].rm_eo != (int)strlen(dev_name_or_subsystem))
) {
continue;
}
@@ -276,10 +283,14 @@ static void make_device(char *path, int delete)
#if ENABLE_FEATURE_MDEV_EXEC
if (command) {
/* setenv will leak memory, use putenv/unsetenv/free */
- char *s = xasprintf("MDEV=%s", device_name);
+ char *s = xasprintf("%s=%s", "MDEV", device_name);
+ char *s1 = xasprintf("%s=%s", "SUBSYSTEM", subsystem);
putenv(s);
+ putenv(s1);
if (system(command) == -1)
bb_perror_msg_and_die("can't run '%s'", command);
+ unsetenv("SUBSYSTEM");
+ free(s1);
unsetenv("MDEV");
free(s);
free(command);
@@ -326,6 +337,13 @@ static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM,
void *userData UNUSED_PARAM,
int depth)
{
+ /* Extract device subsystem -- the name of the directory under /sys/class/ */
+ if (1 == depth) {
+ subsystem = strrchr(fileName, '/');
+ if (subsystem)
+ subsystem++;
+ }
+
return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE);
}
@@ -445,13 +463,14 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
char *env_path;
/* Hotplug:
- * env ACTION=... DEVPATH=... [SEQNUM=...] mdev
+ * env ACTION=... DEVPATH=... SUBSYSTEM=... [SEQNUM=...] mdev
* ACTION can be "add" or "remove"
* DEVPATH is like "/block/sda" or "/class/input/mice"
*/
action = getenv("ACTION");
env_path = getenv("DEVPATH");
- if (!action || !env_path)
+ subsystem = getenv("SUBSYSTEM");
+ if (!action || !env_path /*|| !subsystem*/)
bb_show_usage();
fw = getenv("FIRMWARE");