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
* die_sleep and longjmp here instead. */
die_sleep = -1;
- /* Reset the libc getopt() function, which keeps internal state.
- *
- * BSD-derived getopt() functions require that optind be reset to 1 in
- * order to reset getopt() state. This used to be generally accepted
- * way of resetting getopt(). However, glibc's getopt()
- * has additional getopt() state beyond optind, and requires that
- * optind be set zero to reset its state. So the unfortunate state of
- * affairs is that BSD-derived versions of getopt() misbehave if
- * optind is set to 0 in order to reset getopt(), and glibc's getopt()
- * will core ump if optind is set 1 in order to reset getopt().
- *
- * More modern versions of BSD require that optreset be set to 1 in
- * order to reset getopt(). Sigh. Standards, anyone?
- */
-#ifdef __GLIBC__
- optind = 0;
-#else /* BSD style */
- optind = 1;
- /* optreset = 1; */
-#endif
/* option_mask32 = 0; - not needed */
argc = 1;
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()