Index: /trunk/src/kmk/job.c
===================================================================
--- /trunk/src/kmk/job.c	(revision 1289)
+++ /trunk/src/kmk/job.c	(revision 1290)
@@ -1211,28 +1211,49 @@
     {
       int    rc;
+      char **argv_spawn = NULL;
       char **p2 = argv;
-      while (*p2 && strncmp(*p2, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
-          p2++;
-      assert(*p2);
+      while (*p2 && strncmp (*p2, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
+        p2++;
+      assert (*p2);
       set_command_state (child->file, cs_running);
+      child->pid = 0;
       if (p2 != argv)
-          rc = kmk_builtin_command(*p2);
+        rc = kmk_builtin_command (*p2, &argv_spawn, &child->pid);
       else
-      {
+        {
           int argc = 1;
           while (argv[argc])
-              argc++;
-          rc = kmk_builtin_command_parsed(argc, argv);
-      }
+            argc++;
+          rc = kmk_builtin_command_parsed (argc, argv, &argv_spawn, &child->pid);
+        }
+
 #ifndef VMS
       free (argv[0]);
       free ((char *) argv);
 #endif
-      if (!rc)
-          goto next_command;
-      child->pid = (pid_t)42424242;
-      child->status = rc << 8;
-      child->has_status = 1;
-      return;
+
+      /* synchronous command execution? */
+      if (!rc && !argv_spawn)
+        goto next_command;
+
+      /* spawned a child? */
+      if (!rc && child->pid)
+        {
+          ++job_counter;
+          return;
+        }
+
+      /* failure? */
+      if (rc)
+        {
+          child->pid = (pid_t)42424242;
+          child->status = rc << 8;
+          child->has_status = 1;
+          unblock_sigs();
+          return;
+        }
+
+      /* conditional check == true; kicking off a child (not kmk_builtin_*). */
+      argv = argv_spawn;
     }
 #endif /* CONFIG_WITH_KMK_BUILTIN */
@@ -1509,4 +1530,7 @@
 
   /* Free the storage used by the child's argument list.  */
+#ifdef KMK /* leak */
+ cleanup_argv:
+#endif
 #ifndef VMS
   free (argv[0]);
@@ -1519,5 +1543,9 @@
   child->file->update_status = 2;
   notice_finished_file (child->file);
+#ifdef KMK /* fix leak */
+  goto cleanup_argv;
+#else
   return;
+#endif
 }
 
Index: /trunk/src/kmk/kmkbuiltin.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin.c	(revision 1289)
+++ /trunk/src/kmk/kmkbuiltin.c	(revision 1290)
@@ -29,4 +29,5 @@
 #include <stdio.h>
 #include <ctype.h>
+#include <assert.h>
 #ifdef _MSC_VER
 # include <io.h>
@@ -39,5 +40,5 @@
 #endif
 
-int kmk_builtin_command(const char *pszCmd)
+int kmk_builtin_command(const char *pszCmd, char ***ppapszArgvToSpawn, pid_t *pPidSpawned)
 {
     int         argc;
@@ -151,5 +152,5 @@
      */
     if (!*pszCmd)
-        rc = kmk_builtin_command_parsed(argc, argv);
+        rc = kmk_builtin_command_parsed(argc, argv, ppapszArgvToSpawn, pPidSpawned);
     else
         rc = 1;
@@ -163,5 +164,5 @@
 
 
-int kmk_builtin_command_parsed(int argc, char **argv)
+int kmk_builtin_command_parsed(int argc, char **argv, char ***ppapszArgvToSpawn, pid_t *pPidSpawned)
 {
     const char *pszCmd = argv[0];
@@ -194,17 +195,21 @@
     else if (!strcmp(pszCmd, "kDepIDB"))
         rc = kmk_builtin_kDepIDB(argc, argv, environ);
-    else if (!strcmp(pszCmd, "ln"))
-        rc = kmk_builtin_ln(argc, argv, environ);
     else if (!strcmp(pszCmd, "mkdir"))
         rc = kmk_builtin_mkdir(argc, argv, environ);
     else if (!strcmp(pszCmd, "mv"))
         rc = kmk_builtin_mv(argc, argv, environ);
+    /*else if (!strcmp(pszCmd, "redirect"))
+        rc = kmk_builtin_redirect(argc, argv, environ, pPidSpawned);*/
     else if (!strcmp(pszCmd, "rm"))
         rc = kmk_builtin_rm(argc, argv, environ);
     else if (!strcmp(pszCmd, "rmdir"))
         rc = kmk_builtin_rmdir(argc, argv, environ);
+    /*else if (!strcmp(pszCmd, "test"))
+        rc = kmk_builtin_test(argc, argv, environ, ppapszArgvToSpawn);*/
     /* rarely used commands: */
     else if (!strcmp(pszCmd, "cp"))
         rc = kmk_builtin_cp(argc, argv, environ);
+    else if (!strcmp(pszCmd, "ln"))
+        rc = kmk_builtin_ln(argc, argv, environ);
     else if (!strcmp(pszCmd, "md5sum"))
         rc = kmk_builtin_md5sum(argc, argv, environ);
@@ -218,6 +223,37 @@
         return 1;
     }
+
+    /*
+     * Cleanup.
+     */
     g_progname = "kmk";                 /* paranoia, make sure it's not pointing at a freed argv[0]. */
     umask(iumask);
+
+
+    /*
+     * If we've executed a conditional test or something that wishes to execute
+     * some child process, check if the child is a kmk_builtin thing. We recurse
+     * here, both because I'm lazy and because it's easier to debug a problem then
+     * (the call stack shows what's been going on).
+     */
+    if (    !rc
+        &&  *ppapszArgvToSpawn
+        &&  !strncmp(**ppapszArgvToSpawn, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
+    {
+        char **argv_new = *ppapszArgvToSpawn;
+        int argc_new = 1;
+        while (argv_new[argc_new])
+          argc_new++;
+
+        assert(argv_new[0] != argv[0]);
+        assert(!*pPidSpawned);
+
+        *ppapszArgvToSpawn = NULL;
+        rc = kmk_builtin_command_parsed (argc_new, argv_new, ppapszArgvToSpawn, pPidSpawned);
+
+        free (argv_new[0]);
+        free (argv_new);
+    }
+
     return rc;
 }
Index: /trunk/src/kmk/kmkbuiltin.h
===================================================================
--- /trunk/src/kmk/kmkbuiltin.h	(revision 1289)
+++ /trunk/src/kmk/kmkbuiltin.h	(revision 1290)
@@ -25,6 +25,14 @@
  */
 
-int kmk_builtin_command(const char *pszCmd);
-int kmk_builtin_command_parsed(int argc, char **argv);
+#ifdef _MSC_VER
+# ifndef pid_t /* see config.h.win */
+#  define pid_t int
+# endif
+#else
+# include <sys/types.h>
+#endif
+
+int kmk_builtin_command(const char *pszCmd, char ***ppapszArgvToSpawn, pid_t *pPidSpawned);
+int kmk_builtin_command_parsed(int argc, char **argv, char ***ppapszArgvToSpawn, pid_t *pPidSpawned);
 
 extern int kmk_builtin_append(int argc, char **argv, char **envp);
