* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
#include "libbb.h"
int die_sleep;
+#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH
+jmp_buf die_jmp;
+#endif
+
+void xfunc_die(void)
+{
+ if (die_sleep) {
+ if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH)
+ && die_sleep < 0
+ ) {
+ /* Special case. We arrive here if NOFORK applet
+ * calls xfunc, which then decides to die.
+ * We don't die, but jump instead back to caller.
+ * NOFORK applets still cannot carelessly call xfuncs:
+ * p = xmalloc(10);
+ * q = xmalloc(10); // BUG! if this dies, we leak p!
+ */
+ /* -2222 means "zero" (longjmp can't pass 0)
+ * run_nofork_applet() catches -2222. */
+ longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222);
+ }
+ sleep(die_sleep);
+ }
+ exit(xfunc_error_retval);
+}
void bb_error_msg_and_die(const char *s, ...)
{
va_start(p, s);
bb_verror_msg(s, p, NULL);
va_end(p);
- if (die_sleep)
- sleep(die_sleep);
- exit(bb_default_error_retval);
+ xfunc_die();
}