diff options
author | Aaro Koskinen | 2019-02-08 16:30:24 +0100 |
---|---|---|
committer | Denys Vlasenko | 2019-02-08 16:52:51 +0100 |
commit | c89764c0633670ef28166c70d03bc593f4a1179f (patch) | |
tree | 6e109bae5a6fb5979d4ad754ef199031b1fd09b1 /procps/sysctl.c | |
parent | 78301861ef9e8d0edc72898712dbce7d793150a8 (diff) | |
download | busybox-c89764c0633670ef28166c70d03bc593f4a1179f.zip busybox-c89764c0633670ef28166c70d03bc593f4a1179f.tar.gz |
sysctl: fix compatibility with procps sysctl
Busybox sysctl is incompatible with procps when '.' appears in
directory name, mostly happens with VLANs.
busybox syntax (since 2008): net.ipv4.conf.eth0.100.mc_forwarding
procps syntax (since 2002): net.ipv4.conf.eth0/100.mc_forwarding
(supported by both: net/ipv4/conf/eth0.100/mc_forwarding)
Use procps syntax for output; for input, allow both.
function old new delta
sysctl_dots_to_slashes 86 143 +57
sysctl_act_on_setting 443 453 +10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 67/0) Total: 67 bytes
Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'procps/sysctl.c')
-rw-r--r-- | procps/sysctl.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/procps/sysctl.c b/procps/sysctl.c index 5303460..6d77185 100644 --- a/procps/sysctl.c +++ b/procps/sysctl.c @@ -56,9 +56,32 @@ enum { static void sysctl_dots_to_slashes(char *name) { - char *cptr, *last_good, *end; + char *cptr, *last_good, *end, *slash; char end_ch; + end = strchrnul(name, '='); + + slash = strchrnul(name, '/'); + if (slash < end + && strchrnul(name, '.') < slash + ) { + /* There are both dots and slashes, and 1st dot is + * before 1st slash. + * (IOW: not raw, unmangled a/b/c.d format) + * + * procps supports this syntax for names with dots: + * net.ipv4.conf.eth0/100.mc_forwarding + * (dots and slashes are simply swapped) + */ + while (end != name) { + end--; + if (*end == '.') *end = '/'; + else if (*end == '/') *end = '.'; + } + return; + } + /* else: use our old behavior: */ + /* Convert minimum number of '.' to '/' so that * we end up with existing file's name. * @@ -77,7 +100,6 @@ static void sysctl_dots_to_slashes(char *name) * * To set up testing: modprobe 8021q; vconfig add eth0 100 */ - end = strchrnul(name, '='); end_ch = *end; *end = '.'; /* trick the loop into trying full name too */ @@ -114,6 +136,8 @@ static int sysctl_act_on_setting(char *setting) while (*cptr) { if (*cptr == '/') *cptr = '.'; + else if (*cptr == '.') + *cptr = '/'; cptr++; } |