diff --git a/src/array.c b/src/array.c
index fe1fe0db5dace84bebbeaff7caefca15b04e9e85..b12e24b1a12efe96e6bb56897e229daa6c4de495 100644
--- a/src/array.c
+++ b/src/array.c
@@ -1535,7 +1535,8 @@ void debug_dump_type_field(TYPE_FIELD t)
 
 void debug_dump_array(struct array *a)
 {
-  fprintf(stderr,"Refs=%d, next=%p, prev=%p, size=%d, malloced_size=%d\n",
+  fprintf(stderr,"Locatoin=%p Refs=%d, next=%p, prev=%p, size=%d, malloced_size=%d\n",
+	  a,
 	  a->refs,
 	  a->next,
 	  a->prev,
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 13be00f1c5feb93a0955c1d4a320e6e6427aa320..ac872ecf5552543e929b6a464a14b7a437cfee06 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.64 1998/01/29 18:10:53 grubba Exp $");
+RCSID("$Id: builtin_functions.c,v 1.65 1998/01/30 06:19:50 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -617,9 +617,8 @@ void f_throw(INT32 args)
 {
   if(args < 1)
     error("Too few arguments to throw()\n");
-  pop_n_elems(args-1);
-  throw_value=sp[-1];
-  sp--;
+  assign_svalue(&throw_value,sp-args);
+  pop_n_elems(args);
   pike_throw();
 }
 
diff --git a/src/error.c b/src/error.c
index c21871d1b9fb9ca9628596ffefce0f9093c4f294..3acf9da06ccae64e2c0eee18aaba34aa4457e680 100644
--- a/src/error.c
+++ b/src/error.c
@@ -109,8 +109,7 @@ void va_error(char *fmt, va_list args) ATTRIBUTE((noreturn))
   f_backtrace(0);
   f_aggregate(2);
   free_svalue(& throw_value);
-  sp--;
-  throw_value = *sp;
+  throw_value = *--sp;
   throw_severity=THROW_ERROR;
 
   in_error=0;
diff --git a/src/modules/Oracle/oracle.c b/src/modules/Oracle/oracle.c
index b8c18df4e1f0a729564b613c193a1c1ecabd2c45..e367447d96d40a8425833be6e0397db5ecfa99b7 100644
--- a/src/modules/Oracle/oracle.c
+++ b/src/modules/Oracle/oracle.c
@@ -1,5 +1,5 @@
 /*
- * $Id: oracle.c,v 1.6 1997/12/07 21:50:48 grubba Exp $
+ * $Id: oracle.c,v 1.7 1998/01/30 06:20:21 hubbe Exp $
  *
  * Pike interface to Oracle databases.
  *
@@ -34,7 +34,7 @@
 
 #endif
 
-RCSID("$Id: oracle.c,v 1.6 1997/12/07 21:50:48 grubba Exp $");
+RCSID("$Id: oracle.c,v 1.7 1998/01/30 06:20:21 hubbe Exp $");
 
 #ifdef HAVE_ORACLE
 
@@ -585,6 +585,11 @@ void pike_module_init(void)
 void pike_module_exit(void)
 {
 #ifdef HAVE_ORACLE
+  if(oracle_program)
+  {
+    free_program(oracle_program);
+    oracle_program=0;
+  }
   if (oracle_result_program) {
     free_program(oracle_result_program);
     oracle_program = NULL;
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 585ef792101ba14890dfab4fcaf8168519747f95..9f73cd8cdbb5dc59b131ee04eb88fb4bd853cce8 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -6,7 +6,7 @@
 #define READ_BUFFER 8192
 
 #include "global.h"
-RCSID("$Id: file.c,v 1.71 1998/01/28 01:36:30 hubbe Exp $");
+RCSID("$Id: file.c,v 1.72 1998/01/30 06:20:54 hubbe Exp $");
 #include "fdlib.h"
 #include "interpret.h"
 #include "svalue.h"
@@ -1170,7 +1170,7 @@ static void file_pipe(INT32 args)
   int type=fd_CAN_NONBLOCK | fd_BIDIRECTIONAL;
 
   check_all_args("file->pipe",args, BIT_INT | BIT_VOID, 0);
-  if(args) type = sp[-args].u.integer;;
+  if(args) type = sp[-args].u.integer;
 
   do_close(FD,FILE_READ | FILE_WRITE);
   FD=-1;
@@ -1602,6 +1602,97 @@ static void file_create(INT32 args)
   }
 }
 
+#ifdef _REENTRANT
+
+struct new_thread_data
+{
+  struct object *from;
+  struct object *to;
+  INT32 fromfd, tofd;
+};
+
+static void *proxy_thread(void * data)
+{
+  char buffer[READ_BUFFER];
+  struct new_thread_data *p=(struct new_thread_data *)data;
+
+  while(1)
+  {
+    long len, w;
+    len=fd_read(p->fromfd, buffer, READ_BUFFER);
+    if(len<0)
+    {
+      if(errno==EINTR) continue;
+      break;
+    }
+
+    w=0;
+    while(w<len)
+    {
+      long wl=fd_write(p->tofd, buffer+w, len-w);
+      if(wl<0) if(errno==EINTR) continue;
+      w+=wl;
+    }
+  }
+
+  mt_lock(&interpreter_lock);
+  free_object(p->from);
+  free_object(p->to);
+  mt_unlock(&interpreter_lock);
+  free((char *)p);
+  return 0;
+}
+
+void file_proxy(INT32 args)
+{
+  struct file_struct *f;
+  struct new_thread_data *p;
+  THREAD_T id;
+  check_all_args("Stdio.File->proxy",args, T_OBJECT,0);
+  f=(struct file_struct *)get_storage(sp[-args].u.object, file_program);
+  if(!f)
+    error("Bad argument 1 to Stdio.File->proxy, not a Stdio.File object.\n");
+
+  p=ALLOC_STRUCT(new_thread_data);
+  p->to=fp->current_object;
+  p->tofd=FD;
+  p->from=sp[-args].u.object;
+  p->fromfd=f->fd;
+  p->to->refs++;
+  p->from->refs++;
+  if(th_create_small(&id,new_thread_func,p))
+  {
+    free((char *)p);
+    error("Failed to create thread.\n");
+  }
+  th_destroy(& id);
+  pop_n_elems(args);
+  push_int(0);
+}
+
+void create_proxy_pipe(struct object *o, int for_reading)
+{
+  struct object *n,*n2;
+  push_object(n=clone_object(file_program,0));
+  push_int(fd_INTERPROCESSABLE);
+  apply(n,"pipe",1);
+  n2=sp[-1].u.object;
+  if(for_reading)
+  {
+    ref_push_object(o);
+    apply(n2,"proxy",1);
+    pop_n_elems(2);
+  }else{
+    /* Swap */
+    sp[-2].u.object=n2;
+    sp[-1].u.object=n;
+    apply(o,"proxy",1);
+    pop_stack();
+  }
+}
+
+#endif
+
 void pike_module_exit(void)
 {
   if(file_program)
@@ -1717,6 +1808,9 @@ void pike_module_init(void)
   add_function("create",file_create,"function(void|string,void|string:void)",0);
   add_function("`<<",file_lsh,"function(mixed:object)",0);
 
+#ifdef _REENTRANT
+  add_function("proxy",file_proxy,"function(object:void)",0);
+#endif
   set_init_callback(init_file_struct);
   set_exit_callback(exit_file_struct);
   set_gc_mark_callback(gc_mark_file_struct);
diff --git a/src/modules/system/system.c b/src/modules/system/system.c
index e449f02a87a29e43afd69a491d5c2d64f67358ca..6081b3f5d1d19c59d12529e11a268dc4b9a2963d 100644
--- a/src/modules/system/system.c
+++ b/src/modules/system/system.c
@@ -1,5 +1,5 @@
 /*
- * $Id: system.c,v 1.39 1998/01/25 08:28:45 hubbe Exp $
+ * $Id: system.c,v 1.40 1998/01/30 06:21:37 hubbe Exp $
  *
  * System-call module for Pike
  *
@@ -14,7 +14,7 @@
 #include "system.h"
 
 #include "global.h"
-RCSID("$Id: system.c,v 1.39 1998/01/25 08:28:45 hubbe Exp $");
+RCSID("$Id: system.c,v 1.40 1998/01/30 06:21:37 hubbe Exp $");
 #ifdef HAVE_WINSOCK2_H
 #include <winsock2.h>
 #endif
@@ -873,7 +873,6 @@ static void f_cp(INT32 args)
 }
 #endif
 
-
 /*
  * Module linkage
  */
diff --git a/src/signal_handler.c b/src/signal_handler.c
index 3fa42e4bfaa06256cb6f7c2fd5c6a868fdc63e35..cd7a10021d5c2ea4c7aaa379fecb6b66e05ee660 100644
--- a/src/signal_handler.c
+++ b/src/signal_handler.c
@@ -429,7 +429,10 @@ static void report_child(int pid,
 					       pid_status_program)))
 	{
 	  p->state = PROCESS_EXITED;
-	  p->result = WEXITSTATUS(status);
+	  if(WIFEXITED(p->result))
+	    p->result = WEXITSTATUS(status);
+	  else
+	    p->result=-1;
 	}
       }
       map_delete(pid_mapping, &key);
