changeset 696:99ca30ad3d2b

Add rebound support to intercept error_exit() and longjmp instead.
author Rob Landley <rob@landley.net>
date Fri, 16 Nov 2012 00:35:46 -0600
parents d2dde3d0ef05
children ca9a1d8e2531
files lib/lib.c main.c toys.h toys/lsb/killall.c toys/posix/sh.c
diffstat 5 files changed, 18 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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;
--- 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 <sched.h>
 #include <shadow.h>
 #include <stdarg.h>
+#include <stddef.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -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).
--- 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!");
   }
 
--- 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);