]> mj.ucw.cz Git - eval.git/blobdiff - src/box.c
Rewritten the pedant utility. It is now able to limit the output per
[eval.git] / src / box.c
index 17e1487ec31accdc6b23b2819fbfd3fc2009a57e..126452adbe176f9f511e38a47bef1e7f32cc1124 100644 (file)
--- a/src/box.c
+++ b/src/box.c
@@ -44,6 +44,7 @@ static int is_ptraced;
 static volatile int timer_tick;
 static struct timeval start_time;
 static int ticks_per_sec;
+static int exec_seen;
 
 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0
 /* glibc 2.1 or newer -> has lseek64 */
@@ -161,11 +162,6 @@ valid_syscall(struct user *u)
 {
   switch (u->regs.orig_eax)
     {
-    case __NR_execve:
-      {
-       static int exec_counter;
-       return !exec_counter++;
-      }
     case __NR_open:
     case __NR_creat:
     case __NR_unlink:
@@ -264,11 +260,11 @@ valid_syscall(struct user *u)
       return allow_times;
     case __NR_kill:
       if (u->regs.ebx == box_pid)
-       die("Commited suicide by signal %d", (int)u->regs.ecx);
+       die("Committed suicide by signal %d", (int)u->regs.ecx);
       return 0;
     case __NR_tgkill:
       if (u->regs.ebx == box_pid && u->regs.ecx == box_pid)
-       die("Commited suicide by signal %d", (int)u->regs.edx);
+       die("Committed suicide by signal %d", (int)u->regs.edx);
       return 0;
     default:
       return 0;
@@ -408,7 +404,7 @@ boxkeeper(void)
       if (WIFSIGNALED(stat))
        {
          box_pid = 0;
-         die("Caught fatal signal %d", WTERMSIG(stat));
+         die("Caught fatal signal %d%s", WTERMSIG(stat), (syscall_count ? "" : " during startup"));
        }
       if (WIFSTOPPED(stat))
        {
@@ -425,8 +421,15 @@ boxkeeper(void)
              else if (stop_count & 1)          /* Syscall entry */
                {
                  msg(">> Syscall %3ld (%08lx,%08lx,%08lx) ", u.regs.orig_eax, u.regs.ebx, u.regs.ecx, u.regs.edx);
-                 syscall_count++;
-                 if (!valid_syscall(&u))
+                 if (!exec_seen)
+                   {
+                     msg("[master] ");
+                     if (u.regs.orig_eax == __NR_execve)
+                       exec_seen = 1;
+                   }
+                 else if (valid_syscall(&u))
+                   syscall_count++;
+                 else
                    {
                      /*
                       * Unfortunately, PTRACE_KILL kills _after_ the syscall completes,
@@ -491,8 +494,14 @@ box_inside(int argc, char **argv)
   rl.rlim_cur = rl.rlim_max = 64;
   if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
     die("setrlimit: %m");
-  if (filter_syscalls && ptrace(PTRACE_TRACEME) < 0)
-    die("ptrace(PTRACE_TRACEME): %m");
+  if (filter_syscalls)
+    {
+      if (ptrace(PTRACE_TRACEME) < 0)
+       die("ptrace(PTRACE_TRACEME): %m");
+      /* Trick: Make sure that we are stopped until the boxkeeper wakes up. */
+      signal(SIGCHLD, SIG_IGN);
+      raise(SIGCHLD);
+    }
   execve(args[0], args, (pass_environ ? environ : env));
   die("execve(\"%s\"): %m", args[0]);
 }