NOFORK
NOFORK applet should work correctly if another applet simply runs
-<applet>_main(argc,argv) and then continues with its business (xargs,
-find, shells can do it). This poses much more serious limitations
-on what applet can/cannot do:
+<applet>_main(argc,argv) and then continues with its business.
+xargs, find, shells do it (grep for "spawn_and_wait" and
+"run_nofork_applet" to find more users).
+
+This poses much more serious limitations on what applet can do:
* all NOEXEC limitations apply.
* do not ever exit() or exec().
is taken from xfunc_error_retval.
- fflush_stdout_and_exit(n) is ok to use.
* do not use shared global data, or save/restore shared global data
- prior to returning. (e.g. bb_common_bufsiz1 is off-limits).
+ (e.g. bb_common_bufsiz1) prior to returning.
- getopt32() is ok to use. You do not need to save/restore option_mask32,
it is already done by core code.
* if you allocate memory, you can use xmalloc() only on the very first
are probably not worth the effort.
Any NOFORK applet is also a NOEXEC applet.
+
+
+ Relevant CONFIG options
+
+FEATURE_PREFER_APPLETS
+ BB_EXECVP(cmd, argv) will try to exec /proc/self/exe
+ if command's name matches some applet name
+ applet tables will contain NOFORK/NOEXEC bits
+ spawn_and_wait(argv) will do NOFORK/NOEXEC tricks
+
+FEATURE_SH_STANDALONE (needs FEATURE_PREFER_APPLETS=y)
+ shells will try to exec /proc/self/exe if command's name matches
+ some applet name
+ shells will do NOEXEC trick on NOEXEC applets
+
+FEATURE_SH_NOFORK (needs FEATURE_PREFER_APPLETS=y)
+ shells will do NOFORK trick on NOFORK applets
# define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
#endif
+
int execable_file(const char *name) FAST_FUNC;
char *find_execable(const char *filename, char **PATHp) FAST_FUNC;
int exists_execable(const char *filename) FAST_FUNC;
default n
depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS
help
- This option causes busybox shells [currently only ash]
- to not execute typical fork/exec/wait sequence, but call <applet>_main
- directly, if possible. (Sometimes it is not possible: for example,
+ This option causes busybox shells to not execute typical
+ fork/exec/wait sequence, but call <applet>_main directly,
+ if possible. (Sometimes it is not possible: for example,
this is not possible in pipes).
This will be done only for some applets (those which are marked
This may significantly speed up some shell scripts.
- This feature is relatively new. Use with care.
+ This feature is relatively new. Use with care. Report bugs
+ to project mailing list.
endmenu
* cmd ; ... { list } ; ...
* cmd && ... { list } && ...
* cmd || ... { list } || ...
- * If it is, then we can run cmd as a builtin, NOFORK [do we do this?],
+ * If it is, then we can run cmd as a builtin, NOFORK,
* or (if SH_STANDALONE) an applet, and we can run the { list }
* with run_list. If it isn't one of these, we fork and exec cmd.
*
}
/* Expand the rest into (possibly) many strings each */
- if (0) {}
#if ENABLE_HUSH_BASH_COMPAT
- else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
+ if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
- }
+ } else
#endif
- else {
+ {
argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
}
return rcode;
}
- if (ENABLE_FEATURE_SH_STANDALONE) {
+ if (ENABLE_FEATURE_SH_NOFORK) {
int n = find_applet_by_name(argv_expanded[0]);
if (n >= 0 && APPLET_IS_NOFORK(n)) {
rcode = redirect_and_varexp_helper(&new_env, &old_vars, command, squirrel, argv_expanded);