# HG changeset patch # User Rob Landley # Date 1353047746 21600 # Node ID 99ca30ad3d2bf419e73c79a0d08e39400eb4a935 # Parent d2dde3d0ef05e16f83795ba7af95a8c252a0eef3 Add rebound support to intercept error_exit() and longjmp instead. diff -r d2dde3d0ef05 -r 99ca30ad3d2b lib/lib.c --- a/lib/lib.c Thu Nov 15 16:15:51 2012 -0600 +++ b/lib/lib.c Fri Nov 16 00:35:46 2012 -0600 @@ -61,7 +61,9 @@ verror_msg(msg, 0, va); va_end(va); - exit(!toys.exitval ? 1 : toys.exitval); + if (!toys.exitval) toys.exitval++; + if (toys.rebound) longjmp(*toys.rebound, 1); + else exit(toys.exitval); } @@ -74,7 +76,9 @@ verror_msg(msg, errno, va); va_end(va); - exit(!toys.exitval ? 1 : toys.exitval); + if (!toys.exitval) toys.exitval++; + if (toys.rebound) longjmp(*toys.rebound, 1); + else exit(toys.exitval); } // Die unless we can allocate memory. diff -r d2dde3d0ef05 -r 99ca30ad3d2b main.c --- a/main.c Thu Nov 15 16:15:51 2012 -0600 +++ b/main.c Fri Nov 16 00:35:46 2012 -0600 @@ -76,10 +76,10 @@ if ((which->flags & TOYFLAG_NEEDROOT) && euid) error_exit("Not root"); } - // Free old toys contents (to be reentrant) + // Free old toys contents (to be reentrant), but leave rebound if any if (toys.optargs != toys.argv+1) free(toys.optargs); - memset(&toys, 0, sizeof(struct toy_context)); + memset(&toys, 0, offsetof(struct toy_context, rebound)); toys.which = which; toys.argv = argv; diff -r d2dde3d0ef05 -r 99ca30ad3d2b toys.h --- a/toys.h Thu Nov 15 16:15:51 2012 -0600 +++ b/toys.h Fri Nov 16 00:35:46 2012 -0600 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -103,6 +104,7 @@ int optc; // Count of optargs int exithelp; // Should error_exit print a usage message first? int old_umask; // Old umask preserved by TOYFLAG_UMASK + jmp_buf *rebound; // longjmp here instead of exit when do_rebound set } toys; // One big temporary buffer, for use by commands (not library functions). diff -r d2dde3d0ef05 -r 99ca30ad3d2b toys/lsb/killall.c --- a/toys/lsb/killall.c Thu Nov 15 16:15:51 2012 -0600 +++ b/toys/lsb/killall.c Fri Nov 16 00:35:46 2012 -0600 @@ -48,7 +48,7 @@ toys.exitval++; if (!*toys.optargs) { - toys.exithelp = 1; + toys.exithelp++; error_exit("Process name missing!"); } diff -r d2dde3d0ef05 -r 99ca30ad3d2b toys/posix/sh.c --- a/toys/posix/sh.c Thu Nov 15 16:15:51 2012 -0600 +++ b/toys/posix/sh.c Fri Nov 16 00:35:46 2012 -0600 @@ -293,12 +293,17 @@ // Is this command a builtin that should run in this process? if (tl && (tl->flags & TOYFLAG_NOFORK)) { struct toy_context temp; + jmp_buf rebound; // This fakes lots of what toybox_main() does. memcpy(&temp, &toys, sizeof(struct toy_context)); memset(&toys, 0, sizeof(struct toy_context)); - toy_init(tl, cmd->argv); - tl->toy_main(); + + if (!setjmp(rebound)) { + toys.rebound = rebound; + toy_init(tl, cmd->argv); + tl->toy_main(); + } cmd->pid = toys.exitval; free(toys.optargs); if (toys.old_umask) umask(toys.old_umask);