diff --git a/src/signal_handler.c b/src/signal_handler.c
index c6eb6b79821a21b9eecf2fadabd7089c3f901282..60e4ea1866b4a927fc0cffd5a0aa44f5259a3d3e 100644
--- a/src/signal_handler.c
+++ b/src/signal_handler.c
@@ -3,6 +3,7 @@
 ||| Pike is distributed as GPL (General Public License)
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
+/**/
 #include "global.h"
 #include "fdlib.h"
 #include "fd_control.h"
@@ -22,7 +23,7 @@
 #include "builtin_functions.h"
 #include <signal.h>
 
-RCSID("$Id: signal_handler.c,v 1.90 1998/11/23 00:06:15 marcus Exp $");
+RCSID("$Id: signal_handler.c,v 1.91 1998/11/29 21:28:17 grubba Exp $");
 
 #ifdef HAVE_PASSWD_H
 # include <passwd.h>
@@ -809,6 +810,37 @@ static void free_perishables(struct perishables *storage)
 
 #endif
 
+#if !defined(__NT__) && !defined(__amigaos__)
+
+extern int pike_make_pipe(int *);
+
+/*
+ * Errors that can be generated by the child process
+ */
+
+#define PROCE_CHDIR		1
+#define PROCE_DUP2		2
+#define PROCE_SETGID		3
+#define PROCE_SETGROUPS		4
+#define PROCE_GETPWUID		5
+#define PROCE_INITGROUPS	6
+#define PROCE_SETUID		7
+#define PROCE_EXEC		8
+
+#define PROCERROR(err, id)	do { int _l, _i; \
+    buf[0] = err; buf[1] = errno; buf[2] = id; \
+    for(_i = 0; _i < 3; _i += _l) { \
+      while (((_l = write(control_pipe[1], buf + _i, 3 - _i)) < 0) && \
+             (errno == EINTR)) \
+        ; \
+      if (_l < 0) break; \
+    } \
+    exit(99); \
+  } while(0)
+
+#endif /* !__NT__ && !__amigaos__ */
+
+
 
 /*
  * create_process(string *arguments, mapping optional_data);
@@ -1101,6 +1133,8 @@ void f_create_process(INT32 args)
     int gid_request=0;
     int keep_signals = 0;
     pid_t pid;
+    int control_pipe[2];	/* Used for communication with the child. */
+    char buf[4];
 
     storage.env=0;
     storage.argv=0;
@@ -1365,6 +1399,10 @@ void f_create_process(INT32 args)
     fprintf(stderr, "%s:%d: init_threads_disable()...\n", __FILE__, __LINE__);
 #endif /* PROC_DEBUG */
 
+    if (pike_make_pipe(control_pipe) < 0) {
+      error("Failed to create child communication pipe.\n");
+    }
+
 #if 1
     init_threads_disable(NULL);
     storage.disabled = 1;
@@ -1383,6 +1421,9 @@ void f_create_process(INT32 args)
     UNSET_ONERROR(err);
 
     if(pid==-1) {
+      close(control_pipe[0]);
+      close(control_pipe[1]);
+
       free_perishables(&storage);
 
 #ifdef PROC_DEBUG
@@ -1393,6 +1434,9 @@ void f_create_process(INT32 args)
       error("Failed to start process.\n"
 	    "errno:%d\n", errno);
     } else if(pid) {
+      /* Close our childs end of the pipe. */
+      close(control_pipe[1]);
+
       free_perishables(&storage);
 
       pop_n_elems(sp - stack_save);
@@ -1402,6 +1446,7 @@ void f_create_process(INT32 args)
 	      __FILE__, __LINE__, (int)pid);
 #endif /* PROC_DEBUG */
 