@@ -538,9 +541,12 @@ static TCHAR *convert_string(char *str, int len)
   return ret;
 }
 
-static HANDLE get_inheritable_handle(struct mapping *optional, char *name)
+static HANDLE get_inheritable_handle(struct mapping *optional,
+				     char *name,
+				     int for_reading)
 {
   HANDLE ret=INVALID_HANDLE_VALUE;
+  struct svalue *save_stack=sp;
   struct svalue *tmp;
   if((tmp=simple_mapping_string_lookup(optional, name)))
   {
@@ -549,6 +555,15 @@ static HANDLE get_inheritable_handle(struct mapping *optional, char *name)
       apply(tmp->u.object,"query_fd",0);
       if(sp[-1].type == T_INT)
       {
+	if(!(fd_query_properties(sp[-1].u.integer) & fd_INTERPROCESSABLE))
+	{
+	  void create_proxy_pipe(struct object *o, int for_reading);
+	  
+	  create_proxy_pipe(tmp->u.object, for_reading);
+	    apply(sp[-1].u.object, "query_fd", 0);
+	}
+	
+	  
 	if(!DuplicateHandle(GetCurrentProcess(),
 			    (HANDLE)da_handle[sp[-1].u.integer],
 			    GetCurrentProcess(),
@@ -559,9 +574,9 @@ static HANDLE get_inheritable_handle(struct mapping *optional, char *name)
 	  /* This could cause handle-leaks */
 	  error("Failed to duplicate handle %d.\n",GetLastError());
       }
-      pop_stack();
     }
   }
+  pop_n_elems(sp-save_stack);
   return ret;
 }
 #endif
@@ -654,13 +669,13 @@ void f_create_process(INT32 args)
 	if(tmp->type == T_STRING)
 	  dir=convert_string(tmp->u.string->str, tmp->u.string->len);
 
-      t1=get_inheritable_handle(optional, "stdin");
+      t1=get_inheritable_handle(optional, "stdin",0);
       if(t1!=INVALID_HANDLE_VALUE) info.hStdInput=t1;
 
-      t2=get_inheritable_handle(optional, "stdout");
+      t2=get_inheritable_handle(optional, "stdout",1);
       if(t2!=INVALID_HANDLE_VALUE) info.hStdOutput=t2;
 
-      t3=get_inheritable_handle(optional, "stderr");
+      t3=get_inheritable_handle(optional, "stderr",1);
       if(t3!=INVALID_HANDLE_VALUE) info.hStdError=t3;
 
 	if((tmp=simple_mapping_string_lookup(optional, "env")))
diff --git a/src/threads.c b/src/threads.c
index 27bb72474629d3d46c7891ab0fb3f4811a4a43b3..73e292ca0378f5730210d90899597b47d44cd624 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.54 1998/01/26 20:00:01 hubbe Exp $");
+RCSID("$Id: threads.c,v 1.55 1998/01/30 06:19:51 hubbe Exp $");
 
 int num_threads = 1;
 int threads_disabled = 0;
@@ -143,6 +143,7 @@ struct program *mutex_key = 0;
 struct program *thread_id_prog = 0;
 #ifdef POSIX_THREADS
 pthread_attr_t pattr;
+pthread_attr_t small_pattr;
 #endif
 
 struct thread_starter
@@ -607,6 +608,13 @@ void th_init(void)
   pthread_attr_setstacksize(&pattr, 2 * 1024 * 1204);
 #endif
   pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
+
+  pthread_attr_init(&small_pattr);
+#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
+  pthread_attr_setstacksize(&small_pattr, 32768);
+#endif
+  pthread_attr_setdetachstate(&small_pattr, PTHREAD_CREATE_DETACHED);
+
 #endif
 
   add_efun("thread_create",f_thread_create,"function(mixed ...:object)",
diff --git a/src/threads.h b/src/threads.h
index 2379a3088402db7c4590b550f86f25ab1dcc8a5e..45c9acd14331082d4e5660907e15945aff83f5fe 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -70,8 +70,11 @@ extern struct object *thread_id;
 #else
 #define th_yield()
 #endif /* HAVE_PTHREAD_YIELD */
+extern pthread_attr_t pattr;
+extern pthread_attr_t small_pattr;
 
 #define th_create(ID,fun,arg) pthread_create(ID,&pattr,fun,arg)
+#define th_create_small(ID,fun,arg) pthread_create(ID,&small_pattr,fun,arg)
 #define th_exit(foo) pthread_exit(foo)
 #define th_self() pthread_self()
 
@@ -110,6 +113,7 @@ extern struct object *thread_id;
 #define th_setconcurrency(X) thr_setconcurrency(X)
 
 #define th_create(ID,fun,arg) thr_create(NULL,0,fun,arg,THR_DAEMON,ID)
+#define th_create_small(ID,fun,arg) thr_create(NULL,32768,fun,arg,THR_DAEMON,ID)
 #define th_exit(foo) thr_exit(foo)
 #define th_self() thr_self()
 #define th_yield() thr_yield()
@@ -141,6 +145,7 @@ extern struct object *thread_id;
 
 #define PIKE_SPROC_FLAGS	(PR_SADDR|PR_SFDS|PR_SDIR|PS_SETEXITSIG)
 #define th_create(ID, fun, arg)	(((*(ID)) = sproc(fun, PIKE_SPROC_FLAGS, arg)) == -1)
+#define th_create_small(ID, fun, arg)	(((*(ID)) = sproc(fun, PIKE_SPROC_FLAGS, arg)) == -1)
 #define th_exit(X)	exit(X)
 #define th_self()	getpid()
 #define th_yield()	sginap(0)
@@ -159,6 +164,7 @@ extern struct object *thread_id;
 #define THREAD_T HANDLE
 #define th_setconcurrency(X)
 #define th_create(ID,fun,arg)  (!(*(ID)=_beginthread(fun, 2*1024*1024, arg)))
+#define th_create_small(ID,fun,arg)  (!(*(ID)=_beginthread(fun, 32768, arg)))
 #define th_exit(foo) _endthread(foo)
 #define th_self() GetCurrentThread()
 #define th_destroy(X)