blob: 51bbcba3be071e7b1443fcf3095f69ffa581ecdc [file] [log] [blame]
Denis Vlasenko0d058362007-04-11 16:16:41 +00001 NOEXEC and NOFORK applets.
2
3Unix shells traditionally execute some commands internally in the attempt
4to dramatically speed up execution. It will be slow as hell if for every
Denis Vlasenko8fd37122007-04-11 19:27:22 +00005"echo blah" shell will fork and exec /bin/echo. For this end, shells
Denis Vlasenko0d058362007-04-11 16:16:41 +00006have to _reimplement_ these commands internally.
7
8Busybox is unique in this regard because it already is a collection
9of reimplemented Unix commands, and we can do the same trick
10for speeding up busybox shells, and more. NOEXEC and NOFORK applets
11are exactly those applets which are eligible for these tricks.
12
13Applet will be subject to NOFORK/NOEXEC tricks if it is marked as such
14in applets.h. CONFIG_FEATURE_PREFER_APPLETS is a config option which
15globally enables usage of NOFORK/NOEXEC tricks.
16
17If you want to call a program and wait for it, use spawn_and_wait(argv).
18It will check whether argv[0] is an applet name and will optionally
19do NOFORK/NOEXEC thing.
20
21NOEXEC
22
23NOEXEC applet should work correctly if another applet forks and then
24executes exit(<applet>_main(argc,argv)) in the child. The rules
25roughly are:
26
27* do not expect shared global variables/buffers to be in their
28 "initialized" state. Examples: xfunc_error_retval can be != 1,
29 bb_common_bufsiz1 can be scribbled over, ...
30* do not expect that stdio wasn't used before. Calling set[v]buf()
31 can be disastrous.
32* ...
33
34NOEXEC applets save only one half of fork+exec overhead.
35NOEXEC trick is disabled for NOMMU compile.
36
37NOFORK
38
39NOFORK applet should work correctly if another applet simply runs
40<applet>_main(argc,argv) and then continues with its business (xargs,
41find, shells can do it). This poses much more serious limitations
42on what applet can/cannot do:
43
44* all NOEXEC limitations apply.
45* do not ever exit() or exec().
46 - xfuncs are okay. They are using special trick to return
47 to the caller applet instead of dying when they detect "x" condition.
48 - you may "exit" to caller applet by calling xfunc_die(). Return value
49 is taken from xfunc_error_retval.
50 - fflush_stdout_and_exit(n) is ok to use.
51* do not use shared global data, or save/restore shared global data
52 prior to returning. (e.g. bb_common_bufsiz1 is off-limits).
53 - getopt32() is ok to use. You do not need to save/restore option_mask32,
54 it is already done by core code.
55* if you allocate memory, you can use xmalloc() only on the very first
56 allocation. All other allocations should use malloc[_or_warn]().
57 After first allocation, you cannot use any xfuncs.
58* All allocated data, opened files, signal handlers, termios settings,
59 O_NONBLOCK flags etc should be freed/closed/restored prior to return.
60* ...
61
62NOFORK applets give the most of speed advantage, but are trickiest
63to implement. In order to minimize amount of bugs and maintenance,
64prime candidates for NOFORK-ification are those applets which
65are small and easy to audit, and those which are more likely to be
66frequently executed from shell/find/xargs, particularly in shell
67script loops. Applets which mess with signal handlers, termios etc
68are probably not worth the effort.
69
70Any NOFORK applet is also a NOEXEC applet.