mdev: add "!" syntax support

Based on the patch by Steve Bennett <steveb@workware.net.au>

function                                             old     new   delta
make_device                                         1640    1673     +33

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2010-04-02 06:47:14 +02:00
parent 5342c3f310
commit b38af7bd31
2 changed files with 42 additions and 23 deletions

View File

@ -51,8 +51,8 @@ device nodes if your system needs something more than the default root/root
660 permissions. 660 permissions.
The file has the format: The file has the format:
<device regex> <uid>:<gid> <octal permissions> <device regex> <uid>:<gid> <permissions>
or @<maj[,min1[-min2]]> <uid>:<gid> <octal permissions> or @<maj[,min1[-min2]]> <uid>:<gid> <permissions>
For example: For example:
hd[a-z][0-9]* 0:3 660 hd[a-z][0-9]* 0:3 660
@ -63,7 +63,7 @@ create your own total match like so:
.* 1:1 777 .* 1:1 777
You can rename/move device nodes by using the next optional field. You can rename/move device nodes by using the next optional field.
<device regex> <uid>:<gid> <octal permissions> [=path] <device regex> <uid>:<gid> <permissions> [=path]
So if you want to place the device node into a subdirectory, make sure the path So if you want to place the device node into a subdirectory, make sure the path
has a trailing /. If you want to rename the device node, just place the name. has a trailing /. If you want to rename the device node, just place the name.
hda 0:3 660 =drives/ hda 0:3 660 =drives/
@ -74,11 +74,17 @@ This will rename "hdb" to "cdrom".
Similarly, ">path" renames/moves the device but it also creates Similarly, ">path" renames/moves the device but it also creates
a direct symlink /dev/DEVNAME to the renamed/moved device. a direct symlink /dev/DEVNAME to the renamed/moved device.
You can also prevent creation of device nodes with the 4th field as "!":
tty[a-z]. 0:0 660 !
pty[a-z]. 0:0 660 !
If you also enable support for executing your own commands, then the file has If you also enable support for executing your own commands, then the file has
the format: the format:
<device regex> <uid>:<gid> <octal permissions> [=path] [@|$|*<command>] <device regex> <uid>:<gid> <permissions> [=path] [@|$|*<command>]
or or
<device regex> <uid>:<gid> <octal permissions> [>path] [@|$|*<command>] <device regex> <uid>:<gid> <permissions> [>path] [@|$|*<command>]
or
<device regex> <uid>:<gid> <permissions> [!] [@|$|*<command>]
For example: For example:
---8<--- ---8<---

View File

@ -204,7 +204,8 @@ static void make_device(char *path, int delete)
if (major < 0) if (major < 0)
continue; /* no dev, no match */ continue; /* no dev, no match */
sc = sscanf(val, "@%u,%u-%u", &cmaj, &cmin0, &cmin1); sc = sscanf(val, "@%u,%u-%u", &cmaj, &cmin0, &cmin1);
if (sc < 1 || major != cmaj if (sc < 1
|| major != cmaj
|| (sc == 2 && minor != cmin0) || (sc == 2 && minor != cmin0)
|| (sc == 3 && (minor < cmin0 || minor > cmin1)) || (sc == 3 && (minor < cmin0 || minor > cmin1))
) { ) {
@ -243,7 +244,8 @@ static void make_device(char *path, int delete)
/* If no match, skip rest of line */ /* If no match, skip rest of line */
/* (regexec returns whole pattern as "range" 0) */ /* (regexec returns whole pattern as "range" 0) */
if (result || off[0].rm_so if (result
|| off[0].rm_so
|| ((int)off[0].rm_eo != (int)strlen(str_to_match)) || ((int)off[0].rm_eo != (int)strlen(str_to_match))
) { ) {
continue; /* this line doesn't match */ continue; /* this line doesn't match */
@ -258,28 +260,34 @@ static void make_device(char *path, int delete)
bb_error_msg("unknown user/group %s on line %d", tokens[1], parser->lineno); bb_error_msg("unknown user/group %s on line %d", tokens[1], parser->lineno);
/* 3rd field: mode - device permissions */ /* 3rd field: mode - device permissions */
/* mode = strtoul(tokens[2], NULL, 8); */
bb_parse_mode(tokens[2], &mode); bb_parse_mode(tokens[2], &mode);
val = tokens[3]; val = tokens[3];
/* 4th field (opt): >|=alias */ /* 4th field (opt): ">|=alias" or "!" to not create the node */
if (ENABLE_FEATURE_MDEV_RENAME && val) { if (ENABLE_FEATURE_MDEV_RENAME && val) {
aliaslink = val[0]; char *a, *s, *st;
if (aliaslink == '>' || aliaslink == '=') {
char *a, *s, *st;
char *p;
unsigned i, n;
a = val; a = val;
s = strchrnul(val, ' '); s = strchrnul(val, ' ');
st = strchrnul(val, '\t'); st = strchrnul(val, '\t');
if (st < s) if (st < s)
s = st; s = st;
val = (s[0] && s[1]) ? s+1 : NULL; st = (s[0] && s[1]) ? s+1 : NULL;
aliaslink = a[0];
if (aliaslink == '!' && s == a+1) {
val = st;
/* "!": suppress node creation/deletion */
major = -1;
}
else if (aliaslink == '>' || aliaslink == '=') {
val = st;
s[0] = '\0'; s[0] = '\0';
if (ENABLE_FEATURE_MDEV_RENAME_REGEXP) { if (ENABLE_FEATURE_MDEV_RENAME_REGEXP) {
char *p;
unsigned i, n;
/* substitute %1..9 with off[1..9], if any */ /* substitute %1..9 with off[1..9], if any */
n = 0; n = 0;
s = a; s = a;
@ -323,8 +331,13 @@ static void make_device(char *path, int delete)
/* Are we running this command now? /* Are we running this command now?
* Run $cmd on delete, @cmd on create, *cmd on both * Run $cmd on delete, @cmd on create, *cmd on both
*/ */
if (s2-s != delete) if (s2 - s != delete) {
/* We are here if: '*',
* or: '@' and delete = 0,
* or: '$' and delete = 1
*/
command = xstrdup(val + 1); command = xstrdup(val + 1);
}
} }
} }
@ -368,7 +381,7 @@ static void make_device(char *path, int delete)
free(command); free(command);
} }
if (delete) { if (delete && major >= 0) {
if (ENABLE_FEATURE_MDEV_RENAME && alias) { if (ENABLE_FEATURE_MDEV_RENAME && alias) {
if (aliaslink == '>') if (aliaslink == '>')
unlink(device_name); unlink(device_name);