1 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 5"echo blah" shell will fork and exec /bin/echo. To this end, shells 6have 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 only if it is marked 14as such in applets.src.h or in their inline "//applet:" directives. 15 16In C, if you want to call a program and wait for it, use 17spawn_and_wait(argv), BB_EXECVP(prog,argv) or BB_EXECLP(prog,argv0,...). 18They check whether program name is an applet name and optionally 19do NOFORK/NOEXEC thing depending on configuration. 20 21 22 Relevant CONFIG options 23 24FEATURE_PREFER_APPLETS 25 Globally enables NOFORK/NOEXEC tricks for such programs as xargs 26 and find: 27 BB_EXECVP(cmd, argv) will try to exec /proc/self/exe 28 if command's name matches some applet name; 29 spawn_and_wait(argv) will do NOFORK/NOEXEC tricks 30 31//TODO: the above two things probably should have separate options? 32 33FEATURE_SH_STANDALONE 34 shells will try to exec /proc/self/exe if command's name matches 35 some applet name; shells will do NOEXEC trick on NOEXEC applets 36 37//TODO: split (same as for PREFER_APPLETS) 38 39FEATURE_SH_NOFORK 40 shells will do NOFORK trick on NOFORK applets 41 42NB: shell builtins use these tricks regardless of FEATURE_SH_STANDALONE, 43FEATURE_PREFER_APPLETS or FEATURE_SH_NOFORK. In effect, builtins 44are "always NOFORK". 45 46 47 NOEXEC 48 49NOEXEC applet should work correctly if another applet forks and then 50executes exit(<applet>_main(argc,argv)) in the child. The rules 51roughly are: 52 53* do not expect shared global variables/buffers to be in their 54 "initialized" state. Examples: xfunc_error_retval can be != 1, 55 bb_common_bufsiz1 can be scribbled over, ... 56 (although usually xfunc_error_retval's state is not a problem). 57* do not expect that stdio wasn't used before. Calling set[v]buf() 58 can be disastrous. 59* ... 60 61NOEXEC applets save only one half of fork+exec overhead. 62NOEXEC trick is disabled for NOMMU build. 63 64 65 NOFORK 66 67NOFORK applet should work correctly if another applet simply runs 68<applet>_main(argc,argv) and then continues with its business. 69xargs, find, shells do it (grep for "spawn_and_wait" and 70"run_nofork_applet" to find more users). 71 72This poses much more serious limitations on what applet can do: 73 74* all NOEXEC limitations apply. 75* do not run for a long time or wait for user input: 76 hush shell only handles signals (like ^C) after you return 77 from APPLET_main(). 78* do not ever exit() or exec(). 79 - xfuncs are okay. They are using special trick to return 80 to the caller applet instead of dying when they detect "x" condition. 81 - you may "exit" to caller applet by calling xfunc_die(). Return value 82 is taken from xfunc_error_retval. 83 - fflush_stdout_and_exit(n) is ok to use. 84* do not use shared global data, or save/restore shared global data 85 (e.g. bb_common_bufsiz1) prior to returning. 86 - getopt32() is ok to use. You do not need to save/restore option_mask32, 87 xfunc_error_retval, and logmode - it is already done by core code. 88* if you allocate memory, you can use xmalloc() only on the very first 89 allocation. All other allocations should use malloc[_or_warn](). 90 After first allocation, you cannot use any xfuncs. 91 Otherwise, failing xfunc will return to caller applet 92 without freeing malloced data! 93* the same applies to other resources, such as open fds: no xfuncs after 94 acquiring them! 95* All allocated data, opened files, signal handlers, termios settings 96 etc should be freed/closed/restored prior to return. 97 98Currently, ash shell signal handling is implemented in a way that signals 99have non-SA_RESTARTed handlers. This means that system calls can 100return EINTR. An example of such problem is "yes" applet: 101it is implemented so that it has a writing loop, this loop is exited on 102any write error, and in the case of user pressing ^C the error was EINTR. 103The problem is, the error causes stdout FILE* object to get into error 104state, needing clearerr() - or else subsequent shell output will also 105not work. ("yes" has been downgraded to NOEXEC, since hush signal handling 106does not have this problem - which makes "yes" to not exit on ^C (bug). 107But stray EINTRs can be seen in any NOFORK under ash, until ash is fixed). 108 109NOFORK applets give the most of speed advantage, but are trickiest 110to implement. In order to minimize amount of bugs and maintenance, 111prime candidates for NOFORK-ification are those applets which 112are small and easy to audit, and those which are more likely to be 113frequently executed from shell/find/xargs, particularly in shell 114script loops. Applets which mess with signal handlers, termios etc 115are probably not worth the effort. 116 117Applets which must be interruptible by ^C in shells can not be NOFORKs. 118 119Any NOFORK applet is also a NOEXEC applet. 120 121 122 Calling NOFORK applets 123 124API to call NOFORK applets is two functions: 125 126 run_nofork_applet(appno, argv) 127 spawn_and_wait(argv) // only if FEATURE_PREFER_APPLETS=y 128 129First one is directly used by shells if FEATURE_SH_NOFORK=y. 130Second one is used by many applets, but main users are xargs and find. 131It itself calls run_nofork_applet(), if argv[0] is a name 132of a NOFORK applet. 133 134run_nofork_applet() saves/inits/restores option parsing, xfunc_error_retval, 135logmode, applet_name. Thus, for example, caller does not need to worry about 136option_mask32 getting trashed. 137 138 139 Calling NOEXEC applets 140 141It's the same trusty spawn_and_wait(argv). If FEATURE_PREFER_APPLETS=y, 142it does NOEXEC trick. It resets xfunc_error_retval = 1 and 143logmode = LOGMODE_STDIO in the child. 144