httpd: fix CGI handling bug (we were closing wrong fd).
[oweals/busybox.git] / libbb / error_msg_and_die.c
index 39178a3ce2ad75fa13dbe9aa38a33f0b4ef96c69..0e99a03cfa96ce204a751f35fdf4cdd096f71669 100644 (file)
 #include "libbb.h"
 
 int die_sleep;
+#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH
 jmp_buf die_jmp;
+#endif
 
-void sleep_and_die(void)
+void xfunc_die(void)
 {
        if (die_sleep) {
-               /* Special case: don't die, but jump */
-               if (die_sleep < 0)
-                       longjmp(die_jmp, xfunc_error_retval);
+               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);
@@ -30,5 +43,5 @@ void bb_error_msg_and_die(const char *s, ...)
        va_start(p, s);
        bb_verror_msg(s, p, NULL);
        va_end(p);
-       sleep_and_die();
+       xfunc_die();
 }