+      /* FIXME: Can anything of the following throw an error? */
       if(!signal_evaluator_callback)
       {
 	signal_evaluator_callback=add_to_callback(&evaluator_callbacks,
@@ -1414,7 +1459,24 @@ void f_create_process(INT32 args)
       push_int(pid);
       mapping_insert(pid_mapping,sp-1, sp-2);
       pop_n_elems(2);
-      push_int(0);
+
+      /* Wake up the child. */
+      buf[0] = 0;
+      while (((e = write(control_pipe[0], buf, 1)) < 0) && (errno == EINTR))
+	;
+
+      /* Wait for exec. */
+      while(((e = read(control_pipe[0], buf, 3)) < 0) && (errno == EINTR))
+	;
+      close(control_pipe[0]);
+      if (!e) {
+	/* OK! */
+	push_int(0);
+      } else {
+	/* Something went wrong. */
+	error("Process.create_process(): Child failed: %d, %d, %d!\n",
+	      buf[0], buf[1], buf[2]);
+      }
     }else{
       ONERROR oe;
 
@@ -1424,12 +1486,24 @@ void f_create_process(INT32 args)
       extern void my_set_close_on_exec(int,int);
       extern void do_set_close_on_exec(void);
 
+      /* Close our parents end of the pipe. */
+      close(control_pipe[0]);
+      /* Ensure that the pipe will be closed when the child starts. */
+      set_close_on_exec(control_pipe[1], 1);
+
       SET_ONERROR(oe, exit_on_error, "Error in create_process() child.");
 
 #ifdef _REENTRANT
       /* forked copy. there is now only one thread running, this one. */
       num_threads=1;
 #endif
+
+      /* Wait for parent to get ready... */
+      while ((( e = read(control_pipe[1], buf, 1)) < 0) && (errno == EINTR))
+	;
+
+      /* FIXME: What to do if e < 0 ? */
+
       call_callback(&fork_child_callback, 0);
 
       for(e=0;e<cmd->size;e++) storage.argv[e]=ITEM(cmd)[e].u.string->str;
@@ -1462,7 +1536,7 @@ void f_create_process(INT32 args)
 		      __FILE__, __LINE__, tmp->u.string->str, errno);
 #endif /* PROC_DEBUG */
 
-	      exit(69);
+	      PROCERROR(PROCE_CHDIR, 0);
 	    }
 
 #ifdef HAVE_NICE
@@ -1499,7 +1573,7 @@ void f_create_process(INT32 args)
 			  __FILE__, __LINE__, f, fd, errno);
 #endif /* PROC_DEBUG */
 
-		  exit(67);
+		  PROCERROR(PROCE_DUP2, f);
 		}
 	      }
 	    }
@@ -1544,7 +1618,7 @@ void f_create_process(INT32 args)
 		    __FILE__, __LINE__, (int)wanted_gid, errno);
 #endif /* PROC_DEBUG */
 
-	    exit(77);
+	    PROCERROR(PROCE_SETGID, (int)wanted_gid);
 	  }
       }
 #endif
@@ -1560,7 +1634,8 @@ void f_create_process(INT32 args)
 #ifdef PROC_DEBUG
 	  fprintf(stderr, "setgroups() failed.\n");
 #endif /* PROC_DEBUG */
-	  exit(77);
+
+	  PROCERROR(PROCE_SETGROUPS,0);
 	}
       }
 #endif
@@ -1580,7 +1655,8 @@ void f_create_process(INT32 args)
 #ifdef PROC_DEBUG
 	    fprintf(stderr, "getpwuid() failed.\n");
 #endif /* PROC_DEBUG */
-	    exit(77);
+
+	    PROCERROR(PROCE_GETPWUID, wanted_uid);
 	  }
 	  initgroupgid=pw->pw_gid;
 /*	  printf("uid=%d euid=%d initgroups(%s,%d)\n",getuid(),geteuid(),pw->pw_name, initgroupgid); */
@@ -1604,7 +1680,8 @@ void f_create_process(INT32 args)
 #ifdef PROC_DEBUG
 		fprintf(stderr, "initgroups() failed.\n");
 #endif /* PROC_DEBUG */
-		exit(77);
+
+		PROCERROR(PROCE_INITGROUPS, 0);
 	      }
 	    }
 	}
@@ -1613,7 +1690,8 @@ void f_create_process(INT32 args)
 	if(setuid(wanted_uid))
 	{
 	  perror("setuid");
-	  exit(77);
+
+	  PROCERROR(PROCE_SETUID, (int)wanted_uid);
 	}
       }
 #endif /* SETUID */
@@ -1642,7 +1720,11 @@ void f_create_process(INT32 args)
 	      "errno = %d\n",
 	      storage.argv[0], errno);
 #endif /* PROC_DEBUG */
-      exit(69);
+#ifndef HAVE_BROKEN_F_SETFD
+      /* No way to tell about this on broken OS's :-( */
+      PROCERROR(PROCE_EXEC, 0);
+#endif /* HAVE_BROKEN_F_SETFD */
+      exit(99);
     }
   }
 #endif /* __amigaos__ */