summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtestsuite/mdev.tests17
-rw-r--r--util-linux/Config.in7
-rw-r--r--util-linux/mdev.c44
3 files changed, 65 insertions, 3 deletions
diff --git a/testsuite/mdev.tests b/testsuite/mdev.tests
index 777c5c5..81c440d 100755
--- a/testsuite/mdev.tests
+++ b/testsuite/mdev.tests
@@ -76,6 +76,23 @@ br--r--r-- 1 0 0 sda
" \
"" ""
+# continuing to use directory structure from prev test
+rm -rf mdev.testdir/dev/*
+# here we complicate things by having non-matching group 1 and using %0
+echo "s([0-9])*d([a-z]+) 0:0 644 >sd/%2_%0" >mdev.testdir/etc/mdev.conf
+testing "mdev regexp substring match + replace" \
+ "env - ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1;
+ ls -lnR mdev.testdir/dev | $FILTER_LS2" \
+"\
+mdev.testdir/dev:
+drwxr-xr-x 2 0 0 sd
+lrwxrwxrwx 1 0 0 sda -> sd/a_sda
+
+mdev.testdir/dev/sd:
+brw-r--r-- 1 0 0 a_sda
+" \
+ "" ""
+
# clean up
rm -rf mdev.testdir
diff --git a/util-linux/Config.in b/util-linux/Config.in
index 1f4322b..869ec61 100644
--- a/util-linux/Config.in
+++ b/util-linux/Config.in
@@ -321,6 +321,13 @@ config FEATURE_MDEV_RENAME
For more information, please see docs/mdev.txt
+config FEATURE_MDEV_RENAME_REGEXP
+ bool "Support regular expressions substitutions when renaming device"
+ default n
+ depends on FEATURE_MDEV_RENAME
+ help
+ Add support for regular expressions substitutions when renaming device.
+
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 c8d603b..9d77f6a 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -84,6 +84,8 @@ static void make_device(char *path, int delete)
goto end_parse;
while ((line = xmalloc_fgetline(fp)) != NULL) {
+ regmatch_t off[1+9*ENABLE_FEATURE_MDEV_RENAME_REGEXP];
+
++lineno;
trim(line);
if (!line[0])
@@ -95,16 +97,24 @@ static void make_device(char *path, int delete)
next = next_field(line);
{
regex_t match;
- regmatch_t off;
int result;
/* Is this it? */
xregcomp(&match, line, REG_EXTENDED);
- result = regexec(&match, device_name, 1, &off, 0);
+ result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0);
regfree(&match);
+ //bb_error_msg("matches:");
+ //for (int i = 0; i < ARRAY_SIZE(off); i++) {
+ // if (off[i].rm_so < 0) continue;
+ // bb_error_msg("match %d: '%.*s'\n", i,
+ // (int)(off[i].rm_eo - off[i].rm_so),
+ // device_name + off[i].rm_so);
+ //}
+
/* If not this device, skip rest of line */
- if (result || off.rm_so || off.rm_eo != strlen(device_name))
+ /* (regexec returns whole pattern as "range" 0) */
+ if (result || off[0].rm_so || off[0].rm_eo != strlen(device_name))
goto next_line;
}
@@ -152,7 +162,35 @@ static void make_device(char *path, int delete)
val = next;
next = next_field(val);
if (*val == '>') {
+#if ENABLE_FEATURE_MDEV_RENAME_REGEXP
+ /* substitute %1..9 with off[1..9], if any */
+ char *s, *p;
+ unsigned i, n;
+
+ n = 0;
+ s = val;
+ while (*s && *s++ == '%')
+ n++;
+
+ p = alias = xzalloc(strlen(val) + n * strlen(device_name));
+ s = val + 1;
+ while (*s) {
+ *p = *s;
+ if ('%' == *s) {
+ i = (s[1] - '0');
+ if (i <= 9 && off[i].rm_so >= 0) {
+ n = off[i].rm_eo - off[i].rm_so;
+ strncpy(p, device_name + off[i].rm_so, n);
+ p += n - 1;
+ s++;
+ }
+ }
+ p++;
+ s++;
+ }
+#else
alias = xstrdup(val + 1);
+#endif
}
}