diff options
67 files changed, 1154 insertions, 523 deletions
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 1 | 1 | VERSION = 1 |
2 | PATCHLEVEL = 26 | 2 | PATCHLEVEL = 26 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 2 |
4 | EXTRAVERSION = .git | 4 | EXTRAVERSION = |
5 | NAME = Unnamed | 5 | NAME = Unnamed |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/Makefile.flags b/Makefile.flags index 6b25632a0..4fb57d7b4 100644 --- a/Makefile.flags +++ b/Makefile.flags | |||
@@ -127,7 +127,7 @@ endif | |||
127 | ifeq ($(CONFIG_PLATFORM_MINGW32),y) | 127 | ifeq ($(CONFIG_PLATFORM_MINGW32),y) |
128 | CFLAGS += -Iwin32 -DHAVE_STRING_H=1 -DHAVE_CONFIG_H=0 -fno-builtin-stpcpy -fno-ident | 128 | CFLAGS += -Iwin32 -DHAVE_STRING_H=1 -DHAVE_CONFIG_H=0 -fno-builtin-stpcpy -fno-ident |
129 | EXEEXT = .exe | 129 | EXEEXT = .exe |
130 | LDLIBS += userenv ws2_32 | 130 | LDLIBS += userenv ws2_32 mingwex -l:libssp.a |
131 | endif | 131 | endif |
132 | 132 | ||
133 | # Android has no separate crypt library | 133 | # Android has no separate crypt library |
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index e1eec6d4b..343aec9bd 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -9,6 +9,12 @@ | |||
9 | 9 | ||
10 | /* lzop_main() uses bbunpack(), need this: */ | 10 | /* lzop_main() uses bbunpack(), need this: */ |
11 | //kbuild:lib-$(CONFIG_LZOP) += bbunzip.o | 11 | //kbuild:lib-$(CONFIG_LZOP) += bbunzip.o |
12 | //kbuild:lib-$(CONFIG_LZOPCAT) += bbunzip.o | ||
13 | //kbuild:lib-$(CONFIG_UNLZOP) += bbunzip.o | ||
14 | /* bzip2_main() too: */ | ||
15 | //kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o | ||
16 | /* gzip_main() too: */ | ||
17 | //kbuild:lib-$(CONFIG_GZIP) += bbunzip.o | ||
12 | 18 | ||
13 | /* Note: must be kept in sync with archival/lzop.c */ | 19 | /* Note: must be kept in sync with archival/lzop.c */ |
14 | enum { | 20 | enum { |
@@ -192,7 +198,10 @@ int FAST_FUNC bbunpack(char **argv, | |||
192 | return exitcode; | 198 | return exitcode; |
193 | } | 199 | } |
194 | 200 | ||
195 | #if ENABLE_UNCOMPRESS || ENABLE_BUNZIP2 || ENABLE_UNLZMA || ENABLE_UNXZ | 201 | #if ENABLE_UNCOMPRESS \ |
202 | || ENABLE_BUNZIP2 || ENABLE_BZCAT \ | ||
203 | || ENABLE_UNLZMA || ENABLE_LZCAT || ENABLE_LZMA \ | ||
204 | || ENABLE_UNXZ || ENABLE_XZCAT || ENABLE_XZ | ||
196 | static | 205 | static |
197 | char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) | 206 | char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) |
198 | { | 207 | { |
diff --git a/archival/dpkg.c b/archival/dpkg.c index df7a0db64..f133299e3 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | //config:config DPKG | 29 | //config:config DPKG |
30 | //config: bool "dpkg" | 30 | //config: bool "dpkg" |
31 | //config: default n | 31 | //config: default y |
32 | //config: select FEATURE_SEAMLESS_GZ | 32 | //config: select FEATURE_SEAMLESS_GZ |
33 | //config: help | 33 | //config: help |
34 | //config: dpkg is a medium-level tool to install, build, remove and manage | 34 | //config: dpkg is a medium-level tool to install, build, remove and manage |
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index 86850469d..ebbc7f035 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | //config:config DPKG_DEB | 8 | //config:config DPKG_DEB |
9 | //config: bool "dpkg_deb" | 9 | //config: bool "dpkg_deb" |
10 | //config: default n | 10 | //config: default y |
11 | //config: select FEATURE_SEAMLESS_GZ | 11 | //config: select FEATURE_SEAMLESS_GZ |
12 | //config: help | 12 | //config: help |
13 | //config: dpkg-deb unpacks and provides information about Debian archives. | 13 | //config: dpkg-deb unpacks and provides information about Debian archives. |
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index b159a786a..ad5c5c42d 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src | |||
@@ -48,16 +48,23 @@ lib-$(CONFIG_CPIO) += get_header_cpio.o | |||
48 | lib-$(CONFIG_TAR) += get_header_tar.o unsafe_prefix.o | 48 | lib-$(CONFIG_TAR) += get_header_tar.o unsafe_prefix.o |
49 | lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o | 49 | lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o |
50 | lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | 50 | lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o |
51 | lib-$(CONFIG_UNLZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | ||
52 | lib-$(CONFIG_LZOPCAT) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | ||
51 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o | 53 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o |
52 | lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o | 54 | lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o |
55 | lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o | ||
53 | lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o | 56 | lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o |
57 | lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o | ||
58 | lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o | ||
54 | lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o | 59 | lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o |
60 | lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o | ||
61 | lib-$(CONFIG_XZ) += open_transformer.o decompress_unxz.o | ||
55 | lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o | 62 | lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o |
63 | lib-$(CONFIG_ZCAT) += open_transformer.o decompress_gunzip.o | ||
56 | lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o | 64 | lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o |
57 | lib-$(CONFIG_UNZIP) += open_transformer.o decompress_gunzip.o unsafe_prefix.o | 65 | lib-$(CONFIG_UNZIP) += open_transformer.o decompress_gunzip.o unsafe_prefix.o |
58 | lib-$(CONFIG_RPM2CPIO) += open_transformer.o decompress_gunzip.o get_header_cpio.o | 66 | lib-$(CONFIG_RPM2CPIO) += open_transformer.o decompress_gunzip.o get_header_cpio.o |
59 | lib-$(CONFIG_RPM) += open_transformer.o decompress_gunzip.o get_header_cpio.o | 67 | lib-$(CONFIG_RPM) += open_transformer.o decompress_gunzip.o get_header_cpio.o |
60 | |||
61 | lib-$(CONFIG_GZIP) += open_transformer.o | 68 | lib-$(CONFIG_GZIP) += open_transformer.o |
62 | lib-$(CONFIG_BZIP2) += open_transformer.o | 69 | lib-$(CONFIG_BZIP2) += open_transformer.o |
63 | lib-$(CONFIG_LZOP) += open_transformer.o | 70 | lib-$(CONFIG_LZOP) += open_transformer.o |
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig index 35e7b1297..5801e26a2 100644 --- a/configs/mingw32_defconfig +++ b/configs/mingw32_defconfig | |||
@@ -997,6 +997,7 @@ CONFIG_PS=y | |||
997 | # CONFIG_FEATURE_RUNSVDIR_LOG is not set | 997 | # CONFIG_FEATURE_RUNSVDIR_LOG is not set |
998 | # CONFIG_SV is not set | 998 | # CONFIG_SV is not set |
999 | CONFIG_SV_DEFAULT_SERVICE_DIR="" | 999 | CONFIG_SV_DEFAULT_SERVICE_DIR="" |
1000 | # CONFIG_SVC is not set | ||
1000 | # CONFIG_SVLOGD is not set | 1001 | # CONFIG_SVLOGD is not set |
1001 | # CONFIG_CHCON is not set | 1002 | # CONFIG_CHCON is not set |
1002 | # CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set | 1003 | # CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set |
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig index a5051285b..558c07d56 100644 --- a/configs/mingw64_defconfig +++ b/configs/mingw64_defconfig | |||
@@ -997,6 +997,7 @@ CONFIG_PS=y | |||
997 | # CONFIG_FEATURE_RUNSVDIR_LOG is not set | 997 | # CONFIG_FEATURE_RUNSVDIR_LOG is not set |
998 | # CONFIG_SV is not set | 998 | # CONFIG_SV is not set |
999 | CONFIG_SV_DEFAULT_SERVICE_DIR="" | 999 | CONFIG_SV_DEFAULT_SERVICE_DIR="" |
1000 | # CONFIG_SVC is not set | ||
1000 | # CONFIG_SVLOGD is not set | 1001 | # CONFIG_SVLOGD is not set |
1001 | # CONFIG_CHCON is not set | 1002 | # CONFIG_CHCON is not set |
1002 | # CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set | 1003 | # CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set |
diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src index 8e2c097a3..d9a448781 100644 --- a/coreutils/Kbuild.src +++ b/coreutils/Kbuild.src | |||
@@ -10,12 +10,16 @@ lib-y:= | |||
10 | 10 | ||
11 | INSERT | 11 | INSERT |
12 | 12 | ||
13 | lib-$(CONFIG_MORE) += cat.o # more uses it if stdout isn't a tty | 13 | lib-$(CONFIG_MORE) += cat.o # more uses it if stdout isn't a tty |
14 | lib-$(CONFIG_LESS) += cat.o # less too | 14 | lib-$(CONFIG_LESS) += cat.o # less too |
15 | lib-$(CONFIG_CRONTAB) += cat.o # crontab -l | 15 | lib-$(CONFIG_CRONTAB) += cat.o # crontab -l |
16 | lib-$(CONFIG_ADDUSER) += chown.o # used by adduser | 16 | lib-$(CONFIG_ADDUSER) += chown.o # used by adduser |
17 | lib-$(CONFIG_ADDGROUP) += chown.o # used by adduser | 17 | lib-$(CONFIG_ADDGROUP) += chown.o # used by adduser |
18 | lib-$(CONFIG_ASH) += echo.o # used by ash | 18 | lib-$(CONFIG_ASH) += echo.o # used by ash |
19 | lib-$(CONFIG_HUSH) += echo.o # used by hush | 19 | lib-$(CONFIG_SH_IS_ASH) += echo.o # used by ash |
20 | lib-$(CONFIG_FTPD) += ls.o # used by ftpd | 20 | lib-$(CONFIG_BASH_IS_ASH) += echo.o # used by ash |
21 | lib-$(CONFIG_HUSH) += echo.o # used by hush | ||
22 | lib-$(CONFIG_SH_IS_HUSH) += echo.o # used by hush | ||
23 | lib-$(CONFIG_BASH_IS_HUSH) += echo.o # used by hush | ||
24 | lib-$(CONFIG_FTPD) += ls.o # used by ftpd | ||
21 | lib-$(CONFIG_ASH_BUILTIN_PRINTF) += printf.o | 25 | lib-$(CONFIG_ASH_BUILTIN_PRINTF) += printf.o |
diff --git a/coreutils/df.c b/coreutils/df.c index fdcdae675..79e4c4670 100644 --- a/coreutils/df.c +++ b/coreutils/df.c | |||
@@ -129,8 +129,19 @@ int df_main(int argc UNUSED_PARAM, char **argv) | |||
129 | if (opt & OPT_MEGA) | 129 | if (opt & OPT_MEGA) |
130 | df_disp_hr = 1024*1024; | 130 | df_disp_hr = 1024*1024; |
131 | 131 | ||
132 | if (opt & OPT_BSIZE) | 132 | if (opt & OPT_BSIZE) { |
133 | df_disp_hr = xatoul_range(chp, 1, ULONG_MAX); /* disallow 0 */ | 133 | /* GNU coreutils 8.25 accepts "-BMiB" form too */ |
134 | int i; | ||
135 | for (i = 0; kmg_i_suffixes[i].suffix[0]; i++) { | ||
136 | if (strcmp(kmg_i_suffixes[i].suffix, chp) == 0) { | ||
137 | df_disp_hr = kmg_i_suffixes[i].mult; | ||
138 | goto got_it; | ||
139 | } | ||
140 | } | ||
141 | /* Range used to disallow 0 */ | ||
142 | df_disp_hr = xatoul_range_sfx(chp, 1, ULONG_MAX, kmg_i_suffixes); | ||
143 | got_it: ; | ||
144 | } | ||
134 | 145 | ||
135 | /* From the manpage of df from coreutils-6.10: | 146 | /* From the manpage of df from coreutils-6.10: |
136 | * Disk space is shown in 1K blocks by default, unless the environment | 147 | * Disk space is shown in 1K blocks by default, unless the environment |
@@ -203,6 +214,11 @@ int df_main(int argc UNUSED_PARAM, char **argv) | |||
203 | bb_simple_perror_msg(mount_point); | 214 | bb_simple_perror_msg(mount_point); |
204 | goto set_error; | 215 | goto set_error; |
205 | } | 216 | } |
217 | /* Some uclibc versions were seen to lose f_frsize | ||
218 | * (kernel does return it, but then uclibc does not copy it) | ||
219 | */ | ||
220 | if (s.f_frsize == 0) | ||
221 | s.f_frsize = s.f_bsize; | ||
206 | 222 | ||
207 | if ((s.f_blocks > 0) || !mount_table || (opt & OPT_ALL)) { | 223 | if ((s.f_blocks > 0) || !mount_table || (opt & OPT_ALL)) { |
208 | if (opt & OPT_INODE) { | 224 | if (opt & OPT_INODE) { |
diff --git a/coreutils/install.c b/coreutils/install.c index e68589229..831f9b802 100644 --- a/coreutils/install.c +++ b/coreutils/install.c | |||
@@ -211,7 +211,8 @@ int install_main(int argc, char **argv) | |||
211 | char *ddir = xstrdup(dest); | 211 | char *ddir = xstrdup(dest); |
212 | bb_make_directory(dirname(ddir), 0755, mkdir_flags); | 212 | bb_make_directory(dirname(ddir), 0755, mkdir_flags); |
213 | /* errors are not checked. copy_file | 213 | /* errors are not checked. copy_file |
214 | * will fail if dir is not created. */ | 214 | * will fail if dir is not created. |
215 | */ | ||
215 | free(ddir); | 216 | free(ddir); |
216 | } | 217 | } |
217 | if (isdir) | 218 | if (isdir) |
diff --git a/coreutils/test.c b/coreutils/test.c index df42590e4..67fdfde4f 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -55,6 +55,8 @@ | |||
55 | //kbuild:lib-$(CONFIG_TEST2) += test.o test_ptr_hack.o | 55 | //kbuild:lib-$(CONFIG_TEST2) += test.o test_ptr_hack.o |
56 | //kbuild:lib-$(CONFIG_ASH_BUILTIN_TEST) += test.o test_ptr_hack.o | 56 | //kbuild:lib-$(CONFIG_ASH_BUILTIN_TEST) += test.o test_ptr_hack.o |
57 | //kbuild:lib-$(CONFIG_HUSH) += test.o test_ptr_hack.o | 57 | //kbuild:lib-$(CONFIG_HUSH) += test.o test_ptr_hack.o |
58 | //kbuild:lib-$(CONFIG_SH_IS_HUSH) += test.o test_ptr_hack.o | ||
59 | //kbuild:lib-$(CONFIG_BASH_IS_HUSH) += test.o test_ptr_hack.o | ||
58 | 60 | ||
59 | /* "test --help" is special-cased to ignore --help */ | 61 | /* "test --help" is special-cased to ignore --help */ |
60 | //usage:#define test_trivial_usage NOUSAGE_STR | 62 | //usage:#define test_trivial_usage NOUSAGE_STR |
diff --git a/examples/mdev.conf b/examples/mdev.conf index 51795694d..fab1dc451 100644 --- a/examples/mdev.conf +++ b/examples/mdev.conf | |||
@@ -34,3 +34,5 @@ fd[0-9]* 0:11 660 | |||
34 | 34 | ||
35 | sd[a-z]* 0:6 660 | 35 | sd[a-z]* 0:6 660 |
36 | hd[a-z]* 0:6 660 | 36 | hd[a-z]* 0:6 660 |
37 | |||
38 | hw_random 0:0 600 =hwrng | ||
diff --git a/examples/var_service/README_distro_proposal.txt b/examples/var_service/README_distro_proposal.txt new file mode 100644 index 000000000..9b3fe04ba --- /dev/null +++ b/examples/var_service/README_distro_proposal.txt | |||
@@ -0,0 +1,291 @@ | |||
1 | A distro which already uses runit | ||
2 | |||
3 | I installed Void Linux, in order to see what do they have. | ||
4 | Xfce desktop looks fairly okay, network is up. | ||
5 | ps tells me they did put X, dbus, NM and udev into runsvdir-supervised tree: | ||
6 | |||
7 | 1 ? 00:00:01 runit | ||
8 | 623 ? 00:00:00 runsvdir | ||
9 | 629 ? 00:00:00 runsv | ||
10 | 650 tty1 00:00:00 agetty | ||
11 | 630 ? 00:00:00 runsv | ||
12 | 644 ? 00:00:09 NetworkManager | ||
13 | 1737 ? 00:00:00 dhclient | ||
14 | 631 ? 00:00:00 runsv | ||
15 | 639 tty4 00:00:00 agetty | ||
16 | 632 ? 00:00:00 runsv | ||
17 | 640 ? 00:00:00 sshd | ||
18 | 1804 ? 00:00:00 sshd | ||
19 | 1809 pts/3 00:00:00 sh | ||
20 | 1818 pts/3 00:00:00 ps | ||
21 | 633 ? 00:00:00 runsv | ||
22 | 637 tty5 00:00:00 agetty | ||
23 | 634 ? 00:00:00 runsv | ||
24 | 796 ? 00:00:00 dhclient | ||
25 | 635 ? 00:00:00 runsv | ||
26 | 649 ? 00:00:00 uuidd | ||
27 | 636 ? 00:00:00 runsv | ||
28 | 647 ? 00:00:00 acpid | ||
29 | 638 ? 00:00:00 runsv | ||
30 | 652 ? 00:00:00 console-kit-dae | ||
31 | 641 ? 00:00:00 runsv | ||
32 | 651 tty6 00:00:00 agetty | ||
33 | 642 ? 00:00:00 runsv | ||
34 | 660 tty2 00:00:00 agetty | ||
35 | 643 ? 00:00:00 runsv | ||
36 | 657 ? 00:00:02 dbus-daemon | ||
37 | 645 ? 00:00:00 runsv | ||
38 | 658 ? 00:00:00 cgmanager | ||
39 | 648 ? 00:00:00 runsv | ||
40 | 656 tty3 00:00:00 agetty | ||
41 | 653 ? 00:00:00 runsv | ||
42 | 655 ? 00:00:00 lxdm-binary | ||
43 | 698 tty7 00:00:14 Xorg | ||
44 | 729 ? 00:00:00 lxdm-session | ||
45 | 956 ? 00:00:00 sh | ||
46 | 982 ? 00:00:00 xfce4-session | ||
47 | 1006 ? 00:00:04 nm-applet | ||
48 | 654 ? 00:00:00 runsv | ||
49 | 659 ? 00:00:00 udevd | ||
50 | |||
51 | Here is a link to Vod Linux's wiki: | ||
52 | |||
53 | https://wiki.voidlinux.eu/Runit | ||
54 | |||
55 | Void Linux packages install their services as subdirectories of /etc/rc, | ||
56 | such as /etc/sv/sshd, with a script file, "run", and a link | ||
57 | "supervise" -> /run/runit/supervise.sshd | ||
58 | |||
59 | For sshd, "run" contains: | ||
60 | |||
61 | #!/bin/sh | ||
62 | ssh-keygen -A >/dev/null 2>&1 # generate host keys if they don't exist | ||
63 | [ -r conf ] && . ./conf | ||
64 | exec /usr/bin/sshd -D $OPTS | ||
65 | |||
66 | That's it from the POV of the packager. | ||
67 | |||
68 | This is pretty minimalistic, and yet, it is already distro-specific: | ||
69 | the link to /run/runit/* is conceptually wrong, it requires packagers | ||
70 | to know that /etc/rc should not be mutable and thus they need to use | ||
71 | a different location in filesystem for supervise/ directory. | ||
72 | |||
73 | I think a good thing would be to require just one file: the "run" script. | ||
74 | The rest should be handled by distro tooling, not by packager. | ||
75 | |||
76 | A similar issue is arising with logging. It would be ideal if packagers | ||
77 | would not need to know how a particular distro manages logs. | ||
78 | Whatever their daemons print to stdout/stderr, should be automagically logged | ||
79 | in a way distro prefers. | ||
80 | |||
81 | * * * * * * * * | ||
82 | |||
83 | Proposed "standard" on how distros should use runit | ||
84 | |||
85 | The original idea of services-as-directories belongs to D.J.Bernstein (djb), | ||
86 | and his project to implement it is daemontools: https://cr.yp.to/daemontools.html | ||
87 | |||
88 | There are several reimplementations of daemontools: | ||
89 | - runit: by Gerrit Pape, http://smarden.org/runit/ | ||
90 | (busybox has it included) | ||
91 | - s6: by Laurent Bercot, http://skarnet.org/software/s6/ | ||
92 | |||
93 | |||
94 | It is not required that a specific clone should be used. Let evolution work. | ||
95 | |||
96 | Terminology | ||
97 | |||
98 | daemon: any long running background program. Common examples are sshd, getty, | ||
99 | ntpd, dhcp client... | ||
100 | |||
101 | service: same as "daemon" | ||
102 | |||
103 | service directory: a directory with an executable file (script) named "run" | ||
104 | which (usually) execs daemon (possibly after some preparatory steps). | ||
105 | It should start it not as a child or daemonized process, but by exec'ing it | ||
106 | (inheriting the same PID and the place in the process tree). | ||
107 | |||
108 | service monitor: a tool which watches a set of service directories. | ||
109 | In daemontools package, it is called "svscan". In runit, it is called | ||
110 | "runsvdir". In s6, it is called "s6-svscan". | ||
111 | Service monitor starts a supervisor for each service directory. | ||
112 | If it dies, it restarts it. If service directory disappears, | ||
113 | service monitor will not be restarted if it dies. | ||
114 | runit's service monitor (runsvdir) sends SIGTERM to supervisors | ||
115 | whose directories disappeared. | ||
116 | |||
117 | supervisor: a tool which monitors one service directory. | ||
118 | It runs "run" script as its child. It restarts it if it dies. | ||
119 | It can be instructed to start/top/signal its child. | ||
120 | In daemontools package, it is called "supervise". In runit, it is called | ||
121 | "runsv". In s6, it is called "s6-supervise". | ||
122 | |||
123 | Conceptually, a daemontools clone can be designed such that it does not *have* | ||
124 | the supervisor component: service monitor can directly monitor all its daemons | ||
125 | (for example, this may be a good idea for memory-constrained systems). | ||
126 | However all three existing projects (daemontools/runit/s6) do have a per-service | ||
127 | supervisor process. | ||
128 | |||
129 | log service: a service which is exclusively tasked with logging | ||
130 | the output of another service. It is implemented as log/ subdirectory | ||
131 | in a service directory. It has the same structure as "normal" | ||
132 | service dirs: it has a "run" script which starts a logging tool. | ||
133 | |||
134 | If log service exists, stdout of its "main" service is piped | ||
135 | to log service. Stops/restarts of either of them do not sever the pipe | ||
136 | between them. | ||
137 | |||
138 | If log service exists, daemontools and s6 run a pair of supervisors | ||
139 | (one for the daemon, one for the logger); runit runs only one supervisor | ||
140 | per service, which is handling both of them (presumably this is done | ||
141 | to use fewer processes and thus, fewer resources). | ||
142 | |||
143 | |||
144 | User API | ||
145 | |||
146 | "Users" of service monitoring are authors of software which has daemons. | ||
147 | They need to package their daemons to be installed as services at package | ||
148 | install time. And they need to do this for many distros. | ||
149 | The less distros diverge, the easier users' lives are. | ||
150 | |||
151 | System-wide service dirs reside in a distro-specific location. | ||
152 | The recommended location is /var/service. (However, since it is not | ||
153 | a mandatory location, avoid depending on it in your run scripts). | ||
154 | |||
155 | The install location for service dirs is /etc/rc: | ||
156 | when e.g. ntpd daemon is installed, it creates the /etc/rc/ntpd | ||
157 | directory with (minimally) one executable file (script) named "run" | ||
158 | which starts ntpd daemon. It can have other files there. | ||
159 | |||
160 | At boot, distro should copy /etc/rc/* to a suitable writable | ||
161 | directory (common choice are /var/service, /run/service etc). | ||
162 | It should create log/ directories in each subdirectory | ||
163 | and create "run" files in them with suitable (for this particular distro) | ||
164 | logging tool invocation, unless this directory chose to channel | ||
165 | all logging from all daemons through service monitor process | ||
166 | and log all of them into one file/database/whatever, | ||
167 | in which case log/ directories should not be created. | ||
168 | |||
169 | It is allowable for a distro to directly use /etc/rc/ as the only | ||
170 | location of its service directories. (For example, | ||
171 | /var/service may be a symlink to /etc/rc). | ||
172 | However, it poses some problems: | ||
173 | |||
174 | (1) Supervision tools will need to write to subdirectories: | ||
175 | the control of running daemons is implemented via some files and fifos | ||
176 | in automatically created supervise/ subdirectory in each /etc/rc/DIR. | ||
177 | |||
178 | (2) Creation of a new service can race with the rescanning of /etc/rc/ | ||
179 | by service monitor: service monitor may see a directory with only some files | ||
180 | present. If it attempts to start the service in this state, all sorts | ||
181 | of bad things may happen. This may be worked around by various | ||
182 | heuristics in service monitor which give new service a few seconds | ||
183 | of "grace time" to be fully populated; but this is not yet | ||
184 | implemented in any of three packages. | ||
185 | |||
186 | Daemons' output file descriptors are handled somewhat awkwardly | ||
187 | by various daemontools implementations. For example, for runit tools, | ||
188 | daemons' stdout goes to wherever runsdir's stdout was directied; | ||
189 | stderr goes to runsvdir, which in turn "rotates" it on its command line | ||
190 | (which is visible in ps output). | ||
191 | |||
192 | Hopefully this get changed/standardized; while it is not, the "run" file | ||
193 | should start with a | ||
194 | |||
195 | exec 2>&1 | ||
196 | |||
197 | command, making stderr equivalent to stdout. | ||
198 | An especially primitive service which does not want its output to be logged | ||
199 | with standard tools can do | ||
200 | |||
201 | exec >LOGFILE 2>&1 | ||
202 | |||
203 | or even | ||
204 | |||
205 | exec >/dev/null 2>&1 | ||
206 | |||
207 | To prevent creation of distro-specific log/ directory, a service directory | ||
208 | in /etc/rc can contain an empty "log" file. | ||
209 | |||
210 | |||
211 | Controlling daemons | ||
212 | |||
213 | The "svc" tool is available for admins and scripts to control services. | ||
214 | In particular, often one service needs to control another: | ||
215 | e.g. ifplugd can detect that the network cable was just plugged in, | ||
216 | and it needs to (re)start DHCP service for this network device. | ||
217 | |||
218 | The name of this tool is not standard either, which is an obvious problem. | ||
219 | I propose to fix this by implementing a tool with fixed name and API by all | ||
220 | daemontools clones. Lets use original daemontools name and API. Thus: | ||
221 | |||
222 | The following form must work: | ||
223 | |||
224 | svc -udopchaitkx DIR | ||
225 | |||
226 | Options map to up/down/once/STOP/CONT/HUP/ALRM/INT/TERM/KILL/exit | ||
227 | commands to the daemon being controlled. | ||
228 | |||
229 | The form with one option letter must work. If multiple-option form | ||
230 | is supported, there is no guarantee in which order they take effect: | ||
231 | svc -it DIR can deliver TERM and INT in any order. | ||
232 | |||
233 | If more than one DIR can be specified (which is not a requirement), | ||
234 | there is no guarantee in which order commands are sent to them. | ||
235 | |||
236 | If DIR has no slash and is not "." or "..", it is assumed to be | ||
237 | relative to the system-wide service directory. | ||
238 | |||
239 | The "svok DIR" tool exits 0 if service is running, and nonzero if not. | ||
240 | |||
241 | The "svstat DIR1 DIR2..." prints one human-readable line for each directory, | ||
242 | saying whether supervise is successfully running in that directory, | ||
243 | and reporting the status information maintained by supervise. | ||
244 | |||
245 | Other tools with different names and APIs may exist; however | ||
246 | for portability scripts should use the above tools. | ||
247 | |||
248 | Creation of a new service on a running system should be done atomically. | ||
249 | To this end, first create and populate a new /etc/rc/DIR. | ||
250 | |||
251 | Then "activate" it by running ??????? - this copies (or symlinks, | ||
252 | depending on the distro) its files to the "live" service directory, | ||
253 | whereever it is located on this distro. | ||
254 | |||
255 | Removal of the service should be done as follows: | ||
256 | svc -d DIR [DIR/log], then remove the service directory | ||
257 | (this makes service monitor SIGTERM per-directory supervisors | ||
258 | (if they exist in the implementation)) | ||
259 | |||
260 | |||
261 | Implementation details | ||
262 | |||
263 | Top-level service monitor program name is not standardized. | ||
264 | [svscan, runsvdir, s6-svscan ...] | ||
265 | |||
266 | It may run one per-directory supervisor, or two supervisors | ||
267 | (one for DIR/ and one for DIR/log/); for memory-constrained systems | ||
268 | an implementation is possible which itself controls all services, without | ||
269 | intermediate supervisors. | ||
270 | [runsvdir runs one "runsv DIR" per DIR, runsv handles DIR/log/ if that exists] | ||
271 | [svscan runs a pair of "superwise DIR" and "superwise DIR/log"] | ||
272 | |||
273 | Directores are remembered by device+inode numbers, not names. Renaming a directory | ||
274 | does not affect the running service (unless it is renamed to a .dotdir). | ||
275 | |||
276 | Removal (or .dotdiring) of a directory sends SIGTERM to any running services. | ||
277 | |||
278 | Standard output of non-logged services goes to standard output of service monitor. | ||
279 | Standard output of logger services goes to standard output of service monitor. | ||
280 | Standard error of them always goes to standard error of service monitor. | ||
281 | |||
282 | If you want to log standard error of your logged service along with its stdout, use | ||
283 | "exec 2>&1" in the beginning of your "run" script. | ||
284 | |||
285 | Whether stdout/stderr of service monitor is discarded (>/dev/null) | ||
286 | or logged in some way is system-dependent. | ||
287 | |||
288 | |||
289 | Containers | ||
290 | |||
291 | [What do containers need?] | ||
diff --git a/include/applets.h.sh b/include/applets.h.sh index bab4e0d72..be117cf84 100755 --- a/include/applets.h.sh +++ b/include/applets.h.sh | |||
@@ -4,11 +4,7 @@ | |||
4 | # enabling it. Run it after applets.h is generated. | 4 | # enabling it. Run it after applets.h is generated. |
5 | 5 | ||
6 | # CONFIG_applet names | 6 | # CONFIG_applet names |
7 | grep ^IF_ applets.h | grep -v IF_FEATURE_ | sed 's/IF_\([A-Z0-9._-]*\)(.*/\1/' \ | 7 | grep ^IF_ applets.h | grep -v ^IF_FEATURE_ | sed 's/IF_\([A-Z0-9._-]*\)(.*/\1/' \ |
8 | | grep -v MODPROBE_SMALL \ | ||
9 | | sed 's/BB_SYSCTL/SYSCTL/' \ | ||
10 | | sed 's/TEST1/[/' \ | ||
11 | | sed 's/TEST2/[[/' \ | ||
12 | | sort | uniq \ | 8 | | sort | uniq \ |
13 | >applets_APP1 | 9 | >applets_APP1 |
14 | 10 | ||
@@ -17,8 +13,11 @@ grep ^IF_ applets.h | sed -e's/ //g' -e's/.*(\([a-z[][^,]*\),.*/\1/' \ | |||
17 | | grep -v '^bash$' \ | 13 | | grep -v '^bash$' \ |
18 | | grep -v '^sh$' \ | 14 | | grep -v '^sh$' \ |
19 | | tr a-z A-Z \ | 15 | | tr a-z A-Z \ |
16 | | sed 's/^SYSCTL$/BB_SYSCTL/' \ | ||
17 | | sed 's/^\[\[$/TEST1/' \ | ||
18 | | sed 's/^\[$/TEST2/' \ | ||
20 | | sort | uniq \ | 19 | | sort | uniq \ |
21 | >applets_APP2 | 20 | >applets_APP2 |
22 | 21 | ||
23 | diff -u applets_APP1 applets_APP2 >applets_APP.diff | 22 | diff -u applets_APP1 applets_APP2 >applets_APP.diff |
24 | rm applets_APP1 applets_APP2 | 23 | #rm applets_APP1 applets_APP2 |
diff --git a/include/libbb.h b/include/libbb.h index a6de5e97b..0b9cfb585 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -45,7 +45,7 @@ | |||
45 | #include <sys/stat.h> | 45 | #include <sys/stat.h> |
46 | #include <sys/time.h> | 46 | #include <sys/time.h> |
47 | #include <sys/types.h> | 47 | #include <sys/types.h> |
48 | #ifndef major | 48 | #if !defined(major) || defined(__GLIBC__) |
49 | # include <sys/sysmacros.h> | 49 | # include <sys/sysmacros.h> |
50 | #endif | 50 | #endif |
51 | #include <sys/wait.h> | 51 | #include <sys/wait.h> |
@@ -81,8 +81,6 @@ | |||
81 | #if ENABLE_SELINUX | 81 | #if ENABLE_SELINUX |
82 | # include <selinux/selinux.h> | 82 | # include <selinux/selinux.h> |
83 | # include <selinux/context.h> | 83 | # include <selinux/context.h> |
84 | # include <selinux/flask.h> | ||
85 | # include <selinux/av_permissions.h> | ||
86 | #endif | 84 | #endif |
87 | #if ENABLE_FEATURE_UTMP | 85 | #if ENABLE_FEATURE_UTMP |
88 | # if defined __UCLIBC__ && ( \ | 86 | # if defined __UCLIBC__ && ( \ |
@@ -944,6 +942,7 @@ extern const struct suffix_mult bkm_suffixes[]; | |||
944 | #define km_suffixes (bkm_suffixes + 1) | 942 | #define km_suffixes (bkm_suffixes + 1) |
945 | extern const struct suffix_mult cwbkMG_suffixes[]; | 943 | extern const struct suffix_mult cwbkMG_suffixes[]; |
946 | #define kMG_suffixes (cwbkMG_suffixes + 3) | 944 | #define kMG_suffixes (cwbkMG_suffixes + 3) |
945 | extern const struct suffix_mult kmg_i_suffixes[]; | ||
947 | 946 | ||
948 | #include "xatonum.h" | 947 | #include "xatonum.h" |
949 | /* Specialized: */ | 948 | /* Specialized: */ |
@@ -1210,8 +1209,16 @@ int bb_cat(char** argv); | |||
1210 | /* If shell needs them, they exist even if not enabled as applets */ | 1209 | /* If shell needs them, they exist even if not enabled as applets */ |
1211 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); | 1210 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); |
1212 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); | 1211 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); |
1213 | int test_main(int argc, char **argv) IF_TEST(MAIN_EXTERNALLY_VISIBLE); | 1212 | int test_main(int argc, char **argv) |
1214 | int kill_main(int argc, char **argv) IF_KILL(MAIN_EXTERNALLY_VISIBLE); | 1213 | #if ENABLE_TEST || ENABLE_TEST1 || ENABLE_TEST2 |
1214 | MAIN_EXTERNALLY_VISIBLE | ||
1215 | #endif | ||
1216 | ; | ||
1217 | int kill_main(int argc, char **argv) | ||
1218 | #if ENABLE_KILL || ENABLE_KILLALL || ENABLE_KILLALL5 | ||
1219 | MAIN_EXTERNALLY_VISIBLE | ||
1220 | #endif | ||
1221 | ; | ||
1215 | /* Similar, but used by chgrp, not shell */ | 1222 | /* Similar, but used by chgrp, not shell */ |
1216 | int chown_main(int argc, char **argv) IF_CHOWN(MAIN_EXTERNALLY_VISIBLE); | 1223 | int chown_main(int argc, char **argv) IF_CHOWN(MAIN_EXTERNALLY_VISIBLE); |
1217 | /* Used by ftpd */ | 1224 | /* Used by ftpd */ |
diff --git a/include/mingw.h b/include/mingw.h index 04700963c..569c2c704 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -448,7 +448,9 @@ DIR *mingw_opendir(const char *path); | |||
448 | * MinGW specific | 448 | * MinGW specific |
449 | */ | 449 | */ |
450 | #define is_dir_sep(c) ((c) == '/' || (c) == '\\') | 450 | #define is_dir_sep(c) ((c) == '/' || (c) == '\\') |
451 | #ifndef PRIuMAX | ||
451 | #define PRIuMAX "I64u" | 452 | #define PRIuMAX "I64u" |
453 | #endif | ||
452 | 454 | ||
453 | pid_t FAST_FUNC mingw_spawn(char **argv); | 455 | pid_t FAST_FUNC mingw_spawn(char **argv); |
454 | intptr_t FAST_FUNC mingw_spawn_proc(char **argv); | 456 | intptr_t FAST_FUNC mingw_spawn_proc(char **argv); |
diff --git a/init/init.c b/init/init.c index 0813d1b5f..08cfa2f8c 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -83,7 +83,7 @@ | |||
83 | //config: | 83 | //config: |
84 | //config:config FEATURE_INIT_COREDUMPS | 84 | //config:config FEATURE_INIT_COREDUMPS |
85 | //config: bool "Support dumping core for child processes (debugging only)" | 85 | //config: bool "Support dumping core for child processes (debugging only)" |
86 | //config: default y | 86 | //config: default n # not Y because this is a debug option |
87 | //config: depends on INIT || LINUXRC | 87 | //config: depends on INIT || LINUXRC |
88 | //config: help | 88 | //config: help |
89 | //config: If this option is enabled and the file /.init_enable_core | 89 | //config: If this option is enabled and the file /.init_enable_core |
diff --git a/libbb/Config.src b/libbb/Config.src index 00804e31e..172fbcc0e 100644 --- a/libbb/Config.src +++ b/libbb/Config.src | |||
@@ -152,7 +152,7 @@ config FEATURE_TAB_COMPLETION | |||
152 | 152 | ||
153 | config FEATURE_USERNAME_COMPLETION | 153 | config FEATURE_USERNAME_COMPLETION |
154 | bool "Username completion" | 154 | bool "Username completion" |
155 | default n | 155 | default y |
156 | depends on FEATURE_TAB_COMPLETION | 156 | depends on FEATURE_TAB_COMPLETION |
157 | help | 157 | help |
158 | Enable username completion. | 158 | Enable username completion. |
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 39d9d907d..fc9371db1 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
@@ -135,6 +135,7 @@ lib-$(CONFIG_TFTPD) += udp_io.o | |||
135 | lib-$(CONFIG_TCPSVD) += udp_io.o | 135 | lib-$(CONFIG_TCPSVD) += udp_io.o |
136 | lib-$(CONFIG_UDPSVD) += udp_io.o | 136 | lib-$(CONFIG_UDPSVD) += udp_io.o |
137 | lib-$(CONFIG_TRACEROUTE) += udp_io.o | 137 | lib-$(CONFIG_TRACEROUTE) += udp_io.o |
138 | lib-$(CONFIG_TRACEROUTE6) += udp_io.o | ||
138 | 139 | ||
139 | lib-$(CONFIG_LOSETUP) += loop.o | 140 | lib-$(CONFIG_LOSETUP) += loop.o |
140 | lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o | 141 | lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o |
@@ -144,7 +145,7 @@ lib-$(CONFIG_ADDUSER) += update_passwd.o | |||
144 | lib-$(CONFIG_DELGROUP) += update_passwd.o | 145 | lib-$(CONFIG_DELGROUP) += update_passwd.o |
145 | lib-$(CONFIG_DELUSER) += update_passwd.o | 146 | lib-$(CONFIG_DELUSER) += update_passwd.o |
146 | 147 | ||
147 | lib-$(CONFIG_FTPD) += correct_password.o | 148 | lib-$(CONFIG_FTPD) += pw_encrypt.o correct_password.o |
148 | lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o | 149 | lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o |
149 | lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o | 150 | lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o |
150 | lib-$(CONFIG_CRYPTPW) += pw_encrypt.o | 151 | lib-$(CONFIG_CRYPTPW) += pw_encrypt.o |
@@ -159,6 +160,7 @@ lib-$(CONFIG_FEATURE_FTP_AUTHENTICATION) += pw_encrypt.o | |||
159 | lib-$(CONFIG_DF) += find_mount_point.o | 160 | lib-$(CONFIG_DF) += find_mount_point.o |
160 | lib-$(CONFIG_MKFS_MINIX) += find_mount_point.o | 161 | lib-$(CONFIG_MKFS_MINIX) += find_mount_point.o |
161 | lib-$(CONFIG_MKFS_EXT2) += find_mount_point.o | 162 | lib-$(CONFIG_MKFS_EXT2) += find_mount_point.o |
163 | lib-$(CONFIG_MKE2FS) += find_mount_point.o | ||
162 | lib-$(CONFIG_MKFS_REISER) += find_mount_point.o | 164 | lib-$(CONFIG_MKFS_REISER) += find_mount_point.o |
163 | lib-$(CONFIG_FSCK_MINIX) += find_mount_point.o | 165 | lib-$(CONFIG_FSCK_MINIX) += find_mount_point.o |
164 | lib-$(CONFIG_MOUNT) += find_mount_point.o | 166 | lib-$(CONFIG_MOUNT) += find_mount_point.o |
@@ -171,11 +173,13 @@ lib-$(CONFIG_MPSTAT) += get_cpu_count.o | |||
171 | lib-$(CONFIG_POWERTOP) += get_cpu_count.o | 173 | lib-$(CONFIG_POWERTOP) += get_cpu_count.o |
172 | 174 | ||
173 | lib-$(CONFIG_PING) += inet_cksum.o | 175 | lib-$(CONFIG_PING) += inet_cksum.o |
176 | lib-$(CONFIG_PING6) += inet_cksum.o | ||
174 | lib-$(CONFIG_TRACEROUTE) += inet_cksum.o | 177 | lib-$(CONFIG_TRACEROUTE) += inet_cksum.o |
175 | lib-$(CONFIG_TRACEROUTE6) += inet_cksum.o | 178 | lib-$(CONFIG_TRACEROUTE6) += inet_cksum.o |
176 | lib-$(CONFIG_UDHCPC) += inet_cksum.o | 179 | lib-$(CONFIG_UDHCPC) += inet_cksum.o |
177 | lib-$(CONFIG_UDHCPC6) += inet_cksum.o | 180 | lib-$(CONFIG_UDHCPC6) += inet_cksum.o |
178 | lib-$(CONFIG_UDHCPD) += inet_cksum.o | 181 | lib-$(CONFIG_UDHCPD) += inet_cksum.o |
182 | lib-$(CONFIG_DHCPRELAY) += inet_cksum.o | ||
179 | 183 | ||
180 | # We shouldn't build xregcomp.c if we don't need it - this ensures we don't | 184 | # We shouldn't build xregcomp.c if we don't need it - this ensures we don't |
181 | # require regex.h to be in the include dir even if we don't need it thereby | 185 | # require regex.h to be in the include dir even if we don't need it thereby |
@@ -184,6 +188,8 @@ lib-$(CONFIG_UDHCPD) += inet_cksum.o | |||
184 | lib-$(CONFIG_AWK) += xregcomp.o | 188 | lib-$(CONFIG_AWK) += xregcomp.o |
185 | lib-$(CONFIG_SED) += xregcomp.o | 189 | lib-$(CONFIG_SED) += xregcomp.o |
186 | lib-$(CONFIG_GREP) += xregcomp.o | 190 | lib-$(CONFIG_GREP) += xregcomp.o |
191 | lib-$(CONFIG_EGREP) += xregcomp.o | ||
192 | lib-$(CONFIG_FGREP) += xregcomp.o | ||
187 | lib-$(CONFIG_EXPR) += xregcomp.o | 193 | lib-$(CONFIG_EXPR) += xregcomp.o |
188 | lib-$(CONFIG_MDEV) += xregcomp.o | 194 | lib-$(CONFIG_MDEV) += xregcomp.o |
189 | lib-$(CONFIG_LESS) += xregcomp.o | 195 | lib-$(CONFIG_LESS) += xregcomp.o |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 1fe0eb44f..ac3e414f5 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -334,21 +334,6 @@ static struct suid_config_t { | |||
334 | 334 | ||
335 | static bool suid_cfg_readable; | 335 | static bool suid_cfg_readable; |
336 | 336 | ||
337 | /* check if u is member of group g */ | ||
338 | static int ingroup(uid_t u, gid_t g) | ||
339 | { | ||
340 | struct group *grp = getgrgid(g); | ||
341 | if (grp) { | ||
342 | char **mem; | ||
343 | for (mem = grp->gr_mem; *mem; mem++) { | ||
344 | struct passwd *pwd = getpwnam(*mem); | ||
345 | if (pwd && (pwd->pw_uid == u)) | ||
346 | return 1; | ||
347 | } | ||
348 | } | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | /* libbb candidate */ | 337 | /* libbb candidate */ |
353 | static char *get_trimmed_slice(char *s, char *e) | 338 | static char *get_trimmed_slice(char *s, char *e) |
354 | { | 339 | { |
@@ -573,7 +558,22 @@ static inline void parse_config_file(void) | |||
573 | # endif /* FEATURE_SUID_CONFIG */ | 558 | # endif /* FEATURE_SUID_CONFIG */ |
574 | 559 | ||
575 | 560 | ||
576 | # if ENABLE_FEATURE_SUID | 561 | # if ENABLE_FEATURE_SUID && NUM_APPLETS > 0 |
562 | /* check if u is member of group g */ | ||
563 | static int ingroup(uid_t u, gid_t g) | ||
564 | { | ||
565 | struct group *grp = getgrgid(g); | ||
566 | if (grp) { | ||
567 | char **mem; | ||
568 | for (mem = grp->gr_mem; *mem; mem++) { | ||
569 | struct passwd *pwd = getpwnam(*mem); | ||
570 | if (pwd && (pwd->pw_uid == u)) | ||
571 | return 1; | ||
572 | } | ||
573 | } | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static void check_suid(int applet_no) | 577 | static void check_suid(int applet_no) |
578 | { | 578 | { |
579 | gid_t rgid; /* real gid */ | 579 | gid_t rgid; /* real gid */ |
diff --git a/libbb/make_directory.c b/libbb/make_directory.c index 3980376ec..840c525b0 100644 --- a/libbb/make_directory.c +++ b/libbb/make_directory.c | |||
@@ -35,9 +35,20 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags) | |||
35 | char c; | 35 | char c; |
36 | struct stat st; | 36 | struct stat st; |
37 | 37 | ||
38 | /* Happens on bb_make_directory(dirname("no_slashes"),...) */ | 38 | /* "path" can be a result of dirname(). |
39 | if (LONE_CHAR(path, '.')) | 39 | * dirname("no_slashes") returns ".", possibly read-only. |
40 | * musl dirname() can return read-only "/" too. | ||
41 | * We need writable string. And for "/", "." (and ".."?) | ||
42 | * nothing needs to be created anyway. | ||
43 | */ | ||
44 | if (LONE_CHAR(path, '/')) | ||
40 | return 0; | 45 | return 0; |
46 | if (path[0] == '.') { | ||
47 | if (path[1] == '\0') | ||
48 | return 0; /* "." */ | ||
49 | // if (path[1] == '.' && path[2] == '\0') | ||
50 | // return 0; /* ".." */ | ||
51 | } | ||
41 | 52 | ||
42 | org_mask = cur_mask = (mode_t)-1L; | 53 | org_mask = cur_mask = (mode_t)-1L; |
43 | s = path; | 54 | s = path; |
diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c index a2004f480..95423d19b 100644 --- a/libbb/update_passwd.c +++ b/libbb/update_passwd.c | |||
@@ -30,7 +30,18 @@ static void check_selinux_update_passwd(const char *username) | |||
30 | if (!seuser) | 30 | if (!seuser) |
31 | bb_error_msg_and_die("invalid context '%s'", context); | 31 | bb_error_msg_and_die("invalid context '%s'", context); |
32 | if (strcmp(seuser, username) != 0) { | 32 | if (strcmp(seuser, username) != 0) { |
33 | if (checkPasswdAccess(PASSWD__PASSWD) != 0) | 33 | security_class_t tclass; |
34 | access_vector_t av; | ||
35 | |||
36 | tclass = string_to_security_class("passwd"); | ||
37 | if (tclass == 0) | ||
38 | goto die; | ||
39 | av = string_to_av_perm(tclass, "passwd"); | ||
40 | if (av == 0) | ||
41 | goto die; | ||
42 | |||
43 | if (selinux_check_passwd_access(av) != 0) | ||
44 | die: | ||
34 | bb_error_msg_and_die("SELinux: access denied"); | 45 | bb_error_msg_and_die("SELinux: access denied"); |
35 | } | 46 | } |
36 | if (ENABLE_FEATURE_CLEAN_UP) | 47 | if (ENABLE_FEATURE_CLEAN_UP) |
@@ -169,6 +180,7 @@ int FAST_FUNC update_passwd(const char *filename, | |||
169 | if (!line) /* EOF/error */ | 180 | if (!line) /* EOF/error */ |
170 | break; | 181 | break; |
171 | 182 | ||
183 | #if ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP | ||
172 | if (!name && member) { | 184 | if (!name && member) { |
173 | /* Delete member from all groups */ | 185 | /* Delete member from all groups */ |
174 | /* line is "GROUP:PASSWD:[member1[,member2]...]" */ | 186 | /* line is "GROUP:PASSWD:[member1[,member2]...]" */ |
@@ -198,6 +210,7 @@ int FAST_FUNC update_passwd(const char *filename, | |||
198 | fprintf(new_fp, "%s\n", line); | 210 | fprintf(new_fp, "%s\n", line); |
199 | goto next; | 211 | goto next; |
200 | } | 212 | } |
213 | #endif | ||
201 | 214 | ||
202 | cp = is_prefixed_with(line, name_colon); | 215 | cp = is_prefixed_with(line, name_colon); |
203 | if (!cp) { | 216 | if (!cp) { |
diff --git a/libbb/xatonum.c b/libbb/xatonum.c index 9dd5c3e7e..b63b7f54d 100644 --- a/libbb/xatonum.c +++ b/libbb/xatonum.c | |||
@@ -96,3 +96,22 @@ const struct suffix_mult cwbkMG_suffixes[] = { | |||
96 | /* coreutils also understands TPEZY suffixes for tera- and so on, with B suffix for decimal */ | 96 | /* coreutils also understands TPEZY suffixes for tera- and so on, with B suffix for decimal */ |
97 | { "", 0 } | 97 | { "", 0 } |
98 | }; | 98 | }; |
99 | |||
100 | const struct suffix_mult kmg_i_suffixes[] = { | ||
101 | { "KiB", 1024 }, | ||
102 | { "kiB", 1024 }, | ||
103 | { "K", 1024 }, | ||
104 | { "k", 1024 }, | ||
105 | { "MiB", 1048576 }, | ||
106 | { "miB", 1048576 }, | ||
107 | { "M", 1048576 }, | ||
108 | { "m", 1048576 }, | ||
109 | { "GiB", 1073741824 }, | ||
110 | { "giB", 1073741824 }, | ||
111 | { "G", 1073741824 }, | ||
112 | { "g", 1073741824 }, | ||
113 | { "KB", 1000 }, | ||
114 | { "MB", 1000000 }, | ||
115 | { "GB", 1000000000 }, | ||
116 | { "", 0 } | ||
117 | }; | ||
diff --git a/loginutils/login.c b/loginutils/login.c index 52abc1886..3ca8213bb 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -69,7 +69,9 @@ | |||
69 | #if ENABLE_SELINUX | 69 | #if ENABLE_SELINUX |
70 | # include <selinux/selinux.h> /* for is_selinux_enabled() */ | 70 | # include <selinux/selinux.h> /* for is_selinux_enabled() */ |
71 | # include <selinux/get_context_list.h> /* for get_default_context() */ | 71 | # include <selinux/get_context_list.h> /* for get_default_context() */ |
72 | # include <selinux/flask.h> /* for security class definitions */ | 72 | # /* from deprecated <selinux/flask.h>: */ |
73 | # undef SECCLASS_CHR_FILE | ||
74 | # define SECCLASS_CHR_FILE 10 | ||
73 | #endif | 75 | #endif |
74 | 76 | ||
75 | #if ENABLE_PAM | 77 | #if ENABLE_PAM |
diff --git a/make_single_applets.sh b/make_single_applets.sh new file mode 100755 index 000000000..00f502eda --- /dev/null +++ b/make_single_applets.sh | |||
@@ -0,0 +1,73 @@ | |||
1 | #!/bin/sh | ||
2 | # This script expects that the tree was built with the desired .config: | ||
3 | # in particular, it expects that include/applets.h is generated already. | ||
4 | # | ||
5 | # The script will try to rebuild each enabled applet in isolation. | ||
6 | # All other options which chose general bbox config, applet features, etc, | ||
7 | # are not modified for the builds. | ||
8 | |||
9 | makeopts="-j9" | ||
10 | |||
11 | # The list of all applet config symbols | ||
12 | test -f include/applets.h || { echo "No include/applets.h file"; exit 1; } | ||
13 | apps="` | ||
14 | grep ^IF_ include/applets.h \ | ||
15 | | grep -v ^IF_FEATURE_ \ | ||
16 | | sed 's/IF_\([A-Z0-9._-]*\)(.*/\1/' \ | ||
17 | | sort | uniq | ||
18 | `" | ||
19 | |||
20 | # Take existing config | ||
21 | test -f .config || { echo "No .config file"; exit 1; } | ||
22 | cfg="`cat .config`" | ||
23 | |||
24 | # Make a config with all applet symbols off | ||
25 | allno="$cfg" | ||
26 | for app in $apps; do | ||
27 | allno="`echo "$allno" | sed "s/^CONFIG_${app}=y\$/# CONFIG_${app} is not set/"`" | ||
28 | done | ||
29 | #echo "$allno" >.config_allno | ||
30 | |||
31 | # Turn on each applet individually and build single-applet executable | ||
32 | fail=0 | ||
33 | for app in $apps; do | ||
34 | # Only if it was indeed originally enabled... | ||
35 | { echo "$cfg" | grep -q "^CONFIG_${app}=y\$"; } || continue | ||
36 | |||
37 | echo "Making ${app}..." | ||
38 | mv .config .config.SV | ||
39 | echo "CONFIG_${app}=y" >.config | ||
40 | echo "$allno" | sed "/^# CONFIG_${app} is not set\$/d" >>.config | ||
41 | |||
42 | if test x"${app}" != x"SH_IS_ASH" && test x"${app}" != x"SH_IS_HUSH"; then | ||
43 | # $allno has all choices for "sh" aliasing set to off. | ||
44 | # "sh" aliasing defaults to "ash", not none. | ||
45 | # without this fix, "make oldconfig" sets it wrong, | ||
46 | # resulting in NUM_APPLETS = 2 (the second applet is "sh") | ||
47 | sed '/CONFIG_SH_IS_NONE/d' -i .config | ||
48 | echo "CONFIG_SH_IS_NONE=y" >>.config | ||
49 | fi | ||
50 | |||
51 | if ! yes '' | make oldconfig >busybox_make_${app}.log 2>&1; then | ||
52 | : $((fail++)) | ||
53 | echo "Config error for ${app}" | ||
54 | mv .config busybox_config_${app} | ||
55 | elif ! make $makeopts >>busybox_make_${app}.log 2>&1; then | ||
56 | : $((fail++)) | ||
57 | echo "Build error for ${app}" | ||
58 | mv .config busybox_config_${app} | ||
59 | elif ! grep -q '^#define NUM_APPLETS 1$' include/NUM_APPLETS.h; then | ||
60 | mv busybox busybox_${app} | ||
61 | : $((fail++)) | ||
62 | echo "NUM_APPLETS != 1 for ${app}: `cat include/NUM_APPLETS.h`" | ||
63 | mv .config busybox_config_${app} | ||
64 | else | ||
65 | mv busybox busybox_${app} | ||
66 | rm busybox_make_${app}.log | ||
67 | fi | ||
68 | mv .config.SV .config | ||
69 | #exit | ||
70 | done | ||
71 | touch .config # or else next "make" can be confused | ||
72 | echo "Failures: $fail" | ||
73 | test $fail = 0 # set exitcode | ||
diff --git a/modutils/Config.src b/modutils/Config.src index 4227f356a..84ff34a08 100644 --- a/modutils/Config.src +++ b/modutils/Config.src | |||
@@ -5,6 +5,37 @@ | |||
5 | 5 | ||
6 | menu "Linux Module Utilities" | 6 | menu "Linux Module Utilities" |
7 | 7 | ||
8 | config MODPROBE_SMALL | ||
9 | bool "Simplified modutils" | ||
10 | default y | ||
11 | select PLATFORM_LINUX | ||
12 | help | ||
13 | Simplified modutils. | ||
14 | |||
15 | With this option modprobe does not require modules.dep file | ||
16 | and does not use /etc/modules.conf file. | ||
17 | It scans module files in /lib/modules/`uname -r` and | ||
18 | determines dependencies and module alias names on the fly. | ||
19 | This may make module loading slower, most notably | ||
20 | when one needs to load module by alias (this requires | ||
21 | scanning through module _bodies_). | ||
22 | |||
23 | At the first attempt to load a module by alias modprobe | ||
24 | will try to generate modules.dep.bb file in order to speed up | ||
25 | future loads by alias. Failure to do so (read-only /lib/modules, | ||
26 | etc) is not reported, and future modprobes will be slow too. | ||
27 | |||
28 | NB: modules.dep.bb file format is not compatible | ||
29 | with modules.dep file as created/used by standard module tools. | ||
30 | |||
31 | Additional module parameters can be stored in | ||
32 | /etc/modules/$module_name files. | ||
33 | |||
34 | Apart from modprobe, other utilities are also provided: | ||
35 | - insmod is an alias to modprobe | ||
36 | - rmmod is an alias to modprobe -r | ||
37 | - depmod generates modules.dep.bb | ||
38 | |||
8 | INSERT | 39 | INSERT |
9 | 40 | ||
10 | comment "Options common to multiple modutils" | 41 | comment "Options common to multiple modutils" |
diff --git a/modutils/depmod.c b/modutils/depmod.c index b9347027e..b7965ebd2 100644 --- a/modutils/depmod.c +++ b/modutils/depmod.c | |||
@@ -9,17 +9,18 @@ | |||
9 | */ | 9 | */ |
10 | //config:config DEPMOD | 10 | //config:config DEPMOD |
11 | //config: bool "depmod" | 11 | //config: bool "depmod" |
12 | //config: default n | 12 | //config: default y |
13 | //config: depends on !MODPROBE_SMALL | ||
14 | //config: select PLATFORM_LINUX | 13 | //config: select PLATFORM_LINUX |
15 | //config: help | 14 | //config: help |
16 | //config: depmod generates modules.dep (and potentially modules.alias | 15 | //config: depmod generates modules.dep (and potentially modules.alias |
17 | //config: and modules.symbols) that contain dependency information | 16 | //config: and modules.symbols) that contain dependency information |
18 | //config: for modprobe. | 17 | //config: for modprobe. |
19 | 18 | ||
20 | //applet:IF_DEPMOD(APPLET(depmod, BB_DIR_SBIN, BB_SUID_DROP)) | 19 | //applet:IF_DEPMOD(IF_NOT_MODPROBE_SMALL(APPLET(depmod, BB_DIR_SBIN, BB_SUID_DROP))) |
21 | 20 | ||
21 | //kbuild:ifneq ($(CONFIG_MODPROBE_SMALL),y) | ||
22 | //kbuild:lib-$(CONFIG_DEPMOD) += depmod.o modutils.o | 22 | //kbuild:lib-$(CONFIG_DEPMOD) += depmod.o modutils.o |
23 | //kbuild:endif | ||
23 | 24 | ||
24 | #include "libbb.h" | 25 | #include "libbb.h" |
25 | #include "modutils.h" | 26 | #include "modutils.h" |
diff --git a/modutils/insmod.c b/modutils/insmod.c index 2ebf4beb9..f2c70e16f 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c | |||
@@ -8,15 +8,16 @@ | |||
8 | */ | 8 | */ |
9 | //config:config INSMOD | 9 | //config:config INSMOD |
10 | //config: bool "insmod" | 10 | //config: bool "insmod" |
11 | //config: default n | 11 | //config: default y |
12 | //config: depends on !MODPROBE_SMALL | ||
13 | //config: select PLATFORM_LINUX | 12 | //config: select PLATFORM_LINUX |
14 | //config: help | 13 | //config: help |
15 | //config: insmod is used to load specified modules in the running kernel. | 14 | //config: insmod is used to load specified modules in the running kernel. |
16 | 15 | ||
17 | //applet:IF_INSMOD(APPLET(insmod, BB_DIR_SBIN, BB_SUID_DROP)) | 16 | //applet:IF_INSMOD(IF_NOT_MODPROBE_SMALL(APPLET(insmod, BB_DIR_SBIN, BB_SUID_DROP))) |
18 | 17 | ||
18 | //kbuild:ifneq ($(CONFIG_MODPROBE_SMALL),y) | ||
19 | //kbuild:lib-$(CONFIG_INSMOD) += insmod.o modutils.o | 19 | //kbuild:lib-$(CONFIG_INSMOD) += insmod.o modutils.o |
20 | //kbuild:endif | ||
20 | 21 | ||
21 | #include "libbb.h" | 22 | #include "libbb.h" |
22 | #include "modutils.h" | 23 | #include "modutils.h" |
diff --git a/modutils/lsmod.c b/modutils/lsmod.c index ee85fb0fb..24589420a 100644 --- a/modutils/lsmod.c +++ b/modutils/lsmod.c | |||
@@ -9,25 +9,26 @@ | |||
9 | */ | 9 | */ |
10 | //config:config LSMOD | 10 | //config:config LSMOD |
11 | //config: bool "lsmod" | 11 | //config: bool "lsmod" |
12 | //config: default n | 12 | //config: default y |
13 | //config: depends on !MODPROBE_SMALL | ||
14 | //config: select PLATFORM_LINUX | 13 | //config: select PLATFORM_LINUX |
15 | //config: help | 14 | //config: help |
16 | //config: lsmod is used to display a list of loaded modules. | 15 | //config: lsmod is used to display a list of loaded modules. |
17 | //config: | 16 | //config: |
18 | //config:config FEATURE_LSMOD_PRETTY_2_6_OUTPUT | 17 | //config:config FEATURE_LSMOD_PRETTY_2_6_OUTPUT |
19 | //config: bool "Pretty output" | 18 | //config: bool "Pretty output" |
20 | //config: default n | 19 | //config: default y |
21 | //config: depends on LSMOD | 20 | //config: depends on LSMOD && !MODPROBE_SMALL |
22 | //config: select PLATFORM_LINUX | 21 | //config: select PLATFORM_LINUX |
23 | //config: help | 22 | //config: help |
24 | //config: This option makes output format of lsmod adjusted to | 23 | //config: This option makes output format of lsmod adjusted to |
25 | //config: the format of module-init-tools for Linux kernel 2.6. | 24 | //config: the format of module-init-tools for Linux kernel 2.6. |
26 | //config: Increases size somewhat. | 25 | //config: Increases size somewhat. |
27 | 26 | ||
28 | //applet:IF_LSMOD(APPLET(lsmod, BB_DIR_SBIN, BB_SUID_DROP)) | 27 | //applet:IF_LSMOD(IF_NOT_MODPROBE_SMALL(APPLET(lsmod, BB_DIR_SBIN, BB_SUID_DROP))) |
29 | 28 | ||
29 | //kbuild:ifneq ($(CONFIG_MODPROBE_SMALL),y) | ||
30 | //kbuild:lib-$(CONFIG_LSMOD) += lsmod.o modutils.o | 30 | //kbuild:lib-$(CONFIG_LSMOD) += lsmod.o modutils.o |
31 | //kbuild:endif | ||
31 | 32 | ||
32 | //usage:#if !ENABLE_MODPROBE_SMALL | 33 | //usage:#if !ENABLE_MODPROBE_SMALL |
33 | //usage:#define lsmod_trivial_usage | 34 | //usage:#define lsmod_trivial_usage |
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 51ba42f7a..0fc9ea454 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
@@ -7,37 +7,9 @@ | |||
7 | * | 7 | * |
8 | * Licensed under GPLv2, see file LICENSE in this source tree. | 8 | * Licensed under GPLv2, see file LICENSE in this source tree. |
9 | */ | 9 | */ |
10 | //config:config MODPROBE_SMALL | 10 | |
11 | //config: bool "Simplified modutils" | 11 | /* config MODPROBE_SMALL is defined in Config.src to ensure better "make config" order */ |
12 | //config: default y | 12 | |
13 | //config: select PLATFORM_LINUX | ||
14 | //config: help | ||
15 | //config: Simplified modutils. | ||
16 | //config: | ||
17 | //config: With this option modprobe does not require modules.dep file | ||
18 | //config: and does not use /etc/modules.conf file. | ||
19 | //config: It scans module files in /lib/modules/`uname -r` and | ||
20 | //config: determines dependencies and module alias names on the fly. | ||
21 | //config: This may make module loading slower, most notably | ||
22 | //config: when one needs to load module by alias (this requires | ||
23 | //config: scanning through module _bodies_). | ||
24 | //config: | ||
25 | //config: At the first attempt to load a module by alias modprobe | ||
26 | //config: will try to generate modules.dep.bb file in order to speed up | ||
27 | //config: future loads by alias. Failure to do so (read-only /lib/modules, | ||
28 | //config: etc) is not reported, and future modprobes will be slow too. | ||
29 | //config: | ||
30 | //config: NB: modules.dep.bb file format is not compatible | ||
31 | //config: with modules.dep file as created/used by standard module tools. | ||
32 | //config: | ||
33 | //config: Additional module parameters can be stored in | ||
34 | //config: /etc/modules/$module_name files. | ||
35 | //config: | ||
36 | //config: Apart from modprobe, other utilities are also provided: | ||
37 | //config: - insmod is an alias to modprobe | ||
38 | //config: - rmmod is an alias to modprobe -r | ||
39 | //config: - depmod generates modules.dep.bb | ||
40 | //config: | ||
41 | //config:config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 13 | //config:config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE |
42 | //config: bool "Accept module options on modprobe command line" | 14 | //config: bool "Accept module options on modprobe command line" |
43 | //config: default y | 15 | //config: default y |
@@ -53,11 +25,11 @@ | |||
53 | //config: help | 25 | //config: help |
54 | //config: Check if the module is already loaded. | 26 | //config: Check if the module is already loaded. |
55 | 27 | ||
56 | //applet:IF_MODPROBE_SMALL(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP)) | 28 | //applet:IF_MODPROBE(IF_MODPROBE_SMALL(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP))) |
57 | //applet:IF_MODPROBE_SMALL(APPLET_ODDNAME(depmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, depmod)) | 29 | //applet:IF_DEPMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(depmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, depmod))) |
58 | //applet:IF_MODPROBE_SMALL(APPLET_ODDNAME(insmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, insmod)) | 30 | //applet:IF_INSMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(insmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, insmod))) |
59 | //applet:IF_MODPROBE_SMALL(APPLET_ODDNAME(lsmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, lsmod)) | 31 | //applet:IF_LSMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(lsmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, lsmod))) |
60 | //applet:IF_MODPROBE_SMALL(APPLET_ODDNAME(rmmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, rmmod)) | 32 | //applet:IF_RMMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(rmmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, rmmod))) |
61 | 33 | ||
62 | //kbuild:lib-$(CONFIG_MODPROBE_SMALL) += modprobe-small.o | 34 | //kbuild:lib-$(CONFIG_MODPROBE_SMALL) += modprobe-small.o |
63 | 35 | ||
@@ -67,8 +39,8 @@ | |||
67 | #include <fnmatch.h> | 39 | #include <fnmatch.h> |
68 | #include <sys/syscall.h> | 40 | #include <sys/syscall.h> |
69 | 41 | ||
70 | extern int init_module(void *module, unsigned long len, const char *options); | 42 | #define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) |
71 | extern int delete_module(const char *module, unsigned flags); | 43 | #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) |
72 | #ifdef __NR_finit_module | 44 | #ifdef __NR_finit_module |
73 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) | 45 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) |
74 | #endif | 46 | #endif |
@@ -958,7 +930,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
958 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) | 930 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) |
959 | 931 | ||
960 | /* are we lsmod? -> just dump /proc/modules */ | 932 | /* are we lsmod? -> just dump /proc/modules */ |
961 | if ('l' == applet0) { | 933 | if (ENABLE_LSMOD && 'l' == applet0) { |
962 | xprint_and_close_file(xfopen_for_read("/proc/modules")); | 934 | xprint_and_close_file(xfopen_for_read("/proc/modules")); |
963 | return EXIT_SUCCESS; | 935 | return EXIT_SUCCESS; |
964 | } | 936 | } |
@@ -968,14 +940,14 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
968 | /* Prevent ugly corner cases with no modules at all */ | 940 | /* Prevent ugly corner cases with no modules at all */ |
969 | modinfo = xzalloc(sizeof(modinfo[0])); | 941 | modinfo = xzalloc(sizeof(modinfo[0])); |
970 | 942 | ||
971 | if ('i' != applet0) { /* not insmod */ | 943 | if (!ENABLE_INSMOD || 'i' != applet0) { /* not insmod */ |
972 | /* Goto modules directory */ | 944 | /* Goto modules directory */ |
973 | xchdir(CONFIG_DEFAULT_MODULES_DIR); | 945 | xchdir(CONFIG_DEFAULT_MODULES_DIR); |
974 | } | 946 | } |
975 | uname(&uts); /* never fails */ | 947 | uname(&uts); /* never fails */ |
976 | 948 | ||
977 | /* depmod? */ | 949 | /* depmod? */ |
978 | if ('d' == applet0) { | 950 | if (ENABLE_DEPMOD && 'd' == applet0) { |
979 | /* Supported: | 951 | /* Supported: |
980 | * -n: print result to stdout | 952 | * -n: print result to stdout |
981 | * -a: process all modules (default) | 953 | * -a: process all modules (default) |
@@ -1014,11 +986,11 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1014 | argv += optind; | 986 | argv += optind; |
1015 | 987 | ||
1016 | /* are we rmmod? -> simulate modprobe -r */ | 988 | /* are we rmmod? -> simulate modprobe -r */ |
1017 | if ('r' == applet0) { | 989 | if (ENABLE_RMMOD && 'r' == applet0) { |
1018 | option_mask32 |= OPT_r; | 990 | option_mask32 |= OPT_r; |
1019 | } | 991 | } |
1020 | 992 | ||
1021 | if ('i' != applet0) { /* not insmod */ | 993 | if (!ENABLE_INSMOD || 'i' != applet0) { /* not insmod */ |
1022 | /* Goto $VERSION directory */ | 994 | /* Goto $VERSION directory */ |
1023 | xchdir(uts.release); | 995 | xchdir(uts.release); |
1024 | } | 996 | } |
@@ -1042,7 +1014,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1042 | argv[1] = NULL; | 1014 | argv[1] = NULL; |
1043 | #endif | 1015 | #endif |
1044 | 1016 | ||
1045 | if ('i' == applet0) { /* insmod */ | 1017 | if (ENABLE_INSMOD && 'i' == applet0) { /* insmod */ |
1046 | size_t len; | 1018 | size_t len; |
1047 | void *map; | 1019 | void *map; |
1048 | 1020 | ||
@@ -1062,7 +1034,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1062 | } | 1034 | } |
1063 | 1035 | ||
1064 | /* Try to load modprobe.dep.bb */ | 1036 | /* Try to load modprobe.dep.bb */ |
1065 | if ('r' != applet0) { /* not rmmod */ | 1037 | if (!ENABLE_RMMOD || 'r' != applet0) { /* not rmmod */ |
1066 | load_dep_bb(); | 1038 | load_dep_bb(); |
1067 | } | 1039 | } |
1068 | 1040 | ||
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index d404ef92f..09e3de6c3 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
@@ -9,8 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | //config:config MODPROBE | 10 | //config:config MODPROBE |
11 | //config: bool "modprobe" | 11 | //config: bool "modprobe" |
12 | //config: default n | 12 | //config: default y |
13 | //config: depends on !MODPROBE_SMALL | ||
14 | //config: select PLATFORM_LINUX | 13 | //config: select PLATFORM_LINUX |
15 | //config: help | 14 | //config: help |
16 | //config: Handle the loading of modules, and their dependencies on a high | 15 | //config: Handle the loading of modules, and their dependencies on a high |
@@ -18,8 +17,8 @@ | |||
18 | //config: | 17 | //config: |
19 | //config:config FEATURE_MODPROBE_BLACKLIST | 18 | //config:config FEATURE_MODPROBE_BLACKLIST |
20 | //config: bool "Blacklist support" | 19 | //config: bool "Blacklist support" |
21 | //config: default n | 20 | //config: default y |
22 | //config: depends on MODPROBE | 21 | //config: depends on MODPROBE && !MODPROBE_SMALL |
23 | //config: select PLATFORM_LINUX | 22 | //config: select PLATFORM_LINUX |
24 | //config: help | 23 | //config: help |
25 | //config: Say 'y' here to enable support for the 'blacklist' command in | 24 | //config: Say 'y' here to enable support for the 'blacklist' command in |
@@ -28,9 +27,11 @@ | |||
28 | //config: hardware autodetection scripts to load modules like evdev, frame | 27 | //config: hardware autodetection scripts to load modules like evdev, frame |
29 | //config: buffer drivers etc. | 28 | //config: buffer drivers etc. |
30 | 29 | ||
31 | //applet:IF_MODPROBE(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP)) | 30 | //applet:IF_MODPROBE(IF_NOT_MODPROBE_SMALL(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP))) |
32 | 31 | ||
32 | //kbuild:ifneq ($(CONFIG_MODPROBE_SMALL),y) | ||
33 | //kbuild:lib-$(CONFIG_MODPROBE) += modprobe.o modutils.o | 33 | //kbuild:lib-$(CONFIG_MODPROBE) += modprobe.o modutils.o |
34 | //kbuild:endif | ||
34 | 35 | ||
35 | #include "libbb.h" | 36 | #include "libbb.h" |
36 | #include "modutils.h" | 37 | #include "modutils.h" |
diff --git a/modutils/modutils.c b/modutils/modutils.c index d36caaf68..4204f06fe 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c | |||
@@ -7,17 +7,13 @@ | |||
7 | */ | 7 | */ |
8 | #include "modutils.h" | 8 | #include "modutils.h" |
9 | 9 | ||
10 | #ifdef __UCLIBC__ | 10 | #include <sys/syscall.h> |
11 | extern int init_module(void *module, unsigned long len, const char *options); | 11 | |
12 | extern int delete_module(const char *module, unsigned int flags); | 12 | #define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) |
13 | #else | 13 | #if defined(__NR_finit_module) |
14 | # include <sys/syscall.h> | 14 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) |
15 | # define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) | ||
16 | # if defined(__NR_finit_module) | ||
17 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) | ||
18 | # endif | ||
19 | # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) | ||
20 | #endif | 15 | #endif |
16 | #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) | ||
21 | 17 | ||
22 | static module_entry *helper_get_module(module_db *db, const char *module, int create) | 18 | static module_entry *helper_get_module(module_db *db, const char *module, int create) |
23 | { | 19 | { |
diff --git a/modutils/rmmod.c b/modutils/rmmod.c index e0358838a..527696f63 100644 --- a/modutils/rmmod.c +++ b/modutils/rmmod.c | |||
@@ -9,15 +9,16 @@ | |||
9 | */ | 9 | */ |
10 | //config:config RMMOD | 10 | //config:config RMMOD |
11 | //config: bool "rmmod" | 11 | //config: bool "rmmod" |
12 | //config: default n | 12 | //config: default y |
13 | //config: depends on !MODPROBE_SMALL | ||
14 | //config: select PLATFORM_LINUX | 13 | //config: select PLATFORM_LINUX |
15 | //config: help | 14 | //config: help |
16 | //config: rmmod is used to unload specified modules from the kernel. | 15 | //config: rmmod is used to unload specified modules from the kernel. |
17 | 16 | ||
18 | //applet:IF_RMMOD(APPLET(rmmod, BB_DIR_SBIN, BB_SUID_DROP)) | 17 | //applet:IF_RMMOD(IF_NOT_MODPROBE_SMALL(APPLET(rmmod, BB_DIR_SBIN, BB_SUID_DROP))) |
19 | 18 | ||
19 | //kbuild:ifneq ($(CONFIG_MODPROBE_SMALL),y) | ||
20 | //kbuild:lib-$(CONFIG_RMMOD) += rmmod.o modutils.o | 20 | //kbuild:lib-$(CONFIG_RMMOD) += rmmod.o modutils.o |
21 | //kbuild:endif | ||
21 | 22 | ||
22 | //usage:#if !ENABLE_MODPROBE_SMALL | 23 | //usage:#if !ENABLE_MODPROBE_SMALL |
23 | //usage:#define rmmod_trivial_usage | 24 | //usage:#define rmmod_trivial_usage |
diff --git a/networking/Config.src b/networking/Config.src index 527bdd15d..0adb1e2f9 100644 --- a/networking/Config.src +++ b/networking/Config.src | |||
@@ -53,7 +53,7 @@ source networking/udhcp/Config.in | |||
53 | config IFUPDOWN_UDHCPC_CMD_OPTIONS | 53 | config IFUPDOWN_UDHCPC_CMD_OPTIONS |
54 | string "ifup udhcpc command line options" | 54 | string "ifup udhcpc command line options" |
55 | default "-R -n" | 55 | default "-R -n" |
56 | depends on IFUPDOWN && UDHCPC | 56 | depends on IFUP || IFDOWN |
57 | help | 57 | help |
58 | Command line options to pass to udhcpc from ifup. | 58 | Command line options to pass to udhcpc from ifup. |
59 | Intended to alter options not available in /etc/network/interfaces. | 59 | Intended to alter options not available in /etc/network/interfaces. |
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 7ac517afd..1806a6ccc 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -51,41 +51,19 @@ | |||
51 | //config: This config option defines location of ifstate. | 51 | //config: This config option defines location of ifstate. |
52 | //config: | 52 | //config: |
53 | //config:config FEATURE_IFUPDOWN_IP | 53 | //config:config FEATURE_IFUPDOWN_IP |
54 | //config: bool "Use ip applet" | 54 | //config: bool "Use ip tool (else ifconfig/route is used)" |
55 | //config: default y | 55 | //config: default y |
56 | //config: depends on IFUP || IFDOWN | 56 | //config: depends on IFUP || IFDOWN |
57 | //config: help | 57 | //config: help |
58 | //config: Use the iproute "ip" command to implement "ifup" and "ifdown", rather | 58 | //config: Use the iproute "ip" command to implement "ifup" and "ifdown", rather |
59 | //config: than the default of using the older 'ifconfig' and 'route' utilities. | 59 | //config: than the default of using the older "ifconfig" and "route" utilities. |
60 | //config: | 60 | //config: |
61 | //config:config FEATURE_IFUPDOWN_IP_BUILTIN | 61 | //config: If Y: you must install either the full-blown iproute2 package |
62 | //config: bool "Use busybox ip applet" | 62 | //config: or enable "ip" applet in Busybox, or the "ifup" and "ifdown" applets |
63 | //config: default y | 63 | //config: will not work. |
64 | //config: depends on FEATURE_IFUPDOWN_IP | ||
65 | //config: select PLATFORM_LINUX | ||
66 | //config: select IP | ||
67 | //config: select FEATURE_IP_ADDRESS | ||
68 | //config: select FEATURE_IP_LINK | ||
69 | //config: select FEATURE_IP_ROUTE | ||
70 | //config: help | ||
71 | //config: Use the busybox iproute "ip" applet to implement "ifupdown". | ||
72 | //config: | ||
73 | //config: If left disabled, you must install the full-blown iproute2 | ||
74 | //config: utility or the "ifup" and "ifdown" applets will not work. | ||
75 | //config: | ||
76 | //config:config FEATURE_IFUPDOWN_IFCONFIG_BUILTIN | ||
77 | //config: bool "Use busybox ifconfig and route applets" | ||
78 | //config: default n | ||
79 | //config: depends on (IFUP || IFDOWN) && !FEATURE_IFUPDOWN_IP | ||
80 | //config: select IFCONFIG | ||
81 | //config: select ROUTE | ||
82 | //config: help | ||
83 | //config: Use the busybox iproute "ifconfig" and "route" applets to | ||
84 | //config: implement the "ifup" and "ifdown" utilities. | ||
85 | //config: | 64 | //config: |
86 | //config: If left disabled, you must install the full-blown ifconfig | 65 | //config: If N: you must install either the full-blown ifconfig and route |
87 | //config: and route utilities, or the "ifup" and "ifdown" applets will not | 66 | //config: utilities, or enable these applets in Busybox. |
88 | //config: work. | ||
89 | //config: | 67 | //config: |
90 | //config:config FEATURE_IFUPDOWN_IPV4 | 68 | //config:config FEATURE_IFUPDOWN_IPV4 |
91 | //config: bool "Support for IPv4" | 69 | //config: bool "Support for IPv4" |
diff --git a/networking/ip.c b/networking/ip.c index c3607b74f..939721e46 100644 --- a/networking/ip.c +++ b/networking/ip.c | |||
@@ -17,24 +17,72 @@ | |||
17 | //config: utility. You generally don't need "ip" to use busybox with | 17 | //config: utility. You generally don't need "ip" to use busybox with |
18 | //config: TCP/IP. | 18 | //config: TCP/IP. |
19 | //config: | 19 | //config: |
20 | //config:config IPADDR | ||
21 | //config: bool "ipaddr" | ||
22 | //config: default y | ||
23 | //config: select FEATURE_IP_ADDRESS | ||
24 | //config: select PLATFORM_LINUX | ||
25 | //config: help | ||
26 | //config: Support short form of ip addr: ipaddr | ||
27 | //config: | ||
28 | //config:config IPLINK | ||
29 | //config: bool "iplink" | ||
30 | //config: default y | ||
31 | //config: select FEATURE_IP_LINK | ||
32 | //config: select PLATFORM_LINUX | ||
33 | //config: help | ||
34 | //config: Support short form of ip link: iplink | ||
35 | //config: | ||
36 | //config:config IPROUTE | ||
37 | //config: bool "iproute" | ||
38 | //config: default y | ||
39 | //config: select FEATURE_IP_ROUTE | ||
40 | //config: select PLATFORM_LINUX | ||
41 | //config: help | ||
42 | //config: Support short form of ip route: iproute | ||
43 | //config: | ||
44 | //config:config IPTUNNEL | ||
45 | //config: bool "iptunnel" | ||
46 | //config: default y | ||
47 | //config: select FEATURE_IP_TUNNEL | ||
48 | //config: select PLATFORM_LINUX | ||
49 | //config: help | ||
50 | //config: Support short form of ip tunnel: iptunnel | ||
51 | //config: | ||
52 | //config:config IPRULE | ||
53 | //config: bool "iprule" | ||
54 | //config: default y | ||
55 | //config: select FEATURE_IP_RULE | ||
56 | //config: select PLATFORM_LINUX | ||
57 | //config: help | ||
58 | //config: Support short form of ip rule: iprule | ||
59 | //config: | ||
60 | //config:config IPNEIGH | ||
61 | //config: bool "ipneigh" | ||
62 | //config: default y | ||
63 | //config: select FEATURE_IP_NEIGH | ||
64 | //config: select PLATFORM_LINUX | ||
65 | //config: help | ||
66 | //config: Support short form of ip neigh: ipneigh | ||
67 | //config: | ||
20 | //config:config FEATURE_IP_ADDRESS | 68 | //config:config FEATURE_IP_ADDRESS |
21 | //config: bool "ip address" | 69 | //config: bool "ip address" |
22 | //config: default y | 70 | //config: default y |
23 | //config: depends on IP | 71 | //config: depends on IP || IPADDR |
24 | //config: help | 72 | //config: help |
25 | //config: Address manipulation support for the "ip" applet. | 73 | //config: Address manipulation support for the "ip" applet. |
26 | //config: | 74 | //config: |
27 | //config:config FEATURE_IP_LINK | 75 | //config:config FEATURE_IP_LINK |
28 | //config: bool "ip link" | 76 | //config: bool "ip link" |
29 | //config: default y | 77 | //config: default y |
30 | //config: depends on IP | 78 | //config: depends on IP || IPLINK |
31 | //config: help | 79 | //config: help |
32 | //config: Configure network devices with "ip". | 80 | //config: Configure network devices with "ip". |
33 | //config: | 81 | //config: |
34 | //config:config FEATURE_IP_ROUTE | 82 | //config:config FEATURE_IP_ROUTE |
35 | //config: bool "ip route" | 83 | //config: bool "ip route" |
36 | //config: default y | 84 | //config: default y |
37 | //config: depends on IP | 85 | //config: depends on IP || IPROUTE |
38 | //config: help | 86 | //config: help |
39 | //config: Add support for routing table management to "ip". | 87 | //config: Add support for routing table management to "ip". |
40 | //config: | 88 | //config: |
@@ -48,83 +96,35 @@ | |||
48 | //config:config FEATURE_IP_TUNNEL | 96 | //config:config FEATURE_IP_TUNNEL |
49 | //config: bool "ip tunnel" | 97 | //config: bool "ip tunnel" |
50 | //config: default y | 98 | //config: default y |
51 | //config: depends on IP | 99 | //config: depends on IP || IPTUNNEL |
52 | //config: help | 100 | //config: help |
53 | //config: Add support for tunneling commands to "ip". | 101 | //config: Add support for tunneling commands to "ip". |
54 | //config: | 102 | //config: |
55 | //config:config FEATURE_IP_RULE | 103 | //config:config FEATURE_IP_RULE |
56 | //config: bool "ip rule" | 104 | //config: bool "ip rule" |
57 | //config: default y | 105 | //config: default y |
58 | //config: depends on IP | 106 | //config: depends on IP || IPRULE |
59 | //config: help | 107 | //config: help |
60 | //config: Add support for rule commands to "ip". | 108 | //config: Add support for rule commands to "ip". |
61 | //config: | 109 | //config: |
62 | //config:config FEATURE_IP_NEIGH | 110 | //config:config FEATURE_IP_NEIGH |
63 | //config: bool "ip neighbor" | 111 | //config: bool "ip neighbor" |
64 | //config: default y | 112 | //config: default y |
65 | //config: depends on IP | 113 | //config: depends on IP || IPNEIGH |
66 | //config: help | 114 | //config: help |
67 | //config: Add support for neighbor commands to "ip". | 115 | //config: Add support for neighbor commands to "ip". |
68 | //config: | 116 | //config: |
69 | //config:config FEATURE_IP_SHORT_FORMS | ||
70 | //config: bool "Support short forms of ip commands" | ||
71 | //config: default y | ||
72 | //config: depends on IP | ||
73 | //config: help | ||
74 | //config: Also support short-form of ip <OBJECT> commands: | ||
75 | //config: ip addr -> ipaddr | ||
76 | //config: ip link -> iplink | ||
77 | //config: ip route -> iproute | ||
78 | //config: ip tunnel -> iptunnel | ||
79 | //config: ip rule -> iprule | ||
80 | //config: ip neigh -> ipneigh | ||
81 | //config: | ||
82 | //config: Say N unless you desparately need the short form of the ip | ||
83 | //config: object commands. | ||
84 | //config: | ||
85 | //config:config FEATURE_IP_RARE_PROTOCOLS | 117 | //config:config FEATURE_IP_RARE_PROTOCOLS |
86 | //config: bool "Support displaying rarely used link types" | 118 | //config: bool "Support displaying rarely used link types" |
87 | //config: default n | 119 | //config: default n |
88 | //config: depends on IP | 120 | //config: depends on IP || IPADDR || IPLINK || IPROUTE || IPTUNNEL || IPRULE || IPNEIGH |
89 | //config: help | 121 | //config: help |
90 | //config: If you are not going to use links of type "frad", "econet", | 122 | //config: If you are not going to use links of type "frad", "econet", |
91 | //config: "bif" etc, you probably don't need to enable this. | 123 | //config: "bif" etc, you probably don't need to enable this. |
92 | //config: Ethernet, wireless, infrared, ppp/slip, ip tunnelling | 124 | //config: Ethernet, wireless, infrared, ppp/slip, ip tunnelling |
93 | //config: link types are supported without this option selected. | 125 | //config: link types are supported without this option selected. |
94 | //config: | ||
95 | //config:config IPADDR | ||
96 | //config: bool | ||
97 | //config: default y | ||
98 | //config: depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_ADDRESS | ||
99 | //config: | ||
100 | //config:config IPLINK | ||
101 | //config: bool | ||
102 | //config: default y | ||
103 | //config: depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_LINK | ||
104 | //config: | ||
105 | //config:config IPROUTE | ||
106 | //config: bool | ||
107 | //config: default y | ||
108 | //config: depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_ROUTE | ||
109 | //config: | ||
110 | //config:config IPTUNNEL | ||
111 | //config: bool | ||
112 | //config: default y | ||
113 | //config: depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_TUNNEL | ||
114 | //config: | ||
115 | //config:config IPRULE | ||
116 | //config: bool | ||
117 | //config: default y | ||
118 | //config: depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_RULE | ||
119 | //config: | ||
120 | //config:config IPNEIGH | ||
121 | //config: bool | ||
122 | //config: default y | ||
123 | //config: depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_NEIGH | ||
124 | 126 | ||
125 | //applet:#if ENABLE_FEATURE_IP_ADDRESS || ENABLE_FEATURE_IP_ROUTE || ENABLE_FEATURE_IP_LINK || ENABLE_FEATURE_IP_TUNNEL || ENABLE_FEATURE_IP_RULE || ENABLE_FEATURE_IP_NEIGH | ||
126 | //applet:IF_IP(APPLET(ip, BB_DIR_SBIN, BB_SUID_DROP)) | 127 | //applet:IF_IP(APPLET(ip, BB_DIR_SBIN, BB_SUID_DROP)) |
127 | //applet:#endif | ||
128 | //applet:IF_IPADDR(APPLET(ipaddr, BB_DIR_SBIN, BB_SUID_DROP)) | 128 | //applet:IF_IPADDR(APPLET(ipaddr, BB_DIR_SBIN, BB_SUID_DROP)) |
129 | //applet:IF_IPLINK(APPLET(iplink, BB_DIR_SBIN, BB_SUID_DROP)) | 129 | //applet:IF_IPLINK(APPLET(iplink, BB_DIR_SBIN, BB_SUID_DROP)) |
130 | //applet:IF_IPROUTE(APPLET(iproute, BB_DIR_SBIN, BB_SUID_DROP)) | 130 | //applet:IF_IPROUTE(APPLET(iproute, BB_DIR_SBIN, BB_SUID_DROP)) |
@@ -133,6 +133,12 @@ | |||
133 | //applet:IF_IPNEIGH(APPLET(ipneigh, BB_DIR_SBIN, BB_SUID_DROP)) | 133 | //applet:IF_IPNEIGH(APPLET(ipneigh, BB_DIR_SBIN, BB_SUID_DROP)) |
134 | 134 | ||
135 | //kbuild:lib-$(CONFIG_IP) += ip.o | 135 | //kbuild:lib-$(CONFIG_IP) += ip.o |
136 | //kbuild:lib-$(CONFIG_IPADDR) += ip.o | ||
137 | //kbuild:lib-$(CONFIG_IPLINK) += ip.o | ||
138 | //kbuild:lib-$(CONFIG_IPROUTE) += ip.o | ||
139 | //kbuild:lib-$(CONFIG_IPRULE) += ip.o | ||
140 | //kbuild:lib-$(CONFIG_IPTUNNEL) += ip.o | ||
141 | //kbuild:lib-$(CONFIG_IPNEIGH) += ip.o | ||
136 | 142 | ||
137 | /* would need to make the " | " optional depending on more than one selected: */ | 143 | /* would need to make the " | " optional depending on more than one selected: */ |
138 | //usage:#define ip_trivial_usage | 144 | //usage:#define ip_trivial_usage |
@@ -218,62 +224,57 @@ | |||
218 | #include "libiproute/utils.h" | 224 | #include "libiproute/utils.h" |
219 | #include "libiproute/ip_common.h" | 225 | #include "libiproute/ip_common.h" |
220 | 226 | ||
221 | #if ENABLE_FEATURE_IP_ADDRESS \ | ||
222 | || ENABLE_FEATURE_IP_ROUTE \ | ||
223 | || ENABLE_FEATURE_IP_LINK \ | ||
224 | || ENABLE_FEATURE_IP_TUNNEL \ | ||
225 | || ENABLE_FEATURE_IP_RULE \ | ||
226 | || ENABLE_FEATURE_IP_NEIGH | ||
227 | |||
228 | static int FAST_FUNC ip_print_help(char **argv UNUSED_PARAM) | ||
229 | { | ||
230 | bb_show_usage(); | ||
231 | } | ||
232 | |||
233 | typedef int FAST_FUNC (*ip_func_ptr_t)(char**); | 227 | typedef int FAST_FUNC (*ip_func_ptr_t)(char**); |
234 | 228 | ||
229 | #if ENABLE_IPADDR \ | ||
230 | || ENABLE_IPLINK \ | ||
231 | || ENABLE_IPROUTE \ | ||
232 | || ENABLE_IPRULE \ | ||
233 | || ENABLE_IPTUNNEL \ | ||
234 | || ENABLE_IPNEIGH | ||
235 | static int ip_do(ip_func_ptr_t ip_func, char **argv) | 235 | static int ip_do(ip_func_ptr_t ip_func, char **argv) |
236 | { | 236 | { |
237 | argv = ip_parse_common_args(argv + 1); | 237 | argv = ip_parse_common_args(argv + 1); |
238 | return ip_func(argv); | 238 | return ip_func(argv); |
239 | } | 239 | } |
240 | #endif | ||
240 | 241 | ||
241 | #if ENABLE_FEATURE_IP_ADDRESS | 242 | #if ENABLE_IPADDR |
242 | int ipaddr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 243 | int ipaddr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
243 | int ipaddr_main(int argc UNUSED_PARAM, char **argv) | 244 | int ipaddr_main(int argc UNUSED_PARAM, char **argv) |
244 | { | 245 | { |
245 | return ip_do(do_ipaddr, argv); | 246 | return ip_do(do_ipaddr, argv); |
246 | } | 247 | } |
247 | #endif | 248 | #endif |
248 | #if ENABLE_FEATURE_IP_LINK | 249 | #if ENABLE_IPLINK |
249 | int iplink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 250 | int iplink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
250 | int iplink_main(int argc UNUSED_PARAM, char **argv) | 251 | int iplink_main(int argc UNUSED_PARAM, char **argv) |
251 | { | 252 | { |
252 | return ip_do(do_iplink, argv); | 253 | return ip_do(do_iplink, argv); |
253 | } | 254 | } |
254 | #endif | 255 | #endif |
255 | #if ENABLE_FEATURE_IP_ROUTE | 256 | #if ENABLE_IPROUTE |
256 | int iproute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 257 | int iproute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
257 | int iproute_main(int argc UNUSED_PARAM, char **argv) | 258 | int iproute_main(int argc UNUSED_PARAM, char **argv) |
258 | { | 259 | { |
259 | return ip_do(do_iproute, argv); | 260 | return ip_do(do_iproute, argv); |
260 | } | 261 | } |
261 | #endif | 262 | #endif |
262 | #if ENABLE_FEATURE_IP_RULE | 263 | #if ENABLE_IPRULE |
263 | int iprule_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 264 | int iprule_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
264 | int iprule_main(int argc UNUSED_PARAM, char **argv) | 265 | int iprule_main(int argc UNUSED_PARAM, char **argv) |
265 | { | 266 | { |
266 | return ip_do(do_iprule, argv); | 267 | return ip_do(do_iprule, argv); |
267 | } | 268 | } |
268 | #endif | 269 | #endif |
269 | #if ENABLE_FEATURE_IP_TUNNEL | 270 | #if ENABLE_IPTUNNEL |
270 | int iptunnel_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 271 | int iptunnel_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
271 | int iptunnel_main(int argc UNUSED_PARAM, char **argv) | 272 | int iptunnel_main(int argc UNUSED_PARAM, char **argv) |
272 | { | 273 | { |
273 | return ip_do(do_iptunnel, argv); | 274 | return ip_do(do_iptunnel, argv); |
274 | } | 275 | } |
275 | #endif | 276 | #endif |
276 | #if ENABLE_FEATURE_IP_NEIGH | 277 | #if ENABLE_IPNEIGH |
277 | int ipneigh_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 278 | int ipneigh_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
278 | int ipneigh_main(int argc UNUSED_PARAM, char **argv) | 279 | int ipneigh_main(int argc UNUSED_PARAM, char **argv) |
279 | { | 280 | { |
@@ -281,11 +282,16 @@ int ipneigh_main(int argc UNUSED_PARAM, char **argv) | |||
281 | } | 282 | } |
282 | #endif | 283 | #endif |
283 | 284 | ||
285 | #if ENABLE_IP | ||
286 | static int FAST_FUNC ip_print_help(char **argv UNUSED_PARAM) | ||
287 | { | ||
288 | bb_show_usage(); | ||
289 | } | ||
284 | 290 | ||
285 | int ip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 291 | int ip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
286 | int ip_main(int argc UNUSED_PARAM, char **argv) | 292 | int ip_main(int argc UNUSED_PARAM, char **argv) |
287 | { | 293 | { |
288 | static const char keywords[] ALIGN1 = | 294 | static const char keywords[] ALIGN1 = "" |
289 | IF_FEATURE_IP_ADDRESS("address\0") | 295 | IF_FEATURE_IP_ADDRESS("address\0") |
290 | IF_FEATURE_IP_ROUTE("route\0") | 296 | IF_FEATURE_IP_ROUTE("route\0") |
291 | IF_FEATURE_IP_ROUTE("r\0") | 297 | IF_FEATURE_IP_ROUTE("r\0") |
@@ -310,10 +316,12 @@ int ip_main(int argc UNUSED_PARAM, char **argv) | |||
310 | int key; | 316 | int key; |
311 | 317 | ||
312 | argv = ip_parse_common_args(argv + 1); | 318 | argv = ip_parse_common_args(argv + 1); |
313 | key = *argv ? index_in_substrings(keywords, *argv++) : -1; | 319 | if (ARRAY_SIZE(ip_func_ptrs) > 1 && *argv) |
320 | key = index_in_substrings(keywords, *argv++); | ||
321 | else | ||
322 | key = -1; | ||
314 | ip_func = ip_func_ptrs[key + 1]; | 323 | ip_func = ip_func_ptrs[key + 1]; |
315 | 324 | ||
316 | return ip_func(argv); | 325 | return ip_func(argv); |
317 | } | 326 | } |
318 | 327 | #endif | |
319 | #endif /* any of ENABLE_FEATURE_IP_xxx is 1 */ | ||
diff --git a/networking/libiproute/Kbuild.src b/networking/libiproute/Kbuild.src index c20e2fee8..056a58540 100644 --- a/networking/libiproute/Kbuild.src +++ b/networking/libiproute/Kbuild.src | |||
@@ -62,13 +62,16 @@ lib-$(CONFIG_FEATURE_IP_TUNNEL) += \ | |||
62 | lib-$(CONFIG_FEATURE_IP_RULE) += \ | 62 | lib-$(CONFIG_FEATURE_IP_RULE) += \ |
63 | ip_parse_common_args.o \ | 63 | ip_parse_common_args.o \ |
64 | iprule.o \ | 64 | iprule.o \ |
65 | libnetlink.o \ | ||
65 | rt_names.o \ | 66 | rt_names.o \ |
67 | rtm_map.o \ | ||
66 | utils.o | 68 | utils.o |
67 | 69 | ||
68 | lib-$(CONFIG_FEATURE_IP_NEIGH) += \ | 70 | lib-$(CONFIG_FEATURE_IP_NEIGH) += \ |
69 | ip_parse_common_args.o \ | 71 | ip_parse_common_args.o \ |
70 | ipneigh.o \ | 72 | ipneigh.o \ |
71 | libnetlink.o \ | 73 | libnetlink.o \ |
74 | ll_addr.o \ | ||
72 | ll_map.o \ | 75 | ll_map.o \ |
73 | rt_names.o \ | 76 | rt_names.o \ |
74 | utils.o | 77 | utils.o |
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 48dc6e3d9..0f2b89682 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c | |||
@@ -66,6 +66,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
66 | inet_prefix dst; | 66 | inet_prefix dst; |
67 | inet_prefix src; | 67 | inet_prefix src; |
68 | int host_len = -1; | 68 | int host_len = -1; |
69 | uint32_t tid; | ||
69 | 70 | ||
70 | if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) { | 71 | if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) { |
71 | fprintf(stderr, "Not a route: %08x %08x %08x\n", | 72 | fprintf(stderr, "Not a route: %08x %08x %08x\n", |
@@ -78,6 +79,14 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
78 | if (len < 0) | 79 | if (len < 0) |
79 | bb_error_msg_and_die("wrong nlmsg len %d", len); | 80 | bb_error_msg_and_die("wrong nlmsg len %d", len); |
80 | 81 | ||
82 | memset(tb, 0, sizeof(tb)); | ||
83 | parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); | ||
84 | |||
85 | if (tb[RTA_TABLE]) | ||
86 | tid = *(uint32_t *)RTA_DATA(tb[RTA_TABLE]); | ||
87 | else | ||
88 | tid = r->rtm_table; | ||
89 | |||
81 | if (r->rtm_family == AF_INET6) | 90 | if (r->rtm_family == AF_INET6) |
82 | host_len = 128; | 91 | host_len = 128; |
83 | else if (r->rtm_family == AF_INET) | 92 | else if (r->rtm_family == AF_INET) |
@@ -107,7 +116,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
107 | } | 116 | } |
108 | } | 117 | } |
109 | } else { | 118 | } else { |
110 | if (G_filter.tb > 0 && G_filter.tb != r->rtm_table) { | 119 | if (G_filter.tb > 0 && G_filter.tb != tid) { |
111 | return 0; | 120 | return 0; |
112 | } | 121 | } |
113 | } | 122 | } |
@@ -136,10 +145,8 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
136 | return 0; | 145 | return 0; |
137 | } | 146 | } |
138 | 147 | ||
139 | memset(tb, 0, sizeof(tb)); | ||
140 | memset(&src, 0, sizeof(src)); | 148 | memset(&src, 0, sizeof(src)); |
141 | memset(&dst, 0, sizeof(dst)); | 149 | memset(&dst, 0, sizeof(dst)); |
142 | parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); | ||
143 | 150 | ||
144 | if (tb[RTA_SRC]) { | 151 | if (tb[RTA_SRC]) { |
145 | src.bitlen = r->rtm_src_len; | 152 | src.bitlen = r->rtm_src_len; |
@@ -258,6 +265,10 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
258 | if (tb[RTA_OIF]) { | 265 | if (tb[RTA_OIF]) { |
259 | printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); | 266 | printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); |
260 | } | 267 | } |
268 | #if ENABLE_FEATURE_IP_RULE | ||
269 | if (tid && tid != RT_TABLE_MAIN && !G_filter.tb) | ||
270 | printf("table %s ", rtnl_rttable_n2a(tid)); | ||
271 | #endif | ||
261 | 272 | ||
262 | /* Todo: parse & show "proto kernel", "scope link" here */ | 273 | /* Todo: parse & show "proto kernel", "scope link" here */ |
263 | 274 | ||
@@ -419,7 +430,12 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
419 | NEXT_ARG(); | 430 | NEXT_ARG(); |
420 | if (rtnl_rttable_a2n(&tid, *argv)) | 431 | if (rtnl_rttable_a2n(&tid, *argv)) |
421 | invarg_1_to_2(*argv, "table"); | 432 | invarg_1_to_2(*argv, "table"); |
422 | req.r.rtm_table = tid; | 433 | if (tid < 256) |
434 | req.r.rtm_table = tid; | ||
435 | else { | ||
436 | req.r.rtm_table = RT_TABLE_UNSPEC; | ||
437 | addattr32(&req.n, sizeof(req), RTA_TABLE, tid); | ||
438 | } | ||
423 | #endif | 439 | #endif |
424 | } else if (arg == ARG_dev || arg == ARG_oif) { | 440 | } else if (arg == ARG_dev || arg == ARG_oif) { |
425 | NEXT_ARG(); | 441 | NEXT_ARG(); |
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c index c486834b0..8f3f86286 100644 --- a/networking/libiproute/iprule.c +++ b/networking/libiproute/iprule.c | |||
@@ -114,7 +114,9 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, | |||
114 | printf("iif %s ", (char*)RTA_DATA(tb[RTA_IIF])); | 114 | printf("iif %s ", (char*)RTA_DATA(tb[RTA_IIF])); |
115 | } | 115 | } |
116 | 116 | ||
117 | if (r->rtm_table) | 117 | if (tb[RTA_TABLE]) |
118 | printf("lookup %s ", rtnl_rttable_n2a(*(uint32_t*)RTA_DATA(tb[RTA_TABLE]))); | ||
119 | else if (r->rtm_table) | ||
118 | printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table)); | 120 | printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table)); |
119 | 121 | ||
120 | if (tb[RTA_FLOW]) { | 122 | if (tb[RTA_FLOW]) { |
@@ -256,7 +258,12 @@ static int iprule_modify(int cmd, char **argv) | |||
256 | NEXT_ARG(); | 258 | NEXT_ARG(); |
257 | if (rtnl_rttable_a2n(&tid, *argv)) | 259 | if (rtnl_rttable_a2n(&tid, *argv)) |
258 | invarg_1_to_2(*argv, "table ID"); | 260 | invarg_1_to_2(*argv, "table ID"); |
259 | req.r.rtm_table = tid; | 261 | if (tid < 256) |
262 | req.r.rtm_table = tid; | ||
263 | else { | ||
264 | req.r.rtm_table = RT_TABLE_UNSPEC; | ||
265 | addattr32(&req.n, sizeof(req), RTA_TABLE, tid); | ||
266 | } | ||
260 | table_ok = 1; | 267 | table_ok = 1; |
261 | } else if (key == ARG_dev || | 268 | } else if (key == ARG_dev || |
262 | key == ARG_iif | 269 | key == ARG_iif |
diff --git a/networking/tcpudp.c b/networking/tcpudp.c index 94c89b9ef..3a6c68646 100644 --- a/networking/tcpudp.c +++ b/networking/tcpudp.c | |||
@@ -107,10 +107,10 @@ | |||
107 | #include "libbb.h" | 107 | #include "libbb.h" |
108 | #include "common_bufsiz.h" | 108 | #include "common_bufsiz.h" |
109 | 109 | ||
110 | /* Wants <limits.h> etc, thus included after libbb.h: */ | ||
111 | #ifdef __linux__ | 110 | #ifdef __linux__ |
112 | #include <linux/types.h> /* for __be32 etc */ | 111 | /* from linux/netfilter_ipv4.h: */ |
113 | #include <linux/netfilter_ipv4.h> | 112 | # undef SO_ORIGINAL_DST |
113 | # define SO_ORIGINAL_DST 80 | ||
114 | #endif | 114 | #endif |
115 | 115 | ||
116 | // TODO: move into this file: | 116 | // TODO: move into this file: |
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index c34c8d6f0..90fb313b5 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src | |||
@@ -16,7 +16,6 @@ config UDHCPD | |||
16 | config DHCPRELAY | 16 | config DHCPRELAY |
17 | bool "dhcprelay" | 17 | bool "dhcprelay" |
18 | default y | 18 | default y |
19 | depends on UDHCPD | ||
20 | help | 19 | help |
21 | dhcprelay listens for dhcp requests on one or more interfaces | 20 | dhcprelay listens for dhcp requests on one or more interfaces |
22 | and forwards these requests to a different interface or dhcp | 21 | and forwards these requests to a different interface or dhcp |
@@ -25,7 +24,6 @@ config DHCPRELAY | |||
25 | config DUMPLEASES | 24 | config DUMPLEASES |
26 | bool "Lease display utility (dumpleases)" | 25 | bool "Lease display utility (dumpleases)" |
27 | default y | 26 | default y |
28 | depends on UDHCPD | ||
29 | help | 27 | help |
30 | dumpleases displays the leases written out by the udhcpd server. | 28 | dumpleases displays the leases written out by the udhcpd server. |
31 | Lease times are stored in the file by time remaining in lease, or | 29 | Lease times are stored in the file by time remaining in lease, or |
diff --git a/networking/udhcp/Kbuild.src b/networking/udhcp/Kbuild.src index 5ea77df06..fcb725fbc 100644 --- a/networking/udhcp/Kbuild.src +++ b/networking/udhcp/Kbuild.src | |||
@@ -15,7 +15,7 @@ lib-$(CONFIG_UDHCPD) += common.o packet.o signalpipe.o socket.o | |||
15 | lib-$(CONFIG_UDHCPC) += dhcpc.o | 15 | lib-$(CONFIG_UDHCPC) += dhcpc.o |
16 | lib-$(CONFIG_UDHCPD) += dhcpd.o arpping.o | 16 | lib-$(CONFIG_UDHCPD) += dhcpd.o arpping.o |
17 | lib-$(CONFIG_DUMPLEASES) += dumpleases.o | 17 | lib-$(CONFIG_DUMPLEASES) += dumpleases.o |
18 | lib-$(CONFIG_DHCPRELAY) += dhcprelay.o | 18 | lib-$(CONFIG_DHCPRELAY) += dhcprelay.o common.o socket.o packet.o |
19 | 19 | ||
20 | lib-$(CONFIG_FEATURE_UDHCPC_ARPING) += arpping.o | 20 | lib-$(CONFIG_FEATURE_UDHCPC_ARPING) += arpping.o |
21 | lib-$(CONFIG_FEATURE_UDHCP_RFC3397) += domain_codec.o | 21 | lib-$(CONFIG_FEATURE_UDHCP_RFC3397) += domain_codec.o |
diff --git a/procps/Kbuild.src b/procps/Kbuild.src index 83af05a05..e7adc7340 100644 --- a/procps/Kbuild.src +++ b/procps/Kbuild.src | |||
@@ -9,3 +9,5 @@ lib-y:= | |||
9 | INSERT | 9 | INSERT |
10 | 10 | ||
11 | lib-$(CONFIG_ASH) += kill.o # used for built-in kill by ash | 11 | lib-$(CONFIG_ASH) += kill.o # used for built-in kill by ash |
12 | lib-$(CONFIG_SH_IS_ASH) += kill.o # used for built-in kill by ash | ||
13 | lib-$(CONFIG_BASH_IS_ASH) += kill.o # used for built-in kill by ash | ||
diff --git a/procps/top.c b/procps/top.c index c66cdb764..71207bac1 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -1042,7 +1042,9 @@ static unsigned handle_input(unsigned scan_mask, unsigned interval) | |||
1042 | //usage: "Provide a view of process activity in real time." | 1042 | //usage: "Provide a view of process activity in real time." |
1043 | //usage: "\n""Read the status of all processes from /proc each SECONDS" | 1043 | //usage: "\n""Read the status of all processes from /proc each SECONDS" |
1044 | //usage: "\n""and display a screenful of them." | 1044 | //usage: "\n""and display a screenful of them." |
1045 | //usage: "\n""Keys:" | 1045 | //usage: "\n" |
1046 | //usage: IF_FEATURE_USE_TERMIOS( | ||
1047 | //usage: "Keys:" | ||
1046 | //usage: "\n"" N/M" | 1048 | //usage: "\n"" N/M" |
1047 | //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/P") | 1049 | //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/P") |
1048 | //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/T") | 1050 | //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/T") |
@@ -1062,6 +1064,7 @@ static unsigned handle_input(unsigned scan_mask, unsigned interval) | |||
1062 | //usage: "\n"" Q,^C: exit" | 1064 | //usage: "\n"" Q,^C: exit" |
1063 | //usage: "\n" | 1065 | //usage: "\n" |
1064 | //usage: "\n""Options:" | 1066 | //usage: "\n""Options:" |
1067 | //usage: ) | ||
1065 | //usage: "\n"" -b Batch mode" | 1068 | //usage: "\n"" -b Batch mode" |
1066 | //usage: "\n"" -n N Exit after N iterations" | 1069 | //usage: "\n"" -n N Exit after N iterations" |
1067 | //usage: "\n"" -d N Delay between updates" | 1070 | //usage: "\n"" -d N Delay between updates" |
diff --git a/runit/sv.c b/runit/sv.c index 42abbbbb5..9e2132259 100644 --- a/runit/sv.c +++ b/runit/sv.c | |||
@@ -166,26 +166,19 @@ Exit Codes | |||
166 | //config: help | 166 | //config: help |
167 | //config: Default directory for services. | 167 | //config: Default directory for services. |
168 | //config: Defaults to "/var/service" | 168 | //config: Defaults to "/var/service" |
169 | //config: | ||
170 | //config:config SVC | ||
171 | //config: bool "svc" | ||
172 | //config: default y | ||
173 | //config: help | ||
174 | //config: svc controls the state of services monitored by the runsv supervisor. | ||
175 | //config: It is comaptible with daemontools command with the same name. | ||
169 | 176 | ||
170 | //applet:IF_SV(APPLET(sv, BB_DIR_USR_BIN, BB_SUID_DROP)) | 177 | //applet:IF_SV(APPLET(sv, BB_DIR_USR_BIN, BB_SUID_DROP)) |
178 | //applet:IF_SVC(APPLET(svc, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
171 | 179 | ||
172 | //kbuild:lib-$(CONFIG_SV) += sv.o | 180 | //kbuild:lib-$(CONFIG_SV) += sv.o |
173 | 181 | //kbuild:lib-$(CONFIG_SVC) += sv.o | |
174 | //usage:#define sv_trivial_usage | ||
175 | //usage: "[-v] [-w SEC] CMD SERVICE_DIR..." | ||
176 | //usage:#define sv_full_usage "\n\n" | ||
177 | //usage: "Control services monitored by runsv supervisor.\n" | ||
178 | //usage: "Commands (only first character is enough):\n" | ||
179 | //usage: "\n" | ||
180 | //usage: "status: query service status\n" | ||
181 | //usage: "up: if service isn't running, start it. If service stops, restart it\n" | ||
182 | //usage: "once: like 'up', but if service stops, don't restart it\n" | ||
183 | //usage: "down: send TERM and CONT signals. If ./run exits, start ./finish\n" | ||
184 | //usage: " if it exists. After it stops, don't restart service\n" | ||
185 | //usage: "exit: send TERM and CONT signals to service and log service. If they exit,\n" | ||
186 | //usage: " runsv exits too\n" | ||
187 | //usage: "pause, cont, hup, alarm, interrupt, quit, 1, 2, term, kill: send\n" | ||
188 | //usage: "STOP, CONT, HUP, ALRM, INT, QUIT, USR1, USR2, TERM, KILL signal to service" | ||
189 | 182 | ||
190 | #include <sys/file.h> | 183 | #include <sys/file.h> |
191 | #include "libbb.h" | 184 | #include "libbb.h" |
@@ -452,8 +445,22 @@ static int control(const char *a) | |||
452 | return 1; | 445 | return 1; |
453 | } | 446 | } |
454 | 447 | ||
455 | int sv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 448 | //usage:#define sv_trivial_usage |
456 | int sv_main(int argc UNUSED_PARAM, char **argv) | 449 | //usage: "[-v] [-w SEC] CMD SERVICE_DIR..." |
450 | //usage:#define sv_full_usage "\n\n" | ||
451 | //usage: "Control services monitored by runsv supervisor.\n" | ||
452 | //usage: "Commands (only first character is enough):\n" | ||
453 | //usage: "\n" | ||
454 | //usage: "status: query service status\n" | ||
455 | //usage: "up: if service isn't running, start it. If service stops, restart it\n" | ||
456 | //usage: "once: like 'up', but if service stops, don't restart it\n" | ||
457 | //usage: "down: send TERM and CONT signals. If ./run exits, start ./finish\n" | ||
458 | //usage: " if it exists. After it stops, don't restart service\n" | ||
459 | //usage: "exit: send TERM and CONT signals to service and log service. If they exit,\n" | ||
460 | //usage: " runsv exits too\n" | ||
461 | //usage: "pause, cont, hup, alarm, interrupt, quit, 1, 2, term, kill: send\n" | ||
462 | //usage: "STOP, CONT, HUP, ALRM, INT, QUIT, USR1, USR2, TERM, KILL signal to service" | ||
463 | static int sv(char **argv) | ||
457 | { | 464 | { |
458 | char *x; | 465 | char *x; |
459 | char *action; | 466 | char *action; |
@@ -634,3 +641,72 @@ int sv_main(int argc UNUSED_PARAM, char **argv) | |||
634 | } | 641 | } |
635 | return rc > 99 ? 99 : rc; | 642 | return rc > 99 ? 99 : rc; |
636 | } | 643 | } |
644 | |||
645 | #if ENABLE_SV | ||
646 | int sv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
647 | int sv_main(int argc UNUSED_PARAM, char **argv) | ||
648 | { | ||
649 | return sv(argv); | ||
650 | } | ||
651 | #endif | ||
652 | |||
653 | //usage:#define svc_trivial_usage | ||
654 | //usage: "[-udopchaitkx] SERVICE_DIR..." | ||
655 | //usage:#define svc_full_usage "\n\n" | ||
656 | //usage: "Control services monitored by runsv supervisor" | ||
657 | //usage: "\n" | ||
658 | //usage: "\n"" -u If service is not running, start it; restart if it stops" | ||
659 | //usage: "\n"" -d If service is running, send TERM+CONT signals; do not restart it" | ||
660 | //usage: "\n"" -o Once: if service is not running, start it; do not restart it" | ||
661 | //usage: "\n"" -pchaitk Send STOP, CONT, HUP, ALRM, INT, TERM, KILL signal to service" | ||
662 | //usage: "\n"" -x Exit: runsv will exit as soon as the service is down" | ||
663 | #if ENABLE_SVC | ||
664 | int svc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
665 | int svc_main(int argc UNUSED_PARAM, char **argv) | ||
666 | { | ||
667 | char command[2]; | ||
668 | const char *optstring; | ||
669 | unsigned opts; | ||
670 | |||
671 | INIT_G(); | ||
672 | |||
673 | optstring = "udopchaitkx"; | ||
674 | opts = getopt32(argv, optstring); | ||
675 | argv += optind; | ||
676 | if (!argv[0] || !opts) | ||
677 | bb_show_usage(); | ||
678 | |||
679 | argv -= 2; | ||
680 | if (optind > 2) { | ||
681 | argv--; | ||
682 | argv[2] = (char*)"--"; | ||
683 | } | ||
684 | argv[0] = (char*)"sv"; | ||
685 | argv[1] = command; | ||
686 | command[1] = '\0'; | ||
687 | |||
688 | /* getopt32() was already called: | ||
689 | * reset the libc getopt() function, which keeps internal state. | ||
690 | */ | ||
691 | #ifdef __GLIBC__ | ||
692 | optind = 0; | ||
693 | #else /* BSD style */ | ||
694 | optind = 1; | ||
695 | /* optreset = 1; */ | ||
696 | #endif | ||
697 | |||
698 | do { | ||
699 | if (opts & 1) { | ||
700 | int r; | ||
701 | command[0] = *optstring; | ||
702 | r = sv(argv); | ||
703 | if (r) | ||
704 | return 1; | ||
705 | } | ||
706 | optstring++; | ||
707 | opts >>= 1; | ||
708 | } while (opts); | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | #endif | ||
diff --git a/scripts/randomtest.loop b/scripts/randomtest.loop index 758a8e862..710f5fd05 100755 --- a/scripts/randomtest.loop +++ b/scripts/randomtest.loop | |||
@@ -33,6 +33,7 @@ while sleep 1; do | |||
33 | ) | 33 | ) |
34 | if test $? != 0; then | 34 | if test $? != 0; then |
35 | echo "Failed runtest in $dir" | 35 | echo "Failed runtest in $dir" |
36 | grep ^FAIL -- "$dir/testsuite/runtest.log" | ||
36 | exit 1 # you may comment this out... | 37 | exit 1 # you may comment this out... |
37 | let fail++ | 38 | let fail++ |
38 | continue | 39 | continue |
diff --git a/selinux/runcon.c b/selinux/runcon.c index 366834e46..16f171101 100644 --- a/selinux/runcon.c +++ b/selinux/runcon.c | |||
@@ -68,7 +68,9 @@ | |||
68 | //usage: ) | 68 | //usage: ) |
69 | 69 | ||
70 | #include <selinux/context.h> | 70 | #include <selinux/context.h> |
71 | #include <selinux/flask.h> | 71 | /* from deprecated <selinux/flask.h>: */ |
72 | #undef SECCLASS_PROCESS | ||
73 | #define SECCLASS_PROCESS 2 | ||
72 | 74 | ||
73 | #include "libbb.h" | 75 | #include "libbb.h" |
74 | 76 | ||
diff --git a/selinux/setfiles.c b/selinux/setfiles.c index 4fc307f55..9fa5d3f30 100644 --- a/selinux/setfiles.c +++ b/selinux/setfiles.c | |||
@@ -77,6 +77,7 @@ | |||
77 | //usage: "\n if it has changed" | 77 | //usage: "\n if it has changed" |
78 | 78 | ||
79 | #include "libbb.h" | 79 | #include "libbb.h" |
80 | #include "common_bufsiz.h" | ||
80 | #if ENABLE_FEATURE_SETFILES_CHECK_OPTION | 81 | #if ENABLE_FEATURE_SETFILES_CHECK_OPTION |
81 | #include <sepol/sepol.h> | 82 | #include <sepol/sepol.h> |
82 | #endif | 83 | #endif |
diff --git a/shell/Config.src b/shell/Config.src index e4df35973..7f5f67050 100644 --- a/shell/Config.src +++ b/shell/Config.src | |||
@@ -5,34 +5,30 @@ | |||
5 | 5 | ||
6 | menu "Shells" | 6 | menu "Shells" |
7 | 7 | ||
8 | INSERT | ||
9 | |||
10 | 8 | ||
11 | choice | 9 | choice |
12 | prompt "Choose which shell is aliased to 'sh' name" | 10 | prompt "Choose which shell is aliased to 'sh' name" |
13 | default FEATURE_SH_IS_ASH | 11 | default SH_IS_ASH |
14 | help | 12 | help |
15 | Choose which shell you want to be executed by 'sh' alias. | 13 | Choose which shell you want to be executed by 'sh' alias. |
16 | The ash shell is the most bash compatible and full featured one. | 14 | The ash shell is the most bash compatible and full featured one. |
17 | 15 | ||
18 | # note: cannot use "select ASH" here, it breaks "make allnoconfig" | 16 | # note: cannot use "select ASH" here, it breaks "make allnoconfig" |
19 | config FEATURE_SH_IS_ASH | 17 | config SH_IS_ASH |
20 | depends on ASH | ||
21 | bool "ash" | ||
22 | depends on !NOMMU | 18 | depends on !NOMMU |
19 | bool "ash" | ||
23 | 20 | ||
24 | config FEATURE_SH_IS_HUSH | 21 | config SH_IS_HUSH |
25 | depends on HUSH | ||
26 | bool "hush" | 22 | bool "hush" |
27 | 23 | ||
28 | config FEATURE_SH_IS_NONE | 24 | config SH_IS_NONE |
29 | bool "none" | 25 | bool "none" |
30 | 26 | ||
31 | endchoice | 27 | endchoice |
32 | 28 | ||
33 | choice | 29 | choice |
34 | prompt "Choose which shell is aliased to 'bash' name" | 30 | prompt "Choose which shell is aliased to 'bash' name" |
35 | default FEATURE_BASH_IS_NONE | 31 | default BASH_IS_NONE |
36 | help | 32 | help |
37 | Choose which shell you want to be executed by 'bash' alias. | 33 | Choose which shell you want to be executed by 'bash' alias. |
38 | The ash shell is the most bash compatible and full featured one. | 34 | The ash shell is the most bash compatible and full featured one. |
@@ -47,32 +43,33 @@ choice | |||
47 | can't be used for running them because it won't recongnize | 43 | can't be used for running them because it won't recongnize |
48 | "bash" as a supported applet name. | 44 | "bash" as a supported applet name. |
49 | 45 | ||
50 | config FEATURE_BASH_IS_ASH | 46 | config BASH_IS_ASH |
51 | depends on ASH | ||
52 | bool "ash" | ||
53 | depends on !NOMMU | 47 | depends on !NOMMU |
48 | bool "ash" | ||
54 | 49 | ||
55 | config FEATURE_BASH_IS_HUSH | 50 | config BASH_IS_HUSH |
56 | depends on HUSH | ||
57 | bool "hush" | 51 | bool "hush" |
58 | 52 | ||
59 | config FEATURE_BASH_IS_NONE | 53 | config BASH_IS_NONE |
60 | bool "none" | 54 | bool "none" |
61 | 55 | ||
62 | endchoice | 56 | endchoice |
63 | 57 | ||
64 | 58 | ||
65 | config SH_MATH_SUPPORT | 59 | INSERT |
60 | |||
61 | |||
62 | config FEATURE_SH_MATH | ||
66 | bool "POSIX math support" | 63 | bool "POSIX math support" |
67 | default y | 64 | default y |
68 | depends on ASH || HUSH | 65 | depends on ASH || HUSH || SH_IS_ASH || BASH_IS_ASH || SH_IS_HUSH || BASH_IS_HUSH |
69 | help | 66 | help |
70 | Enable math support in the shell via $((...)) syntax. | 67 | Enable math support in the shell via $((...)) syntax. |
71 | 68 | ||
72 | config SH_MATH_SUPPORT_64 | 69 | config FEATURE_SH_MATH_64 |
73 | bool "Extend POSIX math support to 64 bit" | 70 | bool "Extend POSIX math support to 64 bit" |
74 | default y | 71 | default y |
75 | depends on SH_MATH_SUPPORT | 72 | depends on FEATURE_SH_MATH |
76 | help | 73 | help |
77 | Enable 64-bit math support in the shell. This will make the shell | 74 | Enable 64-bit math support in the shell. This will make the shell |
78 | slightly larger, but will allow computation with very large numbers. | 75 | slightly larger, but will allow computation with very large numbers. |
@@ -81,14 +78,14 @@ config SH_MATH_SUPPORT_64 | |||
81 | config FEATURE_SH_EXTRA_QUIET | 78 | config FEATURE_SH_EXTRA_QUIET |
82 | bool "Hide message on interactive shell startup" | 79 | bool "Hide message on interactive shell startup" |
83 | default y | 80 | default y |
84 | depends on HUSH || ASH | 81 | depends on ASH || HUSH || SH_IS_ASH || BASH_IS_ASH || SH_IS_HUSH || BASH_IS_HUSH |
85 | help | 82 | help |
86 | Remove the busybox introduction when starting a shell. | 83 | Remove the busybox introduction when starting a shell. |
87 | 84 | ||
88 | config FEATURE_SH_STANDALONE | 85 | config FEATURE_SH_STANDALONE |
89 | bool "Standalone shell" | 86 | bool "Standalone shell" |
90 | default n | 87 | default n |
91 | depends on (HUSH || ASH) | 88 | depends on ASH || HUSH || SH_IS_ASH || BASH_IS_ASH || SH_IS_HUSH || BASH_IS_HUSH |
92 | help | 89 | help |
93 | This option causes busybox shells to use busybox applets | 90 | This option causes busybox shells to use busybox applets |
94 | in preference to executables in the PATH whenever possible. For | 91 | in preference to executables in the PATH whenever possible. For |
@@ -121,7 +118,7 @@ config FEATURE_SH_STANDALONE | |||
121 | config FEATURE_SH_NOFORK | 118 | config FEATURE_SH_NOFORK |
122 | bool "Run 'nofork' applets directly" | 119 | bool "Run 'nofork' applets directly" |
123 | default n | 120 | default n |
124 | depends on (HUSH || ASH) | 121 | depends on ASH || HUSH || SH_IS_ASH || BASH_IS_ASH || SH_IS_HUSH || BASH_IS_HUSH |
125 | help | 122 | help |
126 | This option causes busybox shells to not execute typical | 123 | This option causes busybox shells to not execute typical |
127 | fork/exec/wait sequence, but call <applet>_main directly, | 124 | fork/exec/wait sequence, but call <applet>_main directly, |
@@ -139,7 +136,7 @@ config FEATURE_SH_NOFORK | |||
139 | config FEATURE_SH_HISTFILESIZE | 136 | config FEATURE_SH_HISTFILESIZE |
140 | bool "Use $HISTFILESIZE" | 137 | bool "Use $HISTFILESIZE" |
141 | default y | 138 | default y |
142 | depends on HUSH || ASH | 139 | depends on ASH || HUSH || SH_IS_ASH || BASH_IS_ASH || SH_IS_HUSH || BASH_IS_HUSH |
143 | help | 140 | help |
144 | This option makes busybox shells to use $HISTFILESIZE variable | 141 | This option makes busybox shells to use $HISTFILESIZE variable |
145 | to set shell history size. Note that its max value is capped | 142 | to set shell history size. Note that its max value is capped |
diff --git a/shell/Kbuild.src b/shell/Kbuild.src index c00aec92a..6bba4989f 100644 --- a/shell/Kbuild.src +++ b/shell/Kbuild.src | |||
@@ -8,4 +8,4 @@ lib-y:= | |||
8 | 8 | ||
9 | INSERT | 9 | INSERT |
10 | 10 | ||
11 | lib-$(CONFIG_SH_MATH_SUPPORT) += math.o | 11 | lib-$(CONFIG_FEATURE_SH_MATH) += math.o |
diff --git a/shell/ash.c b/shell/ash.c index 2e7f68c05..af1157709 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -30,80 +30,6 @@ | |||
30 | * - fake $PPID | 30 | * - fake $PPID |
31 | */ | 31 | */ |
32 | 32 | ||
33 | /* | ||
34 | * The following should be set to reflect the type of system you have: | ||
35 | * JOBS -> 1 if you have Berkeley job control, 0 otherwise. | ||
36 | * define SYSV if you are running under System V. | ||
37 | * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) | ||
38 | * define DEBUG=2 to compile in and turn on debugging. | ||
39 | * | ||
40 | * When debugging is on (DEBUG is 1 and "set -o debug" was executed), | ||
41 | * debugging info will be written to ./trace and a quit signal | ||
42 | * will generate a core dump. | ||
43 | */ | ||
44 | #define DEBUG 0 | ||
45 | /* Tweak debug output verbosity here */ | ||
46 | #define DEBUG_TIME 0 | ||
47 | #define DEBUG_PID 1 | ||
48 | #define DEBUG_SIG 1 | ||
49 | #define DEBUG_INTONOFF 0 | ||
50 | |||
51 | #define PROFILE 0 | ||
52 | |||
53 | #define JOBS ENABLE_ASH_JOB_CONTROL | ||
54 | |||
55 | #include <setjmp.h> | ||
56 | #include <fnmatch.h> | ||
57 | #include <sys/times.h> | ||
58 | #include <sys/utsname.h> /* for setting $HOSTNAME */ | ||
59 | |||
60 | #include "busybox.h" /* for applet_names */ | ||
61 | |||
62 | #if defined(__ANDROID_API__) && __ANDROID_API__ <= 24 | ||
63 | /* Bionic at least up to version 24 has no glob() */ | ||
64 | # undef ENABLE_ASH_INTERNAL_GLOB | ||
65 | # define ENABLE_ASH_INTERNAL_GLOB 1 | ||
66 | #endif | ||
67 | |||
68 | #if !ENABLE_ASH_INTERNAL_GLOB | ||
69 | # include <glob.h> | ||
70 | #endif | ||
71 | |||
72 | #include "unicode.h" | ||
73 | #include "shell_common.h" | ||
74 | #if ENABLE_SH_MATH_SUPPORT | ||
75 | # include "math.h" | ||
76 | #endif | ||
77 | #if ENABLE_ASH_RANDOM_SUPPORT | ||
78 | # include "random.h" | ||
79 | #else | ||
80 | # define CLEAR_RANDOM_T(rnd) ((void)0) | ||
81 | #endif | ||
82 | |||
83 | #include "NUM_APPLETS.h" | ||
84 | #if NUM_APPLETS == 1 | ||
85 | /* STANDALONE does not make sense, and won't compile */ | ||
86 | # undef CONFIG_FEATURE_SH_STANDALONE | ||
87 | # undef ENABLE_FEATURE_SH_STANDALONE | ||
88 | # undef IF_FEATURE_SH_STANDALONE | ||
89 | # undef IF_NOT_FEATURE_SH_STANDALONE | ||
90 | # define ENABLE_FEATURE_SH_STANDALONE 0 | ||
91 | # define IF_FEATURE_SH_STANDALONE(...) | ||
92 | # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ | ||
93 | #endif | ||
94 | |||
95 | #ifndef PIPE_BUF | ||
96 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ | ||
97 | #endif | ||
98 | |||
99 | #if !ENABLE_PLATFORM_MINGW32 | ||
100 | # define is_absolute_path(path) ((path)[0] == '/') | ||
101 | #endif | ||
102 | |||
103 | #if !BB_MMU | ||
104 | # error "Do not even bother, ash will not run on NOMMU machine" | ||
105 | #endif | ||
106 | |||
107 | //config:config ASH | 33 | //config:config ASH |
108 | //config: bool "ash" | 34 | //config: bool "ash" |
109 | //config: default y | 35 | //config: default y |
@@ -118,14 +44,14 @@ | |||
118 | //config:config ASH_OPTIMIZE_FOR_SIZE | 44 | //config:config ASH_OPTIMIZE_FOR_SIZE |
119 | //config: bool "Optimize for size instead of speed" | 45 | //config: bool "Optimize for size instead of speed" |
120 | //config: default y | 46 | //config: default y |
121 | //config: depends on ASH | 47 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
122 | //config: help | 48 | //config: help |
123 | //config: Compile ash for reduced size at the price of speed. | 49 | //config: Compile ash for reduced size at the price of speed. |
124 | //config: | 50 | //config: |
125 | //config:config ASH_INTERNAL_GLOB | 51 | //config:config ASH_INTERNAL_GLOB |
126 | //config: bool "Use internal glob() implementation" | 52 | //config: bool "Use internal glob() implementation" |
127 | //config: default n | 53 | //config: default y # Y is bigger, but because of uclibc glob() bug, let Y be default for now |
128 | //config: depends on ASH | 54 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
129 | //config: help | 55 | //config: help |
130 | //config: Do not use glob() function from libc, use internal implementation. | 56 | //config: Do not use glob() function from libc, use internal implementation. |
131 | //config: Use this if you are getting "glob.h: No such file or directory" | 57 | //config: Use this if you are getting "glob.h: No such file or directory" |
@@ -134,7 +60,7 @@ | |||
134 | //config:config ASH_RANDOM_SUPPORT | 60 | //config:config ASH_RANDOM_SUPPORT |
135 | //config: bool "Pseudorandom generator and $RANDOM variable" | 61 | //config: bool "Pseudorandom generator and $RANDOM variable" |
136 | //config: default y | 62 | //config: default y |
137 | //config: depends on ASH | 63 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
138 | //config: help | 64 | //config: help |
139 | //config: Enable pseudorandom generator and dynamic variable "$RANDOM". | 65 | //config: Enable pseudorandom generator and dynamic variable "$RANDOM". |
140 | //config: Each read of "$RANDOM" will generate a new pseudorandom value. | 66 | //config: Each read of "$RANDOM" will generate a new pseudorandom value. |
@@ -145,7 +71,7 @@ | |||
145 | //config:config ASH_EXPAND_PRMT | 71 | //config:config ASH_EXPAND_PRMT |
146 | //config: bool "Expand prompt string" | 72 | //config: bool "Expand prompt string" |
147 | //config: default y | 73 | //config: default y |
148 | //config: depends on ASH | 74 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
149 | //config: help | 75 | //config: help |
150 | //config: "PS#" may contain volatile content, such as backquote commands. | 76 | //config: "PS#" may contain volatile content, such as backquote commands. |
151 | //config: This option recreates the prompt string from the environment | 77 | //config: This option recreates the prompt string from the environment |
@@ -154,70 +80,70 @@ | |||
154 | //config:config ASH_BASH_COMPAT | 80 | //config:config ASH_BASH_COMPAT |
155 | //config: bool "bash-compatible extensions" | 81 | //config: bool "bash-compatible extensions" |
156 | //config: default y | 82 | //config: default y |
157 | //config: depends on ASH | 83 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
158 | //config: help | 84 | //config: help |
159 | //config: Enable bash-compatible extensions. | 85 | //config: Enable bash-compatible extensions. |
160 | //config: | 86 | //config: |
161 | //config:config ASH_IDLE_TIMEOUT | 87 | //config:config ASH_IDLE_TIMEOUT |
162 | //config: bool "Idle timeout variable" | 88 | //config: bool "Idle timeout variable" |
163 | //config: default n | 89 | //config: default n |
164 | //config: depends on ASH | 90 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
165 | //config: help | 91 | //config: help |
166 | //config: Enables bash-like auto-logout after $TMOUT seconds of idle time. | 92 | //config: Enables bash-like auto-logout after $TMOUT seconds of idle time. |
167 | //config: | 93 | //config: |
168 | //config:config ASH_JOB_CONTROL | 94 | //config:config ASH_JOB_CONTROL |
169 | //config: bool "Job control" | 95 | //config: bool "Job control" |
170 | //config: default y | 96 | //config: default y |
171 | //config: depends on ASH | 97 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
172 | //config: help | 98 | //config: help |
173 | //config: Enable job control in the ash shell. | 99 | //config: Enable job control in the ash shell. |
174 | //config: | 100 | //config: |
175 | //config:config ASH_ALIAS | 101 | //config:config ASH_ALIAS |
176 | //config: bool "Alias support" | 102 | //config: bool "Alias support" |
177 | //config: default y | 103 | //config: default y |
178 | //config: depends on ASH | 104 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
179 | //config: help | 105 | //config: help |
180 | //config: Enable alias support in the ash shell. | 106 | //config: Enable alias support in the ash shell. |
181 | //config: | 107 | //config: |
182 | //config:config ASH_GETOPTS | 108 | //config:config ASH_GETOPTS |
183 | //config: bool "Builtin getopt to parse positional parameters" | 109 | //config: bool "Builtin getopt to parse positional parameters" |
184 | //config: default y | 110 | //config: default y |
185 | //config: depends on ASH | 111 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
186 | //config: help | 112 | //config: help |
187 | //config: Enable support for getopts builtin in ash. | 113 | //config: Enable support for getopts builtin in ash. |
188 | //config: | 114 | //config: |
189 | //config:config ASH_BUILTIN_ECHO | 115 | //config:config ASH_BUILTIN_ECHO |
190 | //config: bool "Builtin version of 'echo'" | 116 | //config: bool "Builtin version of 'echo'" |
191 | //config: default y | 117 | //config: default y |
192 | //config: depends on ASH | 118 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
193 | //config: help | 119 | //config: help |
194 | //config: Enable support for echo builtin in ash. | 120 | //config: Enable support for echo builtin in ash. |
195 | //config: | 121 | //config: |
196 | //config:config ASH_BUILTIN_PRINTF | 122 | //config:config ASH_BUILTIN_PRINTF |
197 | //config: bool "Builtin version of 'printf'" | 123 | //config: bool "Builtin version of 'printf'" |
198 | //config: default y | 124 | //config: default y |
199 | //config: depends on ASH | 125 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
200 | //config: help | 126 | //config: help |
201 | //config: Enable support for printf builtin in ash. | 127 | //config: Enable support for printf builtin in ash. |
202 | //config: | 128 | //config: |
203 | //config:config ASH_BUILTIN_TEST | 129 | //config:config ASH_BUILTIN_TEST |
204 | //config: bool "Builtin version of 'test'" | 130 | //config: bool "Builtin version of 'test'" |
205 | //config: default y | 131 | //config: default y |
206 | //config: depends on ASH | 132 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
207 | //config: help | 133 | //config: help |
208 | //config: Enable support for test builtin in ash. | 134 | //config: Enable support for test builtin in ash. |
209 | //config: | 135 | //config: |
210 | //config:config ASH_HELP | 136 | //config:config ASH_HELP |
211 | //config: bool "help builtin" | 137 | //config: bool "help builtin" |
212 | //config: default y | 138 | //config: default y |
213 | //config: depends on ASH | 139 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
214 | //config: help | 140 | //config: help |
215 | //config: Enable help builtin in ash. | 141 | //config: Enable help builtin in ash. |
216 | //config: | 142 | //config: |
217 | //config:config ASH_CMDCMD | 143 | //config:config ASH_CMDCMD |
218 | //config: bool "'command' command to override shell builtins" | 144 | //config: bool "'command' command to override shell builtins" |
219 | //config: default y | 145 | //config: default y |
220 | //config: depends on ASH | 146 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
221 | //config: help | 147 | //config: help |
222 | //config: Enable support for the ash 'command' builtin, which allows | 148 | //config: Enable support for the ash 'command' builtin, which allows |
223 | //config: you to run the specified command with the specified arguments, | 149 | //config: you to run the specified command with the specified arguments, |
@@ -225,19 +151,105 @@ | |||
225 | //config: | 151 | //config: |
226 | //config:config ASH_MAIL | 152 | //config:config ASH_MAIL |
227 | //config: bool "Check for new mail on interactive shells" | 153 | //config: bool "Check for new mail on interactive shells" |
228 | //config: default n | 154 | //config: default y |
229 | //config: depends on ASH | 155 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
230 | //config: help | 156 | //config: help |
231 | //config: Enable "check for new mail" function in the ash shell. | 157 | //config: Enable "check for new mail" function in the ash shell. |
232 | //config: | ||
233 | 158 | ||
234 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) | 159 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) |
235 | //applet:IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, sh)) | 160 | //applet:IF_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, ash)) |
236 | //applet:IF_FEATURE_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, bash)) | 161 | //applet:IF_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, ash)) |
237 | 162 | ||
238 | //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o | 163 | //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o |
164 | //kbuild:lib-$(CONFIG_SH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o | ||
165 | //kbuild:lib-$(CONFIG_BASH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o | ||
239 | //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o | 166 | //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o |
240 | 167 | ||
168 | /* | ||
169 | * The following should be set to reflect the type of system you have: | ||
170 | * JOBS -> 1 if you have Berkeley job control, 0 otherwise. | ||
171 | * define SYSV if you are running under System V. | ||
172 | * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) | ||
173 | * define DEBUG=2 to compile in and turn on debugging. | ||
174 | * | ||
175 | * When debugging is on (DEBUG is 1 and "set -o debug" was executed), | ||
176 | * debugging info will be written to ./trace and a quit signal | ||
177 | * will generate a core dump. | ||
178 | */ | ||
179 | #define DEBUG 0 | ||
180 | /* Tweak debug output verbosity here */ | ||
181 | #define DEBUG_TIME 0 | ||
182 | #define DEBUG_PID 1 | ||
183 | #define DEBUG_SIG 1 | ||
184 | #define DEBUG_INTONOFF 0 | ||
185 | |||
186 | #define PROFILE 0 | ||
187 | |||
188 | #define JOBS ENABLE_ASH_JOB_CONTROL | ||
189 | |||
190 | #include <setjmp.h> | ||
191 | #include <fnmatch.h> | ||
192 | #include <sys/times.h> | ||
193 | #include <sys/utsname.h> /* for setting $HOSTNAME */ | ||
194 | |||
195 | #include "busybox.h" /* for applet_names */ | ||
196 | |||
197 | #if defined(__ANDROID_API__) && __ANDROID_API__ <= 24 | ||
198 | /* Bionic at least up to version 24 has no glob() */ | ||
199 | # undef ENABLE_ASH_INTERNAL_GLOB | ||
200 | # define ENABLE_ASH_INTERNAL_GLOB 1 | ||
201 | #endif | ||
202 | |||
203 | #if !ENABLE_ASH_INTERNAL_GLOB && defined(__UCLIBC__) | ||
204 | # error uClibc glob() is buggy, use ASH_INTERNAL_GLOB. | ||
205 | # error The bug is: for "$PWD"/<pattern> ash will escape e.g. dashes in "$PWD" | ||
206 | # error with backslash, even ones which do not need to be: "/a-b" -> "/a\-b" | ||
207 | # error glob() should unbackslash them and match. uClibc does not unbackslash, | ||
208 | # error fails to match dirname, subsequently not expanding <pattern> in it. | ||
209 | // Testcase: | ||
210 | // if (glob("/etc/polkit\\-1", 0, NULL, &pglob)) - this returns 0 on uclibc, no bug | ||
211 | // if (glob("/etc/polkit\\-1/*", 0, NULL, &pglob)) printf("uclibc bug!\n"); | ||
212 | #endif | ||
213 | |||
214 | #if !ENABLE_ASH_INTERNAL_GLOB | ||
215 | # include <glob.h> | ||
216 | #endif | ||
217 | |||
218 | #include "unicode.h" | ||
219 | #include "shell_common.h" | ||
220 | #if CONFIG_FEATURE_SH_MATH | ||
221 | # include "math.h" | ||
222 | #endif | ||
223 | #if ENABLE_ASH_RANDOM_SUPPORT | ||
224 | # include "random.h" | ||
225 | #else | ||
226 | # define CLEAR_RANDOM_T(rnd) ((void)0) | ||
227 | #endif | ||
228 | |||
229 | #include "NUM_APPLETS.h" | ||
230 | #if NUM_APPLETS == 1 | ||
231 | /* STANDALONE does not make sense, and won't compile */ | ||
232 | # undef CONFIG_FEATURE_SH_STANDALONE | ||
233 | # undef ENABLE_FEATURE_SH_STANDALONE | ||
234 | # undef IF_FEATURE_SH_STANDALONE | ||
235 | # undef IF_NOT_FEATURE_SH_STANDALONE | ||
236 | # define ENABLE_FEATURE_SH_STANDALONE 0 | ||
237 | # define IF_FEATURE_SH_STANDALONE(...) | ||
238 | # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ | ||
239 | #endif | ||
240 | |||
241 | #ifndef PIPE_BUF | ||
242 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ | ||
243 | #endif | ||
244 | |||
245 | #if !ENABLE_PLATFORM_MINGW32 | ||
246 | # define is_absolute_path(path) ((path)[0] == '/') | ||
247 | #endif | ||
248 | |||
249 | #if !BB_MMU | ||
250 | # error "Do not even bother, ash will not run on NOMMU machine" | ||
251 | #endif | ||
252 | |||
241 | #if ENABLE_PLATFORM_MINGW32 | 253 | #if ENABLE_PLATFORM_MINGW32 |
242 | union node; | 254 | union node; |
243 | struct strlist; | 255 | struct strlist; |
@@ -1343,6 +1355,8 @@ ash_msg_and_raise_error(const char *msg, ...) | |||
1343 | { | 1355 | { |
1344 | va_list ap; | 1356 | va_list ap; |
1345 | 1357 | ||
1358 | exitstatus = 2; | ||
1359 | |||
1346 | va_start(ap, msg); | 1360 | va_start(ap, msg); |
1347 | ash_vmsg_and_raise(EXERROR, msg, ap); | 1361 | ash_vmsg_and_raise(EXERROR, msg, ap); |
1348 | /* NOTREACHED */ | 1362 | /* NOTREACHED */ |
@@ -2205,6 +2219,7 @@ lookupvar(const char *name) | |||
2205 | return NULL; | 2219 | return NULL; |
2206 | } | 2220 | } |
2207 | 2221 | ||
2222 | #if ENABLE_UNICODE_SUPPORT | ||
2208 | static void | 2223 | static void |
2209 | reinit_unicode_for_ash(void) | 2224 | reinit_unicode_for_ash(void) |
2210 | { | 2225 | { |
@@ -2221,6 +2236,9 @@ reinit_unicode_for_ash(void) | |||
2221 | reinit_unicode(s); | 2236 | reinit_unicode(s); |
2222 | } | 2237 | } |
2223 | } | 2238 | } |
2239 | #else | ||
2240 | # define reinit_unicode_for_ash() ((void)0) | ||
2241 | #endif | ||
2224 | 2242 | ||
2225 | /* | 2243 | /* |
2226 | * Search the environment of a builtin command. | 2244 | * Search the environment of a builtin command. |
@@ -2924,7 +2942,7 @@ pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
2924 | 2942 | ||
2925 | #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE | 2943 | #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE |
2926 | 2944 | ||
2927 | #if ENABLE_SH_MATH_SUPPORT | 2945 | #if ENABLE_FEATURE_SH_MATH |
2928 | # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8) | (d << 12)) | 2946 | # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8) | (d << 12)) |
2929 | #else | 2947 | #else |
2930 | # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8)) | 2948 | # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8)) |
@@ -3305,7 +3323,18 @@ static const uint8_t syntax_index_table[] ALIGN1 = { | |||
3305 | # endif | 3323 | # endif |
3306 | }; | 3324 | }; |
3307 | 3325 | ||
3326 | #if 1 | ||
3308 | # define SIT(c, syntax) ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf) | 3327 | # define SIT(c, syntax) ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf) |
3328 | #else /* debug version, caught one signed char bug */ | ||
3329 | # define SIT(c, syntax) \ | ||
3330 | ({ \ | ||
3331 | if ((c) < 0 || (c) > (PEOF + ENABLE_ASH_ALIAS)) \ | ||
3332 | bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \ | ||
3333 | if ((syntax) < 0 || (syntax) > (2 + ENABLE_FEATURE_SH_MATH)) \ | ||
3334 | bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \ | ||
3335 | ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf); \ | ||
3336 | }) | ||
3337 | #endif | ||
3309 | 3338 | ||
3310 | #endif /* !USE_SIT_FUNCTION */ | 3339 | #endif /* !USE_SIT_FUNCTION */ |
3311 | 3340 | ||
@@ -4765,7 +4794,7 @@ cmdputs(const char *s) | |||
4765 | case CTLBACKQ: | 4794 | case CTLBACKQ: |
4766 | str = "$(...)"; | 4795 | str = "$(...)"; |
4767 | goto dostr; | 4796 | goto dostr; |
4768 | #if ENABLE_SH_MATH_SUPPORT | 4797 | #if ENABLE_FEATURE_SH_MATH |
4769 | case CTLARI: | 4798 | case CTLARI: |
4770 | str = "$(("; | 4799 | str = "$(("; |
4771 | goto dostr; | 4800 | goto dostr; |
@@ -5749,11 +5778,11 @@ redirect(union node *redir, int flags) | |||
5749 | /* Careful to not accidentally "save" | 5778 | /* Careful to not accidentally "save" |
5750 | * to the same fd as right side fd in N>&M */ | 5779 | * to the same fd as right side fd in N>&M */ |
5751 | int minfd = right_fd < 10 ? 10 : right_fd + 1; | 5780 | int minfd = right_fd < 10 ? 10 : right_fd + 1; |
5781 | #if defined(F_DUPFD_CLOEXEC) | ||
5782 | i = fcntl(fd, F_DUPFD_CLOEXEC, minfd); | ||
5783 | #else | ||
5752 | i = fcntl(fd, F_DUPFD, minfd); | 5784 | i = fcntl(fd, F_DUPFD, minfd); |
5753 | /* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds | 5785 | #endif |
5754 | * are closed in popredir() in the child, preventing them from leaking | ||
5755 | * into child. (popredir() also cleans up the mess in case of failures) | ||
5756 | */ | ||
5757 | if (i == -1) { | 5786 | if (i == -1) { |
5758 | i = errno; | 5787 | i = errno; |
5759 | if (i != EBADF) { | 5788 | if (i != EBADF) { |
@@ -5768,6 +5797,9 @@ redirect(union node *redir, int flags) | |||
5768 | remember_to_close: | 5797 | remember_to_close: |
5769 | i = CLOSED; | 5798 | i = CLOSED; |
5770 | } else { /* fd is open, save its copy */ | 5799 | } else { /* fd is open, save its copy */ |
5800 | #if !defined(F_DUPFD_CLOEXEC) | ||
5801 | fcntl(i, F_SETFD, FD_CLOEXEC); | ||
5802 | #endif | ||
5771 | /* "exec fd>&-" should not close fds | 5803 | /* "exec fd>&-" should not close fds |
5772 | * which point to script file(s). | 5804 | * which point to script file(s). |
5773 | * Force them to be restored afterwards */ | 5805 | * Force them to be restored afterwards */ |
@@ -5878,7 +5910,7 @@ redirectsafe(union node *redir, int flags) | |||
5878 | * We have to deal with backquotes, shell variables, and file metacharacters. | 5910 | * We have to deal with backquotes, shell variables, and file metacharacters. |
5879 | */ | 5911 | */ |
5880 | 5912 | ||
5881 | #if ENABLE_SH_MATH_SUPPORT | 5913 | #if ENABLE_FEATURE_SH_MATH |
5882 | static arith_t | 5914 | static arith_t |
5883 | ash_arith(const char *s) | 5915 | ash_arith(const char *s) |
5884 | { | 5916 | { |
@@ -5966,7 +5998,7 @@ static struct arglist exparg; | |||
5966 | /* | 5998 | /* |
5967 | * Our own itoa(). | 5999 | * Our own itoa(). |
5968 | */ | 6000 | */ |
5969 | #if !ENABLE_SH_MATH_SUPPORT | 6001 | #if !ENABLE_FEATURE_SH_MATH |
5970 | /* cvtnum() is used even if math support is off (to prepare $? values and such) */ | 6002 | /* cvtnum() is used even if math support is off (to prepare $? values and such) */ |
5971 | typedef long arith_t; | 6003 | typedef long arith_t; |
5972 | # define ARITH_FMT "%ld" | 6004 | # define ARITH_FMT "%ld" |
@@ -6220,14 +6252,15 @@ memtodest(const char *p, size_t len, int syntax, int quotes) | |||
6220 | do { | 6252 | do { |
6221 | unsigned char c = *p++; | 6253 | unsigned char c = *p++; |
6222 | if (c) { | 6254 | if (c) { |
6223 | int n = SIT(c, syntax); | 6255 | if (quotes & QUOTES_ESC) { |
6224 | if ((quotes & QUOTES_ESC) | 6256 | int n = SIT(c, syntax); |
6225 | && ((n == CCTL) | 6257 | if (n == CCTL |
6226 | || (((quotes & EXP_FULL) || syntax != BASESYNTAX) | 6258 | || (((quotes & EXP_FULL) || syntax != BASESYNTAX) |
6227 | && n == CBACK) | 6259 | && n == CBACK |
6228 | ) | 6260 | ) |
6229 | ) { | 6261 | ) { |
6230 | USTPUTC(CTLESC, q); | 6262 | USTPUTC(CTLESC, q); |
6263 | } | ||
6231 | } | 6264 | } |
6232 | } else if (!(quotes & QUOTES_KEEPNUL)) | 6265 | } else if (!(quotes & QUOTES_KEEPNUL)) |
6233 | continue; | 6266 | continue; |
@@ -6490,7 +6523,7 @@ expbackq(union node *cmd, int flag) | |||
6490 | stackblock() + startloc)); | 6523 | stackblock() + startloc)); |
6491 | } | 6524 | } |
6492 | 6525 | ||
6493 | #if ENABLE_SH_MATH_SUPPORT | 6526 | #if ENABLE_FEATURE_SH_MATH |
6494 | /* | 6527 | /* |
6495 | * Expand arithmetic expression. Backup to start of expression, | 6528 | * Expand arithmetic expression. Backup to start of expression, |
6496 | * evaluate, place result in (backed up) result, adjust string position. | 6529 | * evaluate, place result in (backed up) result, adjust string position. |
@@ -6572,7 +6605,7 @@ argstr(char *p, int flags, struct strlist *var_str_list) | |||
6572 | CTLESC, | 6605 | CTLESC, |
6573 | CTLVAR, | 6606 | CTLVAR, |
6574 | CTLBACKQ, | 6607 | CTLBACKQ, |
6575 | #if ENABLE_SH_MATH_SUPPORT | 6608 | #if ENABLE_FEATURE_SH_MATH |
6576 | CTLENDARI, | 6609 | CTLENDARI, |
6577 | #endif | 6610 | #endif |
6578 | '\0' | 6611 | '\0' |
@@ -6608,7 +6641,7 @@ argstr(char *p, int flags, struct strlist *var_str_list) | |||
6608 | c = p[length]; | 6641 | c = p[length]; |
6609 | if (c) { | 6642 | if (c) { |
6610 | if (!(c & 0x80) | 6643 | if (!(c & 0x80) |
6611 | IF_SH_MATH_SUPPORT(|| c == CTLENDARI) | 6644 | IF_FEATURE_SH_MATH(|| c == CTLENDARI) |
6612 | ) { | 6645 | ) { |
6613 | /* c == '=' || c == ':' || c == CTLENDARI */ | 6646 | /* c == '=' || c == ':' || c == CTLENDARI */ |
6614 | length++; | 6647 | length++; |
@@ -6688,7 +6721,7 @@ argstr(char *p, int flags, struct strlist *var_str_list) | |||
6688 | expbackq(argbackq->n, flags | inquotes); | 6721 | expbackq(argbackq->n, flags | inquotes); |
6689 | argbackq = argbackq->next; | 6722 | argbackq = argbackq->next; |
6690 | goto start; | 6723 | goto start; |
6691 | #if ENABLE_SH_MATH_SUPPORT | 6724 | #if ENABLE_FEATURE_SH_MATH |
6692 | case CTLENDARI: | 6725 | case CTLENDARI: |
6693 | p--; | 6726 | p--; |
6694 | expari(flags | inquotes); | 6727 | expari(flags | inquotes); |
@@ -9686,7 +9719,7 @@ static int helpcmd(int, char **) FAST_FUNC; | |||
9686 | #if MAX_HISTORY | 9719 | #if MAX_HISTORY |
9687 | static int historycmd(int, char **) FAST_FUNC; | 9720 | static int historycmd(int, char **) FAST_FUNC; |
9688 | #endif | 9721 | #endif |
9689 | #if ENABLE_SH_MATH_SUPPORT | 9722 | #if ENABLE_FEATURE_SH_MATH |
9690 | static int letcmd(int, char **) FAST_FUNC; | 9723 | static int letcmd(int, char **) FAST_FUNC; |
9691 | #endif | 9724 | #endif |
9692 | static int readcmd(int, char **) FAST_FUNC; | 9725 | static int readcmd(int, char **) FAST_FUNC; |
@@ -9766,7 +9799,7 @@ static const struct builtincmd builtintab[] = { | |||
9766 | { BUILTIN_REGULAR "jobs" , jobscmd }, | 9799 | { BUILTIN_REGULAR "jobs" , jobscmd }, |
9767 | { BUILTIN_REGULAR "kill" , killcmd }, | 9800 | { BUILTIN_REGULAR "kill" , killcmd }, |
9768 | #endif | 9801 | #endif |
9769 | #if ENABLE_SH_MATH_SUPPORT | 9802 | #if ENABLE_FEATURE_SH_MATH |
9770 | { BUILTIN_NOSPEC "let" , letcmd }, | 9803 | { BUILTIN_NOSPEC "let" , letcmd }, |
9771 | #endif | 9804 | #endif |
9772 | { BUILTIN_ASSIGN "local" , localcmd }, | 9805 | { BUILTIN_ASSIGN "local" , localcmd }, |
@@ -10004,11 +10037,13 @@ evalcommand(union node *cmd, int flags) | |||
10004 | } | 10037 | } |
10005 | 10038 | ||
10006 | if (status) { | 10039 | if (status) { |
10040 | bail: | ||
10041 | exitstatus = status; | ||
10042 | |||
10007 | /* We have a redirection error. */ | 10043 | /* We have a redirection error. */ |
10008 | if (spclbltin > 0) | 10044 | if (spclbltin > 0) |
10009 | raise_exception(EXERROR); | 10045 | raise_exception(EXERROR); |
10010 | bail: | 10046 | |
10011 | exitstatus = status; | ||
10012 | goto out; | 10047 | goto out; |
10013 | } | 10048 | } |
10014 | 10049 | ||
@@ -10516,7 +10551,7 @@ pgetc(void) | |||
10516 | return g_parsefile->lastc[--g_parsefile->unget]; | 10551 | return g_parsefile->lastc[--g_parsefile->unget]; |
10517 | 10552 | ||
10518 | if (--g_parsefile->left_in_line >= 0) | 10553 | if (--g_parsefile->left_in_line >= 0) |
10519 | c = (signed char)*g_parsefile->next_to_pgetc++; | 10554 | c = (unsigned char)*g_parsefile->next_to_pgetc++; |
10520 | else | 10555 | else |
10521 | c = preadbuffer(); | 10556 | c = preadbuffer(); |
10522 | 10557 | ||
@@ -11840,13 +11875,13 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11840 | smallint quotef; | 11875 | smallint quotef; |
11841 | smallint dblquote; | 11876 | smallint dblquote; |
11842 | smallint oldstyle; | 11877 | smallint oldstyle; |
11843 | smallint prevsyntax; /* syntax before arithmetic */ | 11878 | IF_FEATURE_SH_MATH(smallint prevsyntax;) /* syntax before arithmetic */ |
11844 | #if ENABLE_ASH_EXPAND_PRMT | 11879 | #if ENABLE_ASH_EXPAND_PRMT |
11845 | smallint pssyntax; /* we are expanding a prompt string */ | 11880 | smallint pssyntax; /* we are expanding a prompt string */ |
11846 | #endif | 11881 | #endif |
11847 | int varnest; /* levels of variables expansion */ | 11882 | int varnest; /* levels of variables expansion */ |
11848 | int arinest; /* levels of arithmetic expansion */ | 11883 | IF_FEATURE_SH_MATH(int arinest;) /* levels of arithmetic expansion */ |
11849 | int parenlevel; /* levels of parens in arithmetic */ | 11884 | IF_FEATURE_SH_MATH(int parenlevel;) /* levels of parens in arithmetic */ |
11850 | int dqvarnest; /* levels of variables expansion within double quotes */ | 11885 | int dqvarnest; /* levels of variables expansion within double quotes */ |
11851 | 11886 | ||
11852 | IF_ASH_BASH_COMPAT(smallint bash_dollar_squote = 0;) | 11887 | IF_ASH_BASH_COMPAT(smallint bash_dollar_squote = 0;) |
@@ -11854,7 +11889,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11854 | startlinno = g_parsefile->linno; | 11889 | startlinno = g_parsefile->linno; |
11855 | bqlist = NULL; | 11890 | bqlist = NULL; |
11856 | quotef = 0; | 11891 | quotef = 0; |
11857 | prevsyntax = 0; | 11892 | IF_FEATURE_SH_MATH(prevsyntax = 0;) |
11858 | #if ENABLE_ASH_EXPAND_PRMT | 11893 | #if ENABLE_ASH_EXPAND_PRMT |
11859 | pssyntax = (syntax == PSSYNTAX); | 11894 | pssyntax = (syntax == PSSYNTAX); |
11860 | if (pssyntax) | 11895 | if (pssyntax) |
@@ -11862,8 +11897,8 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11862 | #endif | 11897 | #endif |
11863 | dblquote = (syntax == DQSYNTAX); | 11898 | dblquote = (syntax == DQSYNTAX); |
11864 | varnest = 0; | 11899 | varnest = 0; |
11865 | arinest = 0; | 11900 | IF_FEATURE_SH_MATH(arinest = 0;) |
11866 | parenlevel = 0; | 11901 | IF_FEATURE_SH_MATH(parenlevel = 0;) |
11867 | dqvarnest = 0; | 11902 | dqvarnest = 0; |
11868 | 11903 | ||
11869 | STARTSTACKSTR(out); | 11904 | STARTSTACKSTR(out); |
@@ -11970,7 +12005,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11970 | } | 12005 | } |
11971 | USTPUTC(c, out); | 12006 | USTPUTC(c, out); |
11972 | break; | 12007 | break; |
11973 | #if ENABLE_SH_MATH_SUPPORT | 12008 | #if ENABLE_FEATURE_SH_MATH |
11974 | case CLP: /* '(' in arithmetic */ | 12009 | case CLP: /* '(' in arithmetic */ |
11975 | parenlevel++; | 12010 | parenlevel++; |
11976 | USTPUTC(c, out); | 12011 | USTPUTC(c, out); |
@@ -12021,7 +12056,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
12021 | } /* for (;;) */ | 12056 | } /* for (;;) */ |
12022 | endword: | 12057 | endword: |
12023 | 12058 | ||
12024 | #if ENABLE_SH_MATH_SUPPORT | 12059 | #if ENABLE_FEATURE_SH_MATH |
12025 | if (syntax == ARISYNTAX) | 12060 | if (syntax == ARISYNTAX) |
12026 | raise_error_syntax("missing '))'"); | 12061 | raise_error_syntax("missing '))'"); |
12027 | #endif | 12062 | #endif |
@@ -12200,7 +12235,7 @@ parsesub: { | |||
12200 | } else if (c == '(') { | 12235 | } else if (c == '(') { |
12201 | /* $(command) or $((arith)) */ | 12236 | /* $(command) or $((arith)) */ |
12202 | if (pgetc_eatbnl() == '(') { | 12237 | if (pgetc_eatbnl() == '(') { |
12203 | #if ENABLE_SH_MATH_SUPPORT | 12238 | #if ENABLE_FEATURE_SH_MATH |
12204 | PARSEARITH(); | 12239 | PARSEARITH(); |
12205 | #else | 12240 | #else |
12206 | raise_error_syntax("you disabled math support for $((arith)) syntax"); | 12241 | raise_error_syntax("you disabled math support for $((arith)) syntax"); |
@@ -12455,7 +12490,7 @@ parsebackq: { | |||
12455 | goto parsebackq_newreturn; | 12490 | goto parsebackq_newreturn; |
12456 | } | 12491 | } |
12457 | 12492 | ||
12458 | #if ENABLE_SH_MATH_SUPPORT | 12493 | #if ENABLE_FEATURE_SH_MATH |
12459 | /* | 12494 | /* |
12460 | * Parse an arithmetic expansion (indicate start of one and set state) | 12495 | * Parse an arithmetic expansion (indicate start of one and set state) |
12461 | */ | 12496 | */ |
@@ -13532,7 +13567,7 @@ timescmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13532 | return 0; | 13567 | return 0; |
13533 | } | 13568 | } |
13534 | 13569 | ||
13535 | #if ENABLE_SH_MATH_SUPPORT | 13570 | #if ENABLE_FEATURE_SH_MATH |
13536 | /* | 13571 | /* |
13537 | * The let builtin. Partially stolen from GNU Bash, the Bourne Again SHell. | 13572 | * The let builtin. Partially stolen from GNU Bash, the Bourne Again SHell. |
13538 | * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. | 13573 | * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. |
@@ -13871,15 +13906,6 @@ init(void) | |||
13871 | //usage:#define ash_full_usage "\n\n" | 13906 | //usage:#define ash_full_usage "\n\n" |
13872 | //usage: "Unix shell interpreter" | 13907 | //usage: "Unix shell interpreter" |
13873 | 13908 | ||
13874 | //usage:#if ENABLE_FEATURE_SH_IS_ASH | ||
13875 | //usage:# define sh_trivial_usage ash_trivial_usage | ||
13876 | //usage:# define sh_full_usage ash_full_usage | ||
13877 | //usage:#endif | ||
13878 | //usage:#if ENABLE_FEATURE_BASH_IS_ASH | ||
13879 | //usage:# define bash_trivial_usage ash_trivial_usage | ||
13880 | //usage:# define bash_full_usage ash_full_usage | ||
13881 | //usage:#endif | ||
13882 | |||
13883 | /* | 13909 | /* |
13884 | * Process the shell command line arguments. | 13910 | * Process the shell command line arguments. |
13885 | */ | 13911 | */ |
diff --git a/shell/ash_test/ash-misc/exitcode2.right b/shell/ash_test/ash-misc/exitcode2.right new file mode 100644 index 000000000..f7cb983c6 --- /dev/null +++ b/shell/ash_test/ash-misc/exitcode2.right | |||
@@ -0,0 +1,4 @@ | |||
1 | ./test.sh: line 1: syntax error: unexpected ")" | ||
2 | Done:2 | ||
3 | ./exitcode2.tests: line 11: can't open does_not_exist: no such file | ||
4 | Done:1 | ||
diff --git a/shell/ash_test/ash-misc/exitcode2.tests b/shell/ash_test/ash-misc/exitcode2.tests new file mode 100755 index 000000000..79a6ebd50 --- /dev/null +++ b/shell/ash_test/ash-misc/exitcode2.tests | |||
@@ -0,0 +1,12 @@ | |||
1 | # syntax error should return status 2 | ||
2 | cat >test.sh <<EOF | ||
3 | ) | ||
4 | EOF | ||
5 | chmod +x test.sh | ||
6 | $THIS_SH ./test.sh | ||
7 | echo Done:$? | ||
8 | rm -f test.sh | ||
9 | |||
10 | # redirection error with special builtin should return status 1 | ||
11 | (eval cat <does_not_exist) | ||
12 | echo Done:$? | ||
diff --git a/shell/ash_test/ash-redir/redir_leak.right b/shell/ash_test/ash-redir/redir_leak.right new file mode 100644 index 000000000..b1c48292b --- /dev/null +++ b/shell/ash_test/ash-redir/redir_leak.right | |||
@@ -0,0 +1,6 @@ | |||
1 | 4 | ||
2 | 4 | ||
3 | 4 | ||
4 | 4 | ||
5 | 4 | ||
6 | 4 | ||
diff --git a/shell/ash_test/ash-redir/redir_leak.tests b/shell/ash_test/ash-redir/redir_leak.tests new file mode 100755 index 000000000..c8a9c6343 --- /dev/null +++ b/shell/ash_test/ash-redir/redir_leak.tests | |||
@@ -0,0 +1,10 @@ | |||
1 | # Each of these should show only four lines: | ||
2 | # fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. | ||
3 | # This test detects bugs where redirects leave stray open fds. | ||
4 | |||
5 | ls -1 /proc/self/fd | wc -l | ||
6 | ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l | ||
7 | ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l | ||
8 | echo "`ls -1 /proc/self/fd `" | wc -l | ||
9 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l | ||
10 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l | ||
diff --git a/shell/hush.c b/shell/hush.c index bcd4dffee..a56d3b280 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -82,35 +82,6 @@ | |||
82 | * $ "export" i=`echo 'aaa bbb'`; echo "$i" | 82 | * $ "export" i=`echo 'aaa bbb'`; echo "$i" |
83 | * aaa | 83 | * aaa |
84 | */ | 84 | */ |
85 | #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ | ||
86 | || defined(__APPLE__) \ | ||
87 | ) | ||
88 | # include <malloc.h> /* for malloc_trim */ | ||
89 | #endif | ||
90 | #include <glob.h> | ||
91 | /* #include <dmalloc.h> */ | ||
92 | #if ENABLE_HUSH_CASE | ||
93 | # include <fnmatch.h> | ||
94 | #endif | ||
95 | #include <sys/utsname.h> /* for setting $HOSTNAME */ | ||
96 | |||
97 | #include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */ | ||
98 | #include "unicode.h" | ||
99 | #include "shell_common.h" | ||
100 | #include "math.h" | ||
101 | #include "match.h" | ||
102 | #if ENABLE_HUSH_RANDOM_SUPPORT | ||
103 | # include "random.h" | ||
104 | #else | ||
105 | # define CLEAR_RANDOM_T(rnd) ((void)0) | ||
106 | #endif | ||
107 | #ifndef F_DUPFD_CLOEXEC | ||
108 | # define F_DUPFD_CLOEXEC F_DUPFD | ||
109 | #endif | ||
110 | #ifndef PIPE_BUF | ||
111 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ | ||
112 | #endif | ||
113 | |||
114 | //config:config HUSH | 85 | //config:config HUSH |
115 | //config: bool "hush" | 86 | //config: bool "hush" |
116 | //config: default y | 87 | //config: default y |
@@ -128,7 +99,7 @@ | |||
128 | //config:config HUSH_BASH_COMPAT | 99 | //config:config HUSH_BASH_COMPAT |
129 | //config: bool "bash-compatible extensions" | 100 | //config: bool "bash-compatible extensions" |
130 | //config: default y | 101 | //config: default y |
131 | //config: depends on HUSH | 102 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
132 | //config: help | 103 | //config: help |
133 | //config: Enable bash-compatible extensions. | 104 | //config: Enable bash-compatible extensions. |
134 | //config: | 105 | //config: |
@@ -142,14 +113,14 @@ | |||
142 | //config:config HUSH_HELP | 113 | //config:config HUSH_HELP |
143 | //config: bool "help builtin" | 114 | //config: bool "help builtin" |
144 | //config: default y | 115 | //config: default y |
145 | //config: depends on HUSH | 116 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
146 | //config: help | 117 | //config: help |
147 | //config: Enable help builtin in hush. Code size + ~1 kbyte. | 118 | //config: Enable help builtin in hush. Code size + ~1 kbyte. |
148 | //config: | 119 | //config: |
149 | //config:config HUSH_INTERACTIVE | 120 | //config:config HUSH_INTERACTIVE |
150 | //config: bool "Interactive mode" | 121 | //config: bool "Interactive mode" |
151 | //config: default y | 122 | //config: default y |
152 | //config: depends on HUSH | 123 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
153 | //config: help | 124 | //config: help |
154 | //config: Enable interactive mode (prompt and command editing). | 125 | //config: Enable interactive mode (prompt and command editing). |
155 | //config: Without this, hush simply reads and executes commands | 126 | //config: Without this, hush simply reads and executes commands |
@@ -177,35 +148,35 @@ | |||
177 | //config:config HUSH_TICK | 148 | //config:config HUSH_TICK |
178 | //config: bool "Process substitution" | 149 | //config: bool "Process substitution" |
179 | //config: default y | 150 | //config: default y |
180 | //config: depends on HUSH | 151 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
181 | //config: help | 152 | //config: help |
182 | //config: Enable process substitution `command` and $(command) in hush. | 153 | //config: Enable process substitution `command` and $(command) in hush. |
183 | //config: | 154 | //config: |
184 | //config:config HUSH_IF | 155 | //config:config HUSH_IF |
185 | //config: bool "Support if/then/elif/else/fi" | 156 | //config: bool "Support if/then/elif/else/fi" |
186 | //config: default y | 157 | //config: default y |
187 | //config: depends on HUSH | 158 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
188 | //config: help | 159 | //config: help |
189 | //config: Enable if/then/elif/else/fi in hush. | 160 | //config: Enable if/then/elif/else/fi in hush. |
190 | //config: | 161 | //config: |
191 | //config:config HUSH_LOOPS | 162 | //config:config HUSH_LOOPS |
192 | //config: bool "Support for, while and until loops" | 163 | //config: bool "Support for, while and until loops" |
193 | //config: default y | 164 | //config: default y |
194 | //config: depends on HUSH | 165 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
195 | //config: help | 166 | //config: help |
196 | //config: Enable for, while and until loops in hush. | 167 | //config: Enable for, while and until loops in hush. |
197 | //config: | 168 | //config: |
198 | //config:config HUSH_CASE | 169 | //config:config HUSH_CASE |
199 | //config: bool "Support case ... esac statement" | 170 | //config: bool "Support case ... esac statement" |
200 | //config: default y | 171 | //config: default y |
201 | //config: depends on HUSH | 172 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
202 | //config: help | 173 | //config: help |
203 | //config: Enable case ... esac statement in hush. +400 bytes. | 174 | //config: Enable case ... esac statement in hush. +400 bytes. |
204 | //config: | 175 | //config: |
205 | //config:config HUSH_FUNCTIONS | 176 | //config:config HUSH_FUNCTIONS |
206 | //config: bool "Support funcname() { commands; } syntax" | 177 | //config: bool "Support funcname() { commands; } syntax" |
207 | //config: default y | 178 | //config: default y |
208 | //config: depends on HUSH | 179 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
209 | //config: help | 180 | //config: help |
210 | //config: Enable support for shell functions in hush. +800 bytes. | 181 | //config: Enable support for shell functions in hush. +800 bytes. |
211 | //config: | 182 | //config: |
@@ -219,7 +190,7 @@ | |||
219 | //config:config HUSH_RANDOM_SUPPORT | 190 | //config:config HUSH_RANDOM_SUPPORT |
220 | //config: bool "Pseudorandom generator and $RANDOM variable" | 191 | //config: bool "Pseudorandom generator and $RANDOM variable" |
221 | //config: default y | 192 | //config: default y |
222 | //config: depends on HUSH | 193 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
223 | //config: help | 194 | //config: help |
224 | //config: Enable pseudorandom generator and dynamic variable "$RANDOM". | 195 | //config: Enable pseudorandom generator and dynamic variable "$RANDOM". |
225 | //config: Each read of "$RANDOM" will generate a new pseudorandom value. | 196 | //config: Each read of "$RANDOM" will generate a new pseudorandom value. |
@@ -227,14 +198,14 @@ | |||
227 | //config:config HUSH_EXPORT_N | 198 | //config:config HUSH_EXPORT_N |
228 | //config: bool "Support 'export -n' option" | 199 | //config: bool "Support 'export -n' option" |
229 | //config: default y | 200 | //config: default y |
230 | //config: depends on HUSH | 201 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
231 | //config: help | 202 | //config: help |
232 | //config: export -n unexports variables. It is a bash extension. | 203 | //config: export -n unexports variables. It is a bash extension. |
233 | //config: | 204 | //config: |
234 | //config:config HUSH_MODE_X | 205 | //config:config HUSH_MODE_X |
235 | //config: bool "Support 'hush -x' option and 'set -x' command" | 206 | //config: bool "Support 'hush -x' option and 'set -x' command" |
236 | //config: default y | 207 | //config: default y |
237 | //config: depends on HUSH | 208 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
238 | //config: help | 209 | //config: help |
239 | //config: This instructs hush to print commands before execution. | 210 | //config: This instructs hush to print commands before execution. |
240 | //config: Adds ~300 bytes. | 211 | //config: Adds ~300 bytes. |
@@ -245,14 +216,15 @@ | |||
245 | //config: select HUSH | 216 | //config: select HUSH |
246 | //config: help | 217 | //config: help |
247 | //config: msh is deprecated and will be removed, please migrate to hush. | 218 | //config: msh is deprecated and will be removed, please migrate to hush. |
248 | //config: | ||
249 | 219 | ||
250 | //applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP)) | 220 | //applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP)) |
251 | //applet:IF_MSH(APPLET(msh, BB_DIR_BIN, BB_SUID_DROP)) | 221 | //applet:IF_MSH(APPLET_ODDNAME(msh, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) |
252 | //applet:IF_FEATURE_SH_IS_HUSH(APPLET_ODDNAME(sh, hush, BB_DIR_BIN, BB_SUID_DROP, sh)) | 222 | //applet:IF_SH_IS_HUSH(APPLET_ODDNAME(sh, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) |
253 | //applet:IF_FEATURE_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, bash)) | 223 | //applet:IF_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) |
254 | 224 | ||
255 | //kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o | 225 | //kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o |
226 | //kbuild:lib-$(CONFIG_SH_IS_HUSH) += hush.o match.o shell_common.o | ||
227 | //kbuild:lib-$(CONFIG_BASH_IS_HUSH) += hush.o match.o shell_common.o | ||
256 | //kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o | 228 | //kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o |
257 | 229 | ||
258 | /* -i (interactive) and -s (read stdin) are also accepted, | 230 | /* -i (interactive) and -s (read stdin) are also accepted, |
@@ -265,17 +237,34 @@ | |||
265 | //usage:#define hush_full_usage "\n\n" | 237 | //usage:#define hush_full_usage "\n\n" |
266 | //usage: "Unix shell interpreter" | 238 | //usage: "Unix shell interpreter" |
267 | 239 | ||
268 | //usage:#define msh_trivial_usage hush_trivial_usage | 240 | #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ |
269 | //usage:#define msh_full_usage hush_full_usage | 241 | || defined(__APPLE__) \ |
242 | ) | ||
243 | # include <malloc.h> /* for malloc_trim */ | ||
244 | #endif | ||
245 | #include <glob.h> | ||
246 | /* #include <dmalloc.h> */ | ||
247 | #if ENABLE_HUSH_CASE | ||
248 | # include <fnmatch.h> | ||
249 | #endif | ||
250 | #include <sys/utsname.h> /* for setting $HOSTNAME */ | ||
270 | 251 | ||
271 | //usage:#if ENABLE_FEATURE_SH_IS_HUSH | 252 | #include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */ |
272 | //usage:# define sh_trivial_usage hush_trivial_usage | 253 | #include "unicode.h" |
273 | //usage:# define sh_full_usage hush_full_usage | 254 | #include "shell_common.h" |
274 | //usage:#endif | 255 | #include "math.h" |
275 | //usage:#if ENABLE_FEATURE_BASH_IS_HUSH | 256 | #include "match.h" |
276 | //usage:# define bash_trivial_usage hush_trivial_usage | 257 | #if ENABLE_HUSH_RANDOM_SUPPORT |
277 | //usage:# define bash_full_usage hush_full_usage | 258 | # include "random.h" |
278 | //usage:#endif | 259 | #else |
260 | # define CLEAR_RANDOM_T(rnd) ((void)0) | ||
261 | #endif | ||
262 | #ifndef F_DUPFD_CLOEXEC | ||
263 | # define F_DUPFD_CLOEXEC F_DUPFD | ||
264 | #endif | ||
265 | #ifndef PIPE_BUF | ||
266 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ | ||
267 | #endif | ||
279 | 268 | ||
280 | 269 | ||
281 | /* Build knobs */ | 270 | /* Build knobs */ |
@@ -1148,6 +1137,9 @@ static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch) | |||
1148 | char msg[2]; | 1137 | char msg[2]; |
1149 | msg[0] = ch; | 1138 | msg[0] = ch; |
1150 | msg[1] = '\0'; | 1139 | msg[1] = '\0'; |
1140 | #if HUSH_DEBUG >= 2 | ||
1141 | bb_error_msg("hush.c:%u", lineno); | ||
1142 | #endif | ||
1151 | bb_error_msg("syntax error: unexpected %s", ch == EOF ? "EOF" : msg); | 1143 | bb_error_msg("syntax error: unexpected %s", ch == EOF ? "EOF" : msg); |
1152 | } | 1144 | } |
1153 | 1145 | ||
@@ -1574,9 +1566,8 @@ static sighandler_t install_sighandler(int sig, sighandler_t handler) | |||
1574 | } | 1566 | } |
1575 | 1567 | ||
1576 | static void hush_exit(int exitcode) NORETURN; | 1568 | static void hush_exit(int exitcode) NORETURN; |
1577 | static void fflush_and__exit(void) NORETURN; | ||
1578 | static void restore_ttypgrp_and__exit(void) NORETURN; | ||
1579 | 1569 | ||
1570 | static void restore_ttypgrp_and__exit(void) NORETURN; | ||
1580 | static void restore_ttypgrp_and__exit(void) | 1571 | static void restore_ttypgrp_and__exit(void) |
1581 | { | 1572 | { |
1582 | /* xfunc has failed! die die die */ | 1573 | /* xfunc has failed! die die die */ |
@@ -1585,6 +1576,8 @@ static void restore_ttypgrp_and__exit(void) | |||
1585 | hush_exit(xfunc_error_retval); | 1576 | hush_exit(xfunc_error_retval); |
1586 | } | 1577 | } |
1587 | 1578 | ||
1579 | #if ENABLE_HUSH_JOB | ||
1580 | |||
1588 | /* Needed only on some libc: | 1581 | /* Needed only on some libc: |
1589 | * It was observed that on exit(), fgetc'ed buffered data | 1582 | * It was observed that on exit(), fgetc'ed buffered data |
1590 | * gets "unwound" via lseek(fd, -NUM, SEEK_CUR). | 1583 | * gets "unwound" via lseek(fd, -NUM, SEEK_CUR). |
@@ -1598,14 +1591,13 @@ static void restore_ttypgrp_and__exit(void) | |||
1598 | * and in `cmd` handling. | 1591 | * and in `cmd` handling. |
1599 | * If set as die_func(), this makes xfunc_die() exit via _exit(), not exit(): | 1592 | * If set as die_func(), this makes xfunc_die() exit via _exit(), not exit(): |
1600 | */ | 1593 | */ |
1594 | static void fflush_and__exit(void) NORETURN; | ||
1601 | static void fflush_and__exit(void) | 1595 | static void fflush_and__exit(void) |
1602 | { | 1596 | { |
1603 | fflush_all(); | 1597 | fflush_all(); |
1604 | _exit(xfunc_error_retval); | 1598 | _exit(xfunc_error_retval); |
1605 | } | 1599 | } |
1606 | 1600 | ||
1607 | #if ENABLE_HUSH_JOB | ||
1608 | |||
1609 | /* After [v]fork, in child: do not restore tty pgrp on xfunc death */ | 1601 | /* After [v]fork, in child: do not restore tty pgrp on xfunc death */ |
1610 | # define disable_restore_tty_pgrp_on_exit() (die_func = fflush_and__exit) | 1602 | # define disable_restore_tty_pgrp_on_exit() (die_func = fflush_and__exit) |
1611 | /* After [v]fork, in parent: restore tty pgrp on xfunc death */ | 1603 | /* After [v]fork, in parent: restore tty pgrp on xfunc death */ |
@@ -4011,7 +4003,7 @@ static int i_peek_and_eat_bkslash_nl(struct in_str *input) | |||
4011 | } | 4003 | } |
4012 | } | 4004 | } |
4013 | 4005 | ||
4014 | #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS | 4006 | #if ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS |
4015 | /* Subroutines for copying $(...) and `...` things */ | 4007 | /* Subroutines for copying $(...) and `...` things */ |
4016 | static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote); | 4008 | static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote); |
4017 | /* '...' */ | 4009 | /* '...' */ |
@@ -4179,7 +4171,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
4179 | } | 4171 | } |
4180 | return ch; | 4172 | return ch; |
4181 | } | 4173 | } |
4182 | #endif /* ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS */ | 4174 | #endif /* ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS */ |
4183 | 4175 | ||
4184 | /* Return code: 0 for OK, 1 for syntax error */ | 4176 | /* Return code: 0 for OK, 1 for syntax error */ |
4185 | #if BB_MMU | 4177 | #if BB_MMU |
@@ -4333,13 +4325,13 @@ static int parse_dollar(o_string *as_string, | |||
4333 | o_addchr(dest, SPECIAL_VAR_SYMBOL); | 4325 | o_addchr(dest, SPECIAL_VAR_SYMBOL); |
4334 | break; | 4326 | break; |
4335 | } | 4327 | } |
4336 | #if ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_TICK | 4328 | #if ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_TICK |
4337 | case '(': { | 4329 | case '(': { |
4338 | unsigned pos; | 4330 | unsigned pos; |
4339 | 4331 | ||
4340 | ch = i_getch(input); | 4332 | ch = i_getch(input); |
4341 | nommu_addchr(as_string, ch); | 4333 | nommu_addchr(as_string, ch); |
4342 | # if ENABLE_SH_MATH_SUPPORT | 4334 | # if ENABLE_FEATURE_SH_MATH |
4343 | if (i_peek_and_eat_bkslash_nl(input) == '(') { | 4335 | if (i_peek_and_eat_bkslash_nl(input) == '(') { |
4344 | ch = i_getch(input); | 4336 | ch = i_getch(input); |
4345 | nommu_addchr(as_string, ch); | 4337 | nommu_addchr(as_string, ch); |
@@ -5008,7 +5000,8 @@ static struct pipe *parse_stream(char **pstring, | |||
5008 | * if we see {, we call parse_group(..., end_trigger='}') | 5000 | * if we see {, we call parse_group(..., end_trigger='}') |
5009 | * and it will match } earlier (not here). */ | 5001 | * and it will match } earlier (not here). */ |
5010 | syntax_error_unexpected_ch(ch); | 5002 | syntax_error_unexpected_ch(ch); |
5011 | goto parse_error; | 5003 | G.last_exitcode = 2; |
5004 | goto parse_error1; | ||
5012 | default: | 5005 | default: |
5013 | if (HUSH_DEBUG) | 5006 | if (HUSH_DEBUG) |
5014 | bb_error_msg_and_die("BUG: unexpected %c\n", ch); | 5007 | bb_error_msg_and_die("BUG: unexpected %c\n", ch); |
@@ -5016,6 +5009,8 @@ static struct pipe *parse_stream(char **pstring, | |||
5016 | } /* while (1) */ | 5009 | } /* while (1) */ |
5017 | 5010 | ||
5018 | parse_error: | 5011 | parse_error: |
5012 | G.last_exitcode = 1; | ||
5013 | parse_error1: | ||
5019 | { | 5014 | { |
5020 | struct parse_context *pctx; | 5015 | struct parse_context *pctx; |
5021 | IF_HAS_KEYWORDS(struct parse_context *p2;) | 5016 | IF_HAS_KEYWORDS(struct parse_context *p2;) |
@@ -5049,7 +5044,6 @@ static struct pipe *parse_stream(char **pstring, | |||
5049 | } while (HAS_KEYWORDS && pctx); | 5044 | } while (HAS_KEYWORDS && pctx); |
5050 | 5045 | ||
5051 | o_free(&dest); | 5046 | o_free(&dest); |
5052 | G.last_exitcode = 1; | ||
5053 | #if !BB_MMU | 5047 | #if !BB_MMU |
5054 | if (pstring) | 5048 | if (pstring) |
5055 | *pstring = NULL; | 5049 | *pstring = NULL; |
@@ -5217,7 +5211,7 @@ static char *encode_then_expand_string(const char *str, int process_bkslash, int | |||
5217 | return exp_str; | 5211 | return exp_str; |
5218 | } | 5212 | } |
5219 | 5213 | ||
5220 | #if ENABLE_SH_MATH_SUPPORT | 5214 | #if ENABLE_FEATURE_SH_MATH |
5221 | static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p) | 5215 | static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p) |
5222 | { | 5216 | { |
5223 | arith_state_t math_state; | 5217 | arith_state_t math_state; |
@@ -5469,7 +5463,7 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5469 | } | 5463 | } |
5470 | #endif | 5464 | #endif |
5471 | else if (exp_op == ':') { | 5465 | else if (exp_op == ':') { |
5472 | #if ENABLE_HUSH_BASH_COMPAT && ENABLE_SH_MATH_SUPPORT | 5466 | #if ENABLE_HUSH_BASH_COMPAT && ENABLE_FEATURE_SH_MATH |
5473 | /* It's ${var:N[:M]} bashism. | 5467 | /* It's ${var:N[:M]} bashism. |
5474 | * Note that in encoded form it has TWO parts: | 5468 | * Note that in encoded form it has TWO parts: |
5475 | * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL> | 5469 | * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL> |
@@ -5604,7 +5598,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) | |||
5604 | #if ENABLE_HUSH_TICK | 5598 | #if ENABLE_HUSH_TICK |
5605 | o_string subst_result = NULL_O_STRING; | 5599 | o_string subst_result = NULL_O_STRING; |
5606 | #endif | 5600 | #endif |
5607 | #if ENABLE_SH_MATH_SUPPORT | 5601 | #if ENABLE_FEATURE_SH_MATH |
5608 | char arith_buf[sizeof(arith_t)*3 + 2]; | 5602 | char arith_buf[sizeof(arith_t)*3 + 2]; |
5609 | #endif | 5603 | #endif |
5610 | 5604 | ||
@@ -5698,7 +5692,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) | |||
5698 | val = subst_result.data; | 5692 | val = subst_result.data; |
5699 | goto store_val; | 5693 | goto store_val; |
5700 | #endif | 5694 | #endif |
5701 | #if ENABLE_SH_MATH_SUPPORT | 5695 | #if ENABLE_FEATURE_SH_MATH |
5702 | case '+': { /* <SPECIAL_VAR_SYMBOL>+cmd<SPECIAL_VAR_SYMBOL> */ | 5696 | case '+': { /* <SPECIAL_VAR_SYMBOL>+cmd<SPECIAL_VAR_SYMBOL> */ |
5703 | arith_t res; | 5697 | arith_t res; |
5704 | 5698 | ||
diff --git a/shell/hush_test/hush-misc/exitcode2.right b/shell/hush_test/hush-misc/exitcode2.right new file mode 100644 index 000000000..0a57b9b1b --- /dev/null +++ b/shell/hush_test/hush-misc/exitcode2.right | |||
@@ -0,0 +1,4 @@ | |||
1 | hush: syntax error: unexpected ) | ||
2 | Done:2 | ||
3 | hush: can't open 'does_not_exist': No such file or directory | ||
4 | Done:1 | ||
diff --git a/shell/hush_test/hush-misc/exitcode2.tests b/shell/hush_test/hush-misc/exitcode2.tests new file mode 100755 index 000000000..79a6ebd50 --- /dev/null +++ b/shell/hush_test/hush-misc/exitcode2.tests | |||
@@ -0,0 +1,12 @@ | |||
1 | # syntax error should return status 2 | ||
2 | cat >test.sh <<EOF | ||
3 | ) | ||
4 | EOF | ||
5 | chmod +x test.sh | ||
6 | $THIS_SH ./test.sh | ||
7 | echo Done:$? | ||
8 | rm -f test.sh | ||
9 | |||
10 | # redirection error with special builtin should return status 1 | ||
11 | (eval cat <does_not_exist) | ||
12 | echo Done:$? | ||
diff --git a/shell/hush_test/hush-redir/redir_leak.right b/shell/hush_test/hush-redir/redir_leak.right new file mode 100644 index 000000000..b1c48292b --- /dev/null +++ b/shell/hush_test/hush-redir/redir_leak.right | |||
@@ -0,0 +1,6 @@ | |||
1 | 4 | ||
2 | 4 | ||
3 | 4 | ||
4 | 4 | ||
5 | 4 | ||
6 | 4 | ||
diff --git a/shell/hush_test/hush-redir/redir_leak.tests b/shell/hush_test/hush-redir/redir_leak.tests new file mode 100755 index 000000000..c8a9c6343 --- /dev/null +++ b/shell/hush_test/hush-redir/redir_leak.tests | |||
@@ -0,0 +1,10 @@ | |||
1 | # Each of these should show only four lines: | ||
2 | # fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. | ||
3 | # This test detects bugs where redirects leave stray open fds. | ||
4 | |||
5 | ls -1 /proc/self/fd | wc -l | ||
6 | ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l | ||
7 | ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l | ||
8 | echo "`ls -1 /proc/self/fd `" | wc -l | ||
9 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l | ||
10 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l | ||
diff --git a/shell/math.h b/shell/math.h index 864bee691..32e1ffe35 100644 --- a/shell/math.h +++ b/shell/math.h | |||
@@ -63,7 +63,7 @@ | |||
63 | 63 | ||
64 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | 64 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN |
65 | 65 | ||
66 | #if ENABLE_SH_MATH_SUPPORT_64 | 66 | #if ENABLE_FEATURE_SH_MATH_64 |
67 | typedef long long arith_t; | 67 | typedef long long arith_t; |
68 | #define ARITH_FMT "%lld" | 68 | #define ARITH_FMT "%lld" |
69 | #define strto_arith_t strtoull | 69 | #define strto_arith_t strtoull |
diff --git a/sysklogd/logread.c b/sysklogd/logread.c index 5b999730a..1f0c6252d 100644 --- a/sysklogd/logread.c +++ b/sysklogd/logread.c | |||
@@ -11,7 +11,8 @@ | |||
11 | //config:config LOGREAD | 11 | //config:config LOGREAD |
12 | //config: bool "logread" | 12 | //config: bool "logread" |
13 | //config: default y | 13 | //config: default y |
14 | //config: depends on FEATURE_IPC_SYSLOG | 14 | //WRONG: it should be compilable without SYSLOG=y: |
15 | //WRONG: depends on FEATURE_IPC_SYSLOG | ||
15 | //config: help | 16 | //config: help |
16 | //config: If you enabled Circular Buffer support, you almost | 17 | //config: If you enabled Circular Buffer support, you almost |
17 | //config: certainly want to enable this feature as well. This | 18 | //config: certainly want to enable this feature as well. This |
diff --git a/testsuite/bunzip2/bzcat-does-not-remove-compressed-file b/testsuite/bzcat/bzcat-does-not-remove-compressed-file index 7d4016ec5..7d4016ec5 100644 --- a/testsuite/bunzip2/bzcat-does-not-remove-compressed-file +++ b/testsuite/bzcat/bzcat-does-not-remove-compressed-file | |||
diff --git a/testsuite/cpio.tests b/testsuite/cpio.tests index d44c95b10..88ec086b6 100755 --- a/testsuite/cpio.tests +++ b/testsuite/cpio.tests | |||
@@ -127,6 +127,7 @@ testing "cpio extracts in existing directory" \ | |||
127 | " "" "" | 127 | " "" "" |
128 | SKIP= | 128 | SKIP= |
129 | 129 | ||
130 | optional FEATURE_CPIO_O | ||
130 | testing "cpio uses by default uid/gid" \ | 131 | testing "cpio uses by default uid/gid" \ |
131 | "echo $0 | cpio -o -H newc | cpio -tv 2>&1 | tail -n +2 | awk ' { print \$2 } '; echo \$?" \ | 132 | "echo $0 | cpio -o -H newc | cpio -tv 2>&1 | tail -n +2 | awk ' { print \$2 } '; echo \$?" \ |
132 | "\ | 133 | "\ |
@@ -135,6 +136,7 @@ $user/$group | |||
135 | " "" "" | 136 | " "" "" |
136 | SKIP= | 137 | SKIP= |
137 | 138 | ||
139 | optional FEATURE_CPIO_O | ||
138 | testing "cpio -R with create" \ | 140 | testing "cpio -R with create" \ |
139 | "echo $0 | cpio -o -H newc -R 1234:5678 | cpio -tv 2>&1 | tail -n +2 | awk ' { print \$2 } '; echo \$?" \ | 141 | "echo $0 | cpio -o -H newc -R 1234:5678 | cpio -tv 2>&1 | tail -n +2 | awk ' { print \$2 } '; echo \$?" \ |
140 | "\ | 142 | "\ |
@@ -143,6 +145,7 @@ testing "cpio -R with create" \ | |||
143 | " "" "" | 145 | " "" "" |
144 | SKIP= | 146 | SKIP= |
145 | 147 | ||
148 | optional FEATURE_CPIO_O | ||
146 | testing "cpio -R with extract" \ | 149 | testing "cpio -R with extract" \ |
147 | "echo $0 | cpio -o -H newc | cpio -tv -R 8765:4321 2>&1 | tail -n +2 | awk ' { print \$2 } '; echo \$?" \ | 150 | "echo $0 | cpio -o -H newc | cpio -tv -R 8765:4321 2>&1 | tail -n +2 | awk ' { print \$2 } '; echo \$?" \ |
148 | "\ | 151 | "\ |
diff --git a/testsuite/tar.tests b/testsuite/tar.tests index ffcbe9ba9..9f7ce1587 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests | |||
@@ -299,11 +299,11 @@ l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI= | |||
299 | " | 299 | " |
300 | SKIP= | 300 | SKIP= |
301 | 301 | ||
302 | optional UNICODE_SUPPORT | 302 | optional UNICODE_SUPPORT FEATURE_TAR_GNU_EXTENSIONS FEATURE_SEAMLESS_BZ2 FEATURE_TAR_AUTODETECT |
303 | testing "Pax-encoded UTF8 names and symlinks" '\ | 303 | testing "Pax-encoded UTF8 names and symlinks" '\ |
304 | tar xvf ../tar.utf8.tar.bz2 2>&1; echo $? | 304 | tar xvf ../tar.utf8.tar.bz2 2>&1; echo $? |
305 | export LANG=en_US.UTF-8 | 305 | export LANG=en_US.UTF-8 |
306 | ls -l etc/ssl/certs/* | sed "s:.*etc/:etc/:" | 306 | ls -l etc/ssl/certs/* | sed "s:.*etc/:etc/:" | sort |
307 | unset LANG | 307 | unset LANG |
308 | rm -rf etc usr | 308 | rm -rf etc usr |
309 | ' "\ | 309 | ' "\ |
diff --git a/util-linux/fstrim.c b/util-linux/fstrim.c index 51400ef0b..fc51878b6 100644 --- a/util-linux/fstrim.c +++ b/util-linux/fstrim.c | |||
@@ -47,25 +47,6 @@ struct fstrim_range { | |||
47 | #define FITRIM _IOWR('X', 121, struct fstrim_range) | 47 | #define FITRIM _IOWR('X', 121, struct fstrim_range) |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | static const struct suffix_mult fstrim_sfx[] = { | ||
51 | { "KiB", 1024 }, | ||
52 | { "kiB", 1024 }, | ||
53 | { "K", 1024 }, | ||
54 | { "k", 1024 }, | ||
55 | { "MiB", 1048576 }, | ||
56 | { "miB", 1048576 }, | ||
57 | { "M", 1048576 }, | ||
58 | { "m", 1048576 }, | ||
59 | { "GiB", 1073741824 }, | ||
60 | { "giB", 1073741824 }, | ||
61 | { "G", 1073741824 }, | ||
62 | { "g", 1073741824 }, | ||
63 | { "KB", 1000 }, | ||
64 | { "MB", 1000000 }, | ||
65 | { "GB", 1000000000 }, | ||
66 | { "", 0 } | ||
67 | }; | ||
68 | |||
69 | int fstrim_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 50 | int fstrim_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
70 | int fstrim_main(int argc UNUSED_PARAM, char **argv) | 51 | int fstrim_main(int argc UNUSED_PARAM, char **argv) |
71 | { | 52 | { |
@@ -98,11 +79,11 @@ int fstrim_main(int argc UNUSED_PARAM, char **argv) | |||
98 | range.len = ULLONG_MAX; | 79 | range.len = ULLONG_MAX; |
99 | 80 | ||
100 | if (opts & OPT_o) | 81 | if (opts & OPT_o) |
101 | range.start = xatoull_sfx(arg_o, fstrim_sfx); | 82 | range.start = xatoull_sfx(arg_o, kmg_i_suffixes); |
102 | if (opts & OPT_l) | 83 | if (opts & OPT_l) |
103 | range.len = xatoull_sfx(arg_l, fstrim_sfx); | 84 | range.len = xatoull_sfx(arg_l, kmg_i_suffixes); |
104 | if (opts & OPT_m) | 85 | if (opts & OPT_m) |
105 | range.minlen = xatoull_sfx(arg_m, fstrim_sfx); | 86 | range.minlen = xatoull_sfx(arg_m, kmg_i_suffixes); |
106 | 87 | ||
107 | mp = argv[optind]; | 88 | mp = argv[optind]; |
108 | if (find_block_device(mp)) { | 89 | if (find_block_device(mp)) { |