if (WIFSIGNALED(status))
return WTERMSIG(status) + 1000;
return 0;
- if (WIFEXITED(status))
- return WEXITSTATUS(status);
- if (WIFSIGNALED(status))
- return WTERMSIG(status) + 1000;
- return 0;
}
#if ENABLE_FEATURE_PREFER_APPLETS
applet_name = APPLET_NAME(applet_no);
xfunc_error_retval = EXIT_FAILURE;
- /*option_mask32 = 0; - not needed */
- /* special flag for xfunc_die(). If xfunc will "die"
+
+ /* Special flag for xfunc_die(). If xfunc will "die"
* in NOFORK applet, xfunc_die() sees negative
* die_sleep and longjmp here instead. */
die_sleep = -1;
+ /* option_mask32 = 0; - not needed */
+
argc = 1;
while (argv[argc])
argc++;
memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
/* Finally we can call NOFORK applet's main() */
rc = applet_main[applet_no](argc, tmp_argv);
+
+ /* The whole reason behind nofork_save_area is that <applet>_main
+ * may exit non-locally! For example, in hush Ctrl-Z tries
+ * (modulo bugs) to dynamically create a child (backgrounded task)
+ * if it detects that Ctrl-Z was pressed when a NOFORK was running.
+ * Testcase: interactive "rm -i".
+ * Don't fool yourself into thinking "and <applet>_main() returns
+ * quickly here" and removing "useless" nofork_save_area code. */
+
} else { /* xfunc died in NOFORK applet */
/* in case they meant to return 0... */
if (rc == -2222)
/* Restoring globals */
restore_nofork_data(old);
- return rc;
+ return rc & 0xff; /* don't confuse people with "exitcodes" >255 */
}
int run_nofork_applet(int applet_no, char **argv)
if (pid < 0) /* wtf? */
bb_perror_msg_and_die("vfork");
if (pid) /* parent */
- exit(0);
+ exit(EXIT_SUCCESS);
/* child - re-exec ourself */
re_exec(argv);
}
if (pid < 0) /* wtf? */
bb_perror_msg_and_die("fork");
if (pid) /* parent */
- exit(0);
+ exit(EXIT_SUCCESS);
/* child */
}
#define forkexit_or_rexec(argv) forkexit_or_rexec()