From 5a7ab60e25b94765c6a6062a12a0781c30f0f364 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 31 Jan 1998 18:08:25 -0800
Subject: [PATCH] Many patches for NT...

Rev: NT/tools/cp:1.3
Rev: NT/tools/install:1.3
Rev: NT/tools/lib:1.12
Rev: NT/tools/mkdir:1.3
Rev: NT/tools/rntcc:1.10
Rev: NT/tools/sprsh:1.2
Rev: NT/tools/sprshd:1.6
Rev: src/builtin_functions.c:1.66
Rev: src/error.c:1.12
Rev: src/error.h:1.12
Rev: src/fdlib.c:1.11
Rev: src/fdlib.h:1.8
Rev: src/interpret.c:1.65
Rev: src/modules/files/file.c:1.73
Rev: src/modules/files/socket.c:1.28
Rev: src/pike_memory.c:1.12
Rev: src/program.h:1.31
Rev: src/signal_handler.c:1.28
---
 NT/tools/cp                |  29 +--
 NT/tools/install           |  37 ++-
 NT/tools/lib               |   1 +
 NT/tools/mkdir             |  23 +-
 NT/tools/rntcc             | 449 +++++++++++++++++++------------------
 NT/tools/sprsh             |  37 +--
 NT/tools/sprshd            |  31 ++-
 src/builtin_functions.c    |  22 +-
 src/error.c                |   4 +-
 src/error.h                |   5 +-
 src/fdlib.c                | 126 +++++++++--
 src/fdlib.h                |   5 +-
 src/interpret.c            |  20 +-
 src/modules/files/file.c   |  23 +-
 src/modules/files/socket.c |   5 +-
 src/pike_memory.c          |   1 +
 src/program.h              |   2 +-
 src/signal_handler.c       |  12 +-
 18 files changed, 481 insertions(+), 351 deletions(-)

diff --git a/NT/tools/cp b/NT/tools/cp
index ff2ec26424..554acd66db 100755
--- a/NT/tools/cp
+++ b/NT/tools/cp
@@ -1,14 +1,15 @@
-#!/bin/sh
-
-dest=`eval echo '$'$#`
-
-case "x$dest" in
-  x[a-zA-Z]:*)
-    . $NTTOOLS
-    do_cmd copy `fixpath $*`
-    exit $?
-  ;;
-esac
-
-exec /bin/cp "$@"
-
+#!/usr/local/bin/pike
+
+inherit "lib.pike";
+
+int main(int argc, string *argv)
+{
+  if(sscanf(argv[-1],"%*[a-zA-Z]:%*s"))
+  {
+    argv[0]="copy";
+    exit(do_cmd( Array.map(argv,fixpath)));
+  }else{
+    exece("/bin/cp",argv[1..]);
+    exit(69);
+  }
+}
diff --git a/NT/tools/install b/NT/tools/install
index cef825764e..c1a4d7f009 100755
--- a/NT/tools/install
+++ b/NT/tools/install
@@ -1,24 +1,17 @@
-#!/bin/sh
+#!/usr/local/bin/pike
 
-dest=`eval echo '$'$#`
-
-
-case "x$dest" in
-  x[a-zA-Z]:*)
-    . $NTTOOLS
-
-   if test "x$1" = "x-c" ; then
-     shift
-   fi
-
-   if test -f "$1.exe" ; then
-     set -- "$1.exe" "$2"
-   fi
-    
-    do_cmd copy `fixpath $*`
-    exit $?
-  ;;
-esac
-
-exec /usr/bin/install "$@"
+inherit "lib.pike";
 
+int main(int argc, string *argv)
+{
+  if(sscanf(argv[-1],"%*[a-zA-Z]:%*s"))
+  {
+    argv[0]="copy";
+    if(argv[1]=="-c") argv=argv[..0]+argv[2..];
+    if(file_stat(argv[1]+".exe")) argv[1]+=".exe";
+    exit(do_cmd( Array.map(argv,fixpath)));
+  }else{
+    exece("/usr/bin/install",argv[1..]);
+    exit(69);
+  }
+}
diff --git a/NT/tools/lib b/NT/tools/lib
index 005d50ef2e..dbd3a51005 100644
--- a/NT/tools/lib
+++ b/NT/tools/lib
@@ -48,3 +48,4 @@ do_cmd() {
   echo "DOING $*" >&2
   silent_do_cmd "$@"
 }
+
diff --git a/NT/tools/mkdir b/NT/tools/mkdir
index 01df97c14d..8529a862db 100755
--- a/NT/tools/mkdir
+++ b/NT/tools/mkdir
@@ -1,12 +1,15 @@
-#!/bin/sh
+#!/usr/local/bin/pike
 
+inherit "lib.pike";
 
-case "x$1" in
-  x[a-zA-Z]:*)
-    . $NTTOOLS
-    do_cmd mkdir `fixpath $1`
-    exit 0
-  ;;
-esac
-
-exec /bin/mkdir "$@"
+int main(int argc, string *argv)
+{
+  if(sscanf(argv[-1],"%*[a-zA-Z]:%*s"))
+  {
+    argv[0]="mkdir";
+    exit(do_cmd( Array.map(argv,fixpath)));
+  }else{
+    exece("/bin/mkdir",argv[1..]);
+    exit(69);
+  }
+}
diff --git a/NT/tools/rntcc b/NT/tools/rntcc
index 0ae5085d57..4e7b7f0850 100755
--- a/NT/tools/rntcc
+++ b/NT/tools/rntcc
@@ -1,227 +1,230 @@
-#!/bin/sh
-
-. $NTTOOLS
-
-OPTS=""
-CFLAGS=""
-SOURCES=""
-OBJECTS=""
-OUTPUT=
-OPERATION=linking
-INCLUDE_PATH=
-LDOPTS="OPTION STACK=8m"
-LIBRARIES=""
-NTCC=wcc386
-
-DEBUG=no
-OPTIMIZE=no
-
-check_linker_error() {
-  ERROR=ok
-  sed -e 's/\\/\\\\/g' | while read line
-  do
-    echo "$line" >&2
-    case "x$line" in
-      *\ W1008:*)
-        ERROR=failed
-      ;;
-    esac
-  done
-
-  echo $ERROR
-  exit 0
+#!/usr/local/bin/pike
+
+inherit "lib.pike";
+
+int compile(string *sources,
+	     string dest,
+	     string errorfile,
+	     string *cflags)
+{
+  int ret;
+  if(!dest)
+  {
+    string tmp=reverse(sources[0]);
+    sscanf(tmp,"%*s.%s",tmp);
+    dest=reverse(tmp)+".o";
+  }
+
+  sources=Array.map(sources,fixpath);
+  if(lower_case(sources[0][strlen(sources[0])-3..])==".s")
+  {
+    ret=do_cmd(({ "wasm", "-fe"+errorfile, "-fo"+dest,})+ sources );
+  }else{
+    ret=do_cmd(({ "wcc386" }) + cflags + ({"-fr"+errorfile, "-fo"+dest}) + sources );
+  }
+  return ret;
 }
 
-while test "$#" != 0; do
-  case $1 in
-    -shared) ;;
-    -E)  OPERATION=preprocessing ;;
-    -c)  OPERATION=compiling  ;;
-    -g*)
-       CFLAGS="$CFLAGS -d2 "
-       LDOPTS="$LDOPTS DEBUG WATCOM ALL"
-       DEBUG=yes
-     ;;
-#    -O*) ;;
-    -O)
-      CFLAGS="$CFLAGS -ox"
-      OPTIMIZE=yes
-    ;;
-    -O2)
-      CFLAGS="$CFLAGS -otexan"
-      OPTIMIZE=yes
-    ;;
-    *.c | *.s | *.S) SOURCES="$SOURCES $1" ;;
-    *.o | *.a) OBJECTS="$OBJECTS $1" ;;
-     -o) OUTPUT="$2" ; shift ;;
-
-    -I*)
-       if test x$1 = x-I ; then
-         tmp="$2"
-         shift
-       else
-         tmp=`echo $1 | sed -e 's/^-I//g'`
-       fi
-
-       case $tmp in
-         /usr/include/* | /usr/local/include*)
-          ;;
-         *)
-           CFLAGS="$CFLAGS -i`fixpath $tmp`"
-         ;;
-       esac
-     ;;
-
-    -traditional-cpp | -lc | -lm) ;;
-
-    -R | -L) shift ;;
-    -R* | -L* | -Wl*)  ;;
-
-    -W)
-      CFLAGS="$CFLAGS -w2"
-    ;;
-
-    -Wall)
-      CFLAGS="$CFLAGS -wx"
-    ;;
-
-    -D*)
-      CFLAGS="$CFLAGS `echo $1 | sed -e 's/^-D/-d/g'`"
-    ;;
-
-    -U*)
-      CFLAGS="$CFLAGS `echo $1 | sed -e 's/^-U/-u/g'`"
-    ;;
-
-    -l*)
-      tmp=`echo $1 | sed -e 's/^-l//'`
-      LIBRARIES="$LIBRARIES LIBRARY $tmp"
-    ;;
-
-    -*)
-      echo "Unrecognized option $1"
-      exit 1
-    ;;
-
-    *)
-      SOURCES="$SOURCES $1"
-    ;;
-  esac
-  shift
-done
-
-#if [ x$DEBUG$OPTIMIZE = xyesyes ]; then
-#  echo Debug and optimization not supported at the same time
-#  exit 1
-#else
-#  :
-#fi
-
-rm $OUTPUT 2>/dev/null 1>/dev/null || :
-
-OLDIFS="$IFS"
-IFS=:
-set dummy $INCLUDE_PATH
-shift
-IFS="$OLDIFS"
-
-IPATH=.
-IPATHS=":.:"
-
-for a in "$@"
-do
-  case $IPATHS in
-    *:$a:*) ;;
-    *)
-     IPATH="$IPATH;`fixpath $a`"
-     IPATHS="$IPATHS:$a:"
-    ;;
-  esac
-done
-
-
-ERRORFILE=TMP$$.err
-rm $ERRORFILE 2>/dev/null 1>/dev/null || :
-
-CFLAGS="$CFLAGS -bm -zq -hw -fr$ERRORFILE"
-
-
-compile() {
-  if [ "x$2" != x ]; then
-    OFLAGS="$OFLAGS -fo$2"
-  else
-    OFLAGS="$OFLAGS -fo`echo $1 | sed -e 's/\.[^.]$//'`.o"
-  fi
-
-  case $1 in
-    *.s | *.S)
-      do_cmd wasm -fe$ERRORFILE $OFLAGS `fixpath $1`
-    ;;
-
-    *)
-     do_cmd $NTCC $CFLAGS $OFLAGS `fixpath $1`
-    ;;
-  esac
+string check_errorfile(string errorfile)
+{
+  object f=Stdio.File();
+  if(f->open(errorfile,"r"))
+  {
+    string data;
+    write(data=f->read());
+    f->close();
+    data=replace(data,"\r","");
+    rm(errorfile);
+    foreach(data/"\n", string line)
+      {
+	if(!strlen(line)) continue;
+	if(search(line,"Warning")!=-1) continue;
+	werror("Error in compilation detected. "+line+"\n");
+	exit(1);
+      }
+  }
 }
 
-case $OPERATION in
-  compiling)
-    compile $SOURCES $OUTPUT
-    TARGET=$OUTPUT
-  ;;
-
-  preprocessing)
-    silent_do_cmd $NTCC -p $CFLAGS `fixpath $SOURCES`
-  ;;
-
-  linking)
-    for a in `fixpath $SOURCES`
-    do
-      BASE=`echo $a | sed -e 's/\.[^.]$//'`
-      compile $a $BASE.obj
-      OBJECTS="$OBJECTS $BASE.obj"
-    done
-
-    LDFILE=TMP$$.lk
-    if [ "x$OUTPUT" = "x" ]; then
-      OUTPUT=a.out
-    fi
-    echo "name $OUTPUT.exe $LDOPTS FIL `fixpath $OBJECTS | sed -e 's/ /,/g'` $LIBRARIES" >$LDFILE
-    OK=`do_cmd wlink @$LDFILE | check_linker_error`
-    if [ x$OK != xok ]; then
-      exit 1
-    fi
-    TARGET=$OUTPUT.exe
-    if [ $CLEANUP = yes ]; then
-       if [ "x$LDFILE" != x ]; then
-         rm $LDFILE || :
-       fi
-    fi
-  ;;
-esac
-
-if [ -f $ERRORFILE ]; then
-  cat $ERRORFILE 1>&2
-  if grep -iv 'Warning' <$ERRORFILE >/dev/null 2>/dev/null; then
-    rm $ERRORFILE
-    exit 1
-  fi
-  rm $ERRORFILE
-fi
-
-if [ "x$TARGET" != x ]; then
-  if [ ! -f "$TARGET" ]; then
-    echo "RNTCC: output file not generated"
-    exit 1
-  fi
-fi
-
-if [ $OPERATION = linking ]; then
-  PWD=`pwd`
-  echo  >$OUTPUT "#!/bin/sh"
-  echo >>$OUTPUT ". \$NTTOOLS"
-  echo >>$OUTPUT "set -e"
-  echo >>$OUTPUT "silent_do_cmd '`fixpath $NTDRIVE$PWD/$TARGET`' \"\$@\""
-  echo >>$OUTPUT "exit \$?"
-  chmod +x $OUTPUT
-fi
+int main(int argc, string *argv)
+{
+  string target;
+  string operation="link";
+  string *cflags=({});
+  string *ldopts=({"OPTION","STACK=8m"});
+  string *libraries=({});
+  string *objects=({});
+  string *sources=({});
+  int debug,optimize;
+  string output;
+
+  mixed *opts=Getopt.find_all_options(argv, ({
+    ({"oper_pre",Getopt.NO_ARG, ({"-E"}) }),
+      ({"oper_comp",Getopt.NO_ARG, ({"-c"}) }),
+	({"debug",Getopt.MAY_HAVE_ARG, ({"-g"}) }),
+	  ({"optimize",Getopt.MAY_HAVE_ARG, ({"-O"}) }),
+	    ({"include",Getopt.HAS_ARG, ({"-I"}) }),
+	      ({"link",Getopt.HAS_ARG, ({"-l"}) }),
+		({"ignore",Getopt.MAY_HAVE_ARG, ({"-t","-s"}) }),
+		  ({"ignore",Getopt.HAS_ARG, ({"-R","-L"}) }),
+		    ({"warn",Getopt.MAY_HAVE_ARG, ({"-W"}) }),
+		      ({"define",Getopt.HAS_ARG, ({"-D"}) }),
+			({"undefine",Getopt.HAS_ARG, ({"-U"})}),
+			    ({"output",Getopt.HAS_ARG, ({"-o"}) })
+			      }));
+  foreach(opts, mixed *option)
+    {
+      switch(option[0])
+      {
+	case "oper_pre": operation="preprocess"; break;
+	case "oper_comp": operation="compile"; break;
+	case "debug":
+	cflags+=({"-d2"});
+	ldopts+=({"DEBUG","WATCOM","ALL"});
+	debug=1;
+	break;
+	
+	case "optimize":
+	  if(!option[1]) option[1]=1;
+	  switch(optimize=(int)option[1])
+	  {
+	    case 0: optimize=0; break;
+	    case 1: cflags+=({"-ox"}); break;
+	    case 2..: cflags+=({"-otexan"}); break;
+	  }
+	  break;
+	  
+	case "include":
+	  if(sscanf(option[1],"/usr/include/%*s") ||
+	     sscanf(option[1],"/usr/local/%*s"))
+	    break;
+	  
+	  cflags+=({"-i"+fixpath(option[1])});
+	  break;
+	  
+	case "link":
+	  if(option[1]=="m" || option[1]=="c") break;
+	  
+	  libraries+=({"LIBRARY",option[1]});
+	  break;
+	  
+	  case "warn":
+	  if(option[1] && sscanf(option[1],"l,%*s")) break;
+	  switch(option[1])
+	  {
+	    case "all": cflags+=({"-wx"}); break;
+	    default: cflags+=({"-w2"}); break;
+	  }
+	  break;
+	  
+	case "define": cflags+=({"-d"+option[1]}); break;
+	case "undefine": cflags+=({"-u"+option[1]}); break;
+	case "output":
+	  output=option[1];
+	  break;
+      }
+    }
+
+  argv=Getopt.get_args(argv);
+  foreach(argv[1..], string tmp)
+  {
+    string ext;
+    if(tmp[0]=='-')
+    {
+      werror("Unrecognized option "+tmp+".\n");
+      exit(1);
+    }
+    sscanf(reverse(tmp),"%s.",ext);
+    switch(ext)
+    {
+      case "o":
+      case "a":
+	objects+=({tmp});
+	break;
+	
+      default:
+	sources+=({tmp});
+    }
+  }
+
+  if(output) rm(output);
+
+  string errorfile="TMP"+getpid()+".err";
+  rm(errorfile);
+
+  cflags+=({"-bm","-zq","-hw"});
+
+  switch(operation)
+  {
+    default:
+    werror("Unknown operation "+operation+".\n");
+    exit(1);
+
+    case "compile":
+      compile(sources,output,errorfile,cflags);
+      break;
+
+    case "preprocess":
+    {
+      int ret=silent_do_cmd( ({"wcc386","-p","-fr"+errorfile}) + cflags + Array.map(sources, fixpath));
+      break;
+    }
+
+    case "link":
+      foreach(sources, string source)
+	{
+	  string obj=reverse(source);
+	  sscanf(obj,"%*s.%s",obj);
+	  obj=reverse(obj)+".obj";
+
+	  compile( ({source}), obj, errorfile, cflags);
+	  objects+=({obj});
+	  check_errorfile(errorfile);
+	}
+
+      string ldfile="TMP"+getpid()+".lk";
+      if(!output) output="a.out";
+      rm(ldfile);
+      Stdio.write_file(ldfile,
+		 "NAME "+output+".exe "
+		    +ldopts*" "+" "+
+		    "FIL "+Array.map(objects,fixpath)*","+" "+
+		    libraries*" "+" ");
+
+      do_cmd( ({"wlink","@"+ldfile }), lambda(string data)
+      {
+	if(search(data," W1008:")!=-1)
+	  exit(1);
+      });
+
+      target=output+".exe";
+
+      if(getenv("CLEANUP")!="no")
+	rm(ldfile);
+  }
+
+  check_errorfile(errorfile);
+    
+  if(target)
+  {
+    if(!file_stat(target))
+    {
+      werror("RNTCC: output file not generated.\n");
+      exit(1);
+    }
+  }
+
+  if(operation == "link")
+  {
+    rm(output);
+    Stdio.write_file(output,
+		     "#!/usr/local/bin/pike\n"
+		     "inherit \""+find_lib_location()+"\";\n"
+		     "int main(int argc, string *argv) {\n"
+		     "argv[0]+=\".exe\";\n"
+		     "argv[0]=getenv(\"NTDRIVE\")+fixpath(combine_path(getcwd(),argv[0]));\n"
+		     "  exit(silent_do_cmd(argv));\n"
+		     "}\n");
+    chmod(output,0755);
+  }
+  exit(0);
+}
diff --git a/NT/tools/sprsh b/NT/tools/sprsh
index cb463c2ce0..dbb76418af 100755
--- a/NT/tools/sprsh
+++ b/NT/tools/sprsh
@@ -1,42 +1,9 @@
 #!/usr/local/bin/pike
 
-inherit Stdio.File;
-
-string handle_input()
-{
-  object stdin=Stdio.File("stdin");
-  while(string s=stdin->read(1000,1))
-    write(s);
-}
+inherit "lib.pike";
 
 
-#if !constant(strerror)
-#define strerror(X) X
-#endif
-
 int main(int argc, string *cmd)
 {
-  if(!connect(getenv("NTHOST"),(int)getenv("NTPORT")))
-  {
-    werror("Failed to connect "+strerror(errno())+".\n");
-    exit(1);
-  }
-
-  string tmp=getcwd();
-  string mnt=getenv("NTMOUNT");
-  if(mnt && strlen(mnt)) tmp=replace(tmp,mnt,"");
-  cmd[0]=getenv("NTDRIVE")+replace(tmp,"/","\\");
-  write(sprintf("%4c",sizeof(cmd)));
-  for(int e=0;e<sizeof(cmd);e++)
-    write(sprintf("%4c%s",strlen(cmd[e]),cmd[e]));
-
-  thread_create(handle_input);
-  while(1)
-  {
-    sscanf(read(4),"%4c",int len);
-    if(!len) break;
-    predef::write(read(len));
-  }
-  sscanf(read(4),"%4c",int code);
-  exit(code);
+  exit(silent_do_cmd(cmd[1..]));
 }
diff --git a/NT/tools/sprshd b/NT/tools/sprshd
index a3d17f9863..34710f8d52 100755
--- a/NT/tools/sprshd
+++ b/NT/tools/sprshd
@@ -22,7 +22,11 @@ void handle_incoming_connection(object(Stdio.File) io)
   }
 
   object pi=Stdio.File();
+#if constant(Stdio.PROP_IPC)
+  object p2=pi->pipe(Stdio.PROP_IPC);
+#else
   object p2=pi->pipe();
+#endif
   string dir=cmd[0];
   cmd=cmd[1..];
 
@@ -44,11 +48,31 @@ void handle_incoming_connection(object(Stdio.File) io)
       string to=combine_path(combine_path(getcwd(),dir),cmd[2]);
 
       if(mixed stat=file_stat(to))
+      {
 	if(stat[1]==-2)
-	  to=combine_path(to,cmd[1]);
+	{
+	  to=combine_path(to,basename(cmd[1]));
+	}
+      }
 
+
+      int ret=Stdio.cp(from,to);
+      if(!ret)
+      {
+	string x=sprintf("Errno is %d\n"
+			 "CWD=%s\n"
+			 "from=%s\n"
+			 "to=%s\n"
+			 "dir=%s (%s)\n",
+			 errno(),
+			 getcwd(),
+			 from,
+			 to,
+			 dir, combine_path(getcwd(),dir));
+	io->write(sprintf("%4c%s",strlen(x),x));
+      }
       io->write(sprintf("%4c",0));
-      io->write(sprintf("%4c",!Stdio.cp(from,to)));
+      io->write(sprintf("%4c",!ret));
       break;
     }
     case "getenv":
@@ -74,7 +98,9 @@ void handle_incoming_connection(object(Stdio.File) io)
       
       if(!err)
       {
+#if !constant(Process.PROP_IPC)
 	thread_create(monitor,p2,p);
+#endif
 	while(1)
 	{
 	  string s=pi->read(1000,1);
@@ -94,7 +120,6 @@ void handle_incoming_connection(object(Stdio.File) io)
   destruct(io);
 }
 
-
 int main(int argc, string *argv)
 {
   if(argc<2)
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index ac872ecf55..9cfd909b0f 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.65 1998/01/30 06:19:50 hubbe Exp $");
+RCSID("$Id: builtin_functions.c,v 1.66 1998/02/01 02:07:22 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -356,7 +356,8 @@ void f_add_constant(INT32 args)
 #define IS_ABS(X) (IS_SEP((X)[0])?1:0)
 #else   
 #define IS_SEP(X) ( (X) == '/' || (X) == '\\' )
-#define IS_ABS(X) (IS_SEP((X)[0])?1:(isalpha((X)[0]) && (X)[1]==':' && IS_SEP((X)[2]))?3:0)
+#define IS_ABS(X) ((isalpha((X)[0]) && (X)[1]==':' && IS_SEP((X)[2]))?3:0)
+#define IS_ROOT(X) (IS_SEP((X)[0])?1:0)
 #endif
 
 static char *combine_path(char *cwd,char *file)
@@ -369,13 +370,28 @@ static char *combine_path(char *cwd,char *file)
   my_cwd=0;
   
 
-  if(IS_ABS(file))
+  if(IS_ABS(file)
+#ifdef IS_ROOT
+     || ( IS_ROOT(file) && !IS_ABS(cwd))
+#endif
+    )
   {
     MEMCPY(cwdbuf,file,IS_ABS(file));
     cwdbuf[IS_ABS(file)]=0;
     cwd=cwdbuf;
     file+=IS_ABS(file);
   }
+
+#ifdef IS_ROOT
+  else if(IS_ROOT(file) && IS_ABS(cwd))
+  {
+    MEMCPY(cwdbuf,cwd,IS_ABS(cwd));
+    cwdbuf[IS_ABS(cwd)]=0;
+    cwd=cwdbuf;
+    file+=IS_ROOT(file);
+  }
+#endif
+
 #ifdef DEBUG    
   if(!cwd)
     fatal("No cwd in combine_path!\n");
diff --git a/src/error.c b/src/error.c
index 3acf9da06c..c2474a3185 100644
--- a/src/error.c
+++ b/src/error.c
@@ -29,7 +29,7 @@ JMP_BUF *init_recovery(JMP_BUF *r)
   return r;
 }
 
-void pike_throw() ATTRIBUTE((noreturn))
+void pike_throw(void) ATTRIBUTE((noreturn))
 {
   while(recoveries && throw_severity > recoveries->severity)
   {
@@ -143,7 +143,7 @@ void error(char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
 }
 
 
-void fatal(char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
+void debug_fatal(char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
 {
   va_list args;
   static int in_fatal = 0;
diff --git a/src/error.h b/src/error.h
index 2353b9697e..bd3f6e03a9 100644
--- a/src/error.h
+++ b/src/error.h
@@ -82,9 +82,12 @@ void va_error(char *fmt, va_list args) ATTRIBUTE((noreturn));
 void exit_on_error(void *msg);
 void fatal_on_error(void *msg);
 void error(char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2)));
-void fatal(char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)));
+void debug_fatal(char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)));
 /* Prototypes end here */
 
+#define fatal \
+ fprintf(stderr,"Fatal error at %s:%d\n",__FILE__,__LINE__),debug_fatal
+
 #endif
 
 
diff --git a/src/fdlib.c b/src/fdlib.c
index b677f4a9ff..fb6ecc888d 100644
--- a/src/fdlib.c
+++ b/src/fdlib.c
@@ -1,8 +1,15 @@
 #include "fdlib.h"
+#include "error.h"
 #include <math.h>
 
 #ifdef HAVE_WINSOCK2_H
 
+#ifdef _REENTRANT
+#include "threads.h"
+
+static MUTEX_T fd_mutex;
+#endif
+
 long da_handle[MAX_OPEN_FILEDESCRIPTORS];
 int fd_type[MAX_OPEN_FILEDESCRIPTORS];
 int first_free_handle;
@@ -48,6 +55,8 @@ void fd_init()
   int e;
   WSADATA wsadata;
   
+  mt_init(&fd_mutex);
+  mt_lock(&fd_mutex);
   if(WSAStartup(MAKEWORD(2,0), &wsadata) != 0)
   {
     fatal("No winsock available.\n");
@@ -65,11 +74,13 @@ void fd_init()
   for(e=3;e<MAX_OPEN_FILEDESCRIPTORS-1;e++)
     fd_type[e]=e+1;
   fd_type[e]=FD_NO_MORE_FREE;
+  mt_unlock(&fd_mutex);
 }
 
 void fd_exit()
 {
   WSACleanup();
+  mt_destroy(&fd_mutex);
 }
 
 FD fd_open(char *file, int open_mode, int create_mode)
@@ -134,12 +145,15 @@ FD fd_open(char *file, int open_mode, int create_mode)
     return -1;
   }
 
+  mt_lock(&fd_mutex);
 
   fd=first_free_handle;
   first_free_handle=fd_type[fd];
   fd_type[fd]=FD_FILE;
   da_handle[fd]=(long)x;
 
+  mt_unlock(&fd_mutex);
+
   FDDEBUG(fprintf(stderr,"Opened %s file as %d (%d)\n",file,fd,x));
 
   return fd;
@@ -149,22 +163,29 @@ FD fd_socket(int domain, int type, int proto)
 {
   FD fd;
   SOCKET s;
+  mt_lock(&fd_mutex);
   if(first_free_handle == FD_NO_MORE_FREE)
   {
+    mt_unlock(&fd_mutex);
     errno=EMFILE;
     return -1;
   }
+  mt_unlock(&fd_mutex);
+
   s=socket(domain, type, proto);
+
   if(s==INVALID_SOCKET)
   {
     errno=WSAGetLastError();
     return -1;
   }
   
+  mt_lock(&fd_mutex);
   fd=first_free_handle;
   first_free_handle=fd_type[fd];
   fd_type[fd]=FD_SOCKET;
   da_handle[fd]=(long)s;
+  mt_unlock(&fd_mutex);
 
   FDDEBUG(fprintf(stderr,"New socket: %d (%d)\n",fd,s));
 
@@ -174,17 +195,21 @@ FD fd_socket(int domain, int type, int proto)
 int fd_pipe(int fds[2])
 {
   HANDLE files[2];
+  mt_lock(&fd_mutex);
   if(first_free_handle == FD_NO_MORE_FREE)
   {
+    mt_unlock(&fd_mutex);
     errno=EMFILE;
     return -1;
   }
+  mt_unlock(&fd_mutex);
   if(!CreatePipe(&files[0], &files[1], NULL, 0))
   {
     errno=GetLastError();
     return -1;
   }
   
+  mt_lock(&fd_mutex);
   fds[0]=first_free_handle;
   first_free_handle=fd_type[fds[0]];
   fd_type[fds[0]]=FD_PIPE;
@@ -195,6 +220,7 @@ int fd_pipe(int fds[2])
   fd_type[fds[1]]=FD_PIPE;
   da_handle[fds[1]]=(long)files[1];
 
+  mt_unlock(&fd_mutex);
   FDDEBUG(fprintf(stderr,"New pipe: %d (%d) -> %d (%d)\n",fds[0],files[0], fds[1], fds[1]));;
 
   return 0;
@@ -204,18 +230,23 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen)
 {
   FD new_fd;
   SOCKET s;
+  mt_lock(&fd_mutex);
   FDDEBUG(fprintf(stderr,"Accept on %d (%d)..\n",fd,da_handle[fd]));
   if(first_free_handle == FD_NO_MORE_FREE)
   {
+    mt_unlock(&fd_mutex);
     errno=EMFILE;
     return -1;
   }
   if(fd_type[fd]!=FD_SOCKET)
   {
+    mt_unlock(&fd_mutex);
     errno=ENOTSUPP;
     return -1;
   }
-  s=accept((SOCKET)da_handle[fd], addr, addrlen);
+  s=(SOCKET)da_handle[fd];
+  mt_unlock(&fd_mutex);
+  s=accept(s, addr, addrlen);
   if(s==INVALID_SOCKET)
   {
     errno=WSAGetLastError();
@@ -223,6 +254,7 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen)
     return -1;
   }
   
+  mt_lock(&fd_mutex);
   new_fd=first_free_handle;
   first_free_handle=fd_type[new_fd];
   fd_type[new_fd]=FD_SOCKET;
@@ -230,6 +262,8 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen)
 
   FDDEBUG(fprintf(stderr,"Accept on %d (%d) returned new socket: %d (%d)\n",fd,da_handle[fd],new_fd,s));
 
+  mt_unlock(&fd_mutex);
+
   return new_fd;
 }
 
@@ -237,10 +271,14 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen)
 #define SOCKFUN(NAME,X1,X2) \
 int PIKE_CONCAT(fd_,NAME) X1 { SOCKET ret; \
   FDDEBUG(fprintf(stderr, #NAME " on %d (%d)\n",fd,da_handle[fd])); \
+  mt_lock(&fd_mutex); \
   if(fd_type[fd] != FD_SOCKET) { \
+     mt_unlock(&fd_mutex); \
      errno=ENOTSUPP; \
      return -1; \
    } \
+  ret=(SOCKET)da_handle[fd]; \
+  mt_unlock(&fd_mutex); \
    ret=NAME X2; \
    if(ret == SOCKET_ERROR) errno=WSAGetLastError(); \
    FDDEBUG(fprintf(stderr, #NAME " returned %d (%d)\n",ret,errno)); \
@@ -248,25 +286,26 @@ int PIKE_CONCAT(fd_,NAME) X1 { SOCKET ret; \
 }
 
 #define SOCKFUN1(NAME,T1) \
-   SOCKFUN(NAME, (FD fd, T1 a), ((SOCKET)da_handle[fd], a) )
+   SOCKFUN(NAME, (FD fd, T1 a), (ret, a) )
 
 #define SOCKFUN2(NAME,T1,T2) \
-   SOCKFUN(NAME, (FD fd, T1 a, T2 b), ((SOCKET)da_handle[fd], a, b) )
+   SOCKFUN(NAME, (FD fd, T1 a, T2 b), (ret, a, b) )
 
 #define SOCKFUN3(NAME,T1,T2,T3) \
-   SOCKFUN(NAME, (FD fd, T1 a, T2 b, T3 c), ((SOCKET)da_handle[fd], a, b, c) )
+   SOCKFUN(NAME, (FD fd, T1 a, T2 b, T3 c), (ret, a, b, c) )
 
 #define SOCKFUN4(NAME,T1,T2,T3,T4) \
-   SOCKFUN(NAME, (FD fd,T1 a,T2 b,T3 c,T4 d), ((SOCKET)da_handle[fd],a,b,c,d) )
+   SOCKFUN(NAME, (FD fd,T1 a,T2 b,T3 c,T4 d), (ret,a,b,c,d) )
 
 #define SOCKFUN5(NAME,T1,T2,T3,T4,T5) \
-   SOCKFUN(NAME, (FD fd,T1 a,T2 b,T3 c,T4 d,T5 e), ((SOCKET)da_handle[fd],a,b,c,d,e))
+   SOCKFUN(NAME, (FD fd,T1 a,T2 b,T3 c,T4 d,T5 e), (ret,a,b,c,d,e))
 
 
 SOCKFUN2(bind, struct sockaddr *, int)
 int fd_connect (FD fd, struct sockaddr *a, int len)
 {
   SOCKET ret;
+  mt_lock(&fd_mutex);
   FDDEBUG(fprintf(stderr, "connect on %d (%d)\n",fd,da_handle[fd]);
 	  for(ret=0;ret<len;ret++)
 	  fprintf(stderr," %02x",((unsigned char *)a)[ret]);
@@ -274,10 +313,13 @@ int fd_connect (FD fd, struct sockaddr *a, int len)
   )
   if(fd_type[fd] != FD_SOCKET)
   {
+    mt_unlock(&fd_mutex);
     errno=ENOTSUPP;
     return -1; 
   } 
-  ret=connect((SOCKET)da_handle[fd],a,len); 
+  ret=(SOCKET)da_handle[fd];
+  mt_unlock(&fd_mutex);
+  ret=connect(ret,a,len); 
   if(ret == SOCKET_ERROR) errno=WSAGetLastError(); 
   FDDEBUG(fprintf(stderr, "connect returned %d (%d)\n",ret,errno)); 
   return (int)ret; 
@@ -294,40 +336,61 @@ SOCKFUN1(listen, int)
 
 int fd_close(FD fd)
 {
+  HANDLE h;
+  mt_lock(&fd_mutex);
+  h=(HANDLE)da_handle[fd];
   FDDEBUG(fprintf(stderr,"Closing %d (%d)\n",fd,da_handle[fd]));
-  if(!CloseHandle((HANDLE)da_handle[fd]))
+  mt_unlock(&fd_mutex);
+  if(!CloseHandle(h))
   {
     errno=GetLastError();
     return -1;
   }
-  fd_type[fd]=first_free_handle;
-  first_free_handle=fd;
+  mt_lock(&fd_mutex);
+  if(fd_type[fd]<FD_NO_MORE_FREE)
+  {
+    fd_type[fd]=first_free_handle;
+    first_free_handle=fd;
+  }
+  mt_unlock(&fd_mutex);
+
   return 0;
 }
 
 long fd_write(FD fd, void *buf, long len)
 {
   DWORD ret;
+  long handle;
+  mt_lock(&fd_mutex);
   FDDEBUG(fprintf(stderr,"Writing %d bytes to %d (%d)\n",len,fd,da_handle[fd]));
-  switch(fd_type[fd])
+  ret=fd_type[fd];
+  handle=da_handle[fd];
+  mt_unlock(&fd_mutex);
+  
+  switch(ret)
   {
     case FD_SOCKET:
-      ret=send((SOCKET)da_handle[fd], buf, len, 0);
+      ret=send((SOCKET)handle, buf, len, 0);
       if(ret<0)
       {
 	errno=WSAGetLastError();
+	FDDEBUG(fprintf(stderr,"Write on %d failed (%d)\n",fd,errno));
 	return -1;
       }
+      FDDEBUG(fprintf(stderr,"Wrote %d bytes to %d)\n",len,fd));
       return ret;
 
     case FD_CONSOLE:
     case FD_FILE:
     case FD_PIPE:
-      if(!WriteFile((HANDLE)da_handle[fd], buf, len, &ret,0) && !ret)
+      ret=0;
+      if(!WriteFile((HANDLE)handle, buf, len, &ret,0) && ret<=0)
       {
 	errno=GetLastError();
+	FDDEBUG(fprintf(stderr,"Write on %d failed (%d)\n",fd,errno));
 	return -1;
       }
+      FDDEBUG(fprintf(stderr,"Wrote %d bytes to %d)\n",len,fd));
       return ret;
 
     default:
@@ -339,30 +402,39 @@ long fd_write(FD fd, void *buf, long len)
 long fd_read(FD fd, void *to, long len)
 {
   DWORD ret;
+  int rret;
+  long handle;
+
+  mt_lock(&fd_mutex);
   FDDEBUG(fprintf(stderr,"Reading %d bytes from %d (%d) to %lx\n",len,fd,da_handle[fd],(int)(char *)to));
-  switch(fd_type[fd])
+  ret=fd_type[fd];
+  handle=da_handle[fd];
+  mt_unlock(&fd_mutex);
+
+  switch(ret)
   {
     case FD_SOCKET:
-      ret=recv((SOCKET)da_handle[fd], to, len, 0);
-      if(ret<0)
+      rret=recv((SOCKET)handle, to, len, 0);
+      if(rret<0)
       {
 	errno=WSAGetLastError();
+	FDDEBUG(fprintf(stderr,"Read on %d failed %ld\n",fd,errno));
 	return -1;
       }
-      FDDEBUG(fprintf(stderr,"Read returned %ld\n",ret));
-      return ret;
+      FDDEBUG(fprintf(stderr,"Read on %d returned %ld\n",fd,rret));
+      return rret;
 
     case FD_CONSOLE:
     case FD_FILE:
     case FD_PIPE:
       ret=0;
-      if(!ReadFile((HANDLE)da_handle[fd], to, len, &ret,0) && !ret)
+      if(!ReadFile((HANDLE)handle, to, len, &ret,0) && ret<=0)
       {
 	errno=GetLastError();
 	FDDEBUG(fprintf(stderr,"Read failed %d\n",errno));
 	return -1;
       }
-      FDDEBUG(fprintf(stderr,"Read returned %ld\n",ret));
+      FDDEBUG(fprintf(stderr,"Read on %d returned %ld\n",fd,ret));
       return ret;
 
     default:
@@ -374,13 +446,17 @@ long fd_read(FD fd, void *to, long len)
 long fd_lseek(FD fd, long pos, int where)
 {
   long ret;
+  mt_lock(&fd_mutex);
   if(fd_type[fd]!=FD_FILE)
   {
+    mt_unlock(&fd_mutex);
     errno=ENOTSUPP;
     return -1;
   }
+  ret=da_handle[fd];
+  mt_unlock(&fd_mutex);
 
-  ret=LZSeek(da_handle[fd], pos, where);
+  ret=LZSeek((HANDLE)ret, pos, where);
   if(ret<0)
   {
     errno=GetLastError();
@@ -401,12 +477,13 @@ static long convert_filetime_to_time_t(FILETIME tmp)
 int fd_fstat(FD fd, struct stat *s)
 {
   DWORD x;
-  int ret;
+
   FILETIME c,a,m;
   FDDEBUG(fprintf(stderr,"fstat on %d (%d)\n",fd,da_handle[fd]));
   if(fd_type[fd]!=FD_FILE)
   {
     errno=ENOTSUPP;
+    mt_unlock(&fd_mutex);
     return -1;
   }
 
@@ -494,10 +571,12 @@ FD fd_dup(FD from)
     return -1;
   }
 
+  mt_lock(&fd_mutex);
   fd=first_free_handle;
   first_free_handle=fd_type[fd];
   fd_type[fd]=fd_type[from];
   da_handle[fd]=(long)x;
+  mt_unlock(&fd_mutex);
   
   FDDEBUG(fprintf(stderr,"Dup %d (%d) to %d (%d)\n",from,da_handle[from],fd,x));
   return fd;
@@ -512,11 +591,13 @@ FD fd_dup2(FD from, FD to)
     return -1;
   }
 
+  mt_lock(&fd_mutex);
   if(fd_type[to] < FD_NO_MORE_FREE)
   {
     if(!CloseHandle((HANDLE)da_handle[to]))
     {
       errno=GetLastError();
+      mt_unlock(&fd_mutex);
       return -1;
     }
   }else{
@@ -532,6 +613,7 @@ FD fd_dup2(FD from, FD to)
   }
   fd_type[to]=fd_type[from];
   da_handle[to]=(long)x;
+  mt_unlock(&fd_mutex);
 
   FDDEBUG(fprintf(stderr,"Dup2 %d (%d) to %d (%d)\n",from,da_handle[from],to,x));
 
diff --git a/src/fdlib.h b/src/fdlib.h
index 272b3553cf..50bbd8ae6b 100644
--- a/src/fdlib.h
+++ b/src/fdlib.h
@@ -51,7 +51,7 @@ typedef int FD;
 
 /* Prototypes begin here */
 char *fd_info(int fd);
-int fd_query_query_properties(int fd, int guess);
+int fd_query_properties(int fd, int guess);
 void fd_init();
 void fd_exit();
 FD fd_open(char *file, int open_mode, int create_mode);
@@ -94,6 +94,9 @@ struct fd_data_hash_block;
 int get_fd_data_key(void);
 void store_fd_data(FD fd, int key, void *data);
 void *get_fd_data(FD fd, int key);
+struct event;
+struct fd_waitor;
+void fd_waitor_set_customer(struct fd_waitor *x, FD customer, int flags);
 /* Prototypes end here */
 
 #undef SOCKFUN1
diff --git a/src/interpret.c b/src/interpret.c
index 22404a8aee..db8dce364b 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.64 1998/01/30 20:04:32 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.65 1998/02/01 02:07:24 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -1082,6 +1082,24 @@ static int eval_instruction(unsigned char *pc)
       }
       break;
 
+#ifdef F_ASSIGN_ARRAY
+      CASE(F_ASSIGN_ARRAY);
+      {
+	struct svalue *base=*--mark_sp;
+	INT32 e,args=(sp-base)>>1
+	if(sp[-1].type != T_ARRAY)
+	  error("Bad argument to multiple assign, not an array.\n");
+	if(sp[-1].u.array->size < args)
+	  error("Not enough elements in array for multiple assign.\n");
+
+	for(e=0;e<args;e++)
+	  assign_lvalue(base+e*2,sp[-1].u.array->item+e);
+
+	pop_n_elems(sp-base);
+	break;
+      }
+#endif
+
       /* Stack machine stuff */
       CASE(F_POP_VALUE); pop_stack(); break;
       CASE(F_POP_N_ELEMS); pop_n_elems(GET_ARG()); break;
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 9f73cd8cdb..8249689e78 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.72 1998/01/30 06:20:54 hubbe Exp $");
+RCSID("$Id: file.c,v 1.73 1998/02/01 02:08:24 hubbe Exp $");
 #include "fdlib.h"
 #include "interpret.h"
 #include "svalue.h"
@@ -1116,6 +1116,8 @@ retry_connect:
   retry_accept:
     sv[0]=fd_accept(fd,(struct sockaddr *)&addr,&len);
 
+    set_nonblocking(sv[0],0);
+
     if(sv[0] < 0) {
       if(errno==EINTR) goto retry_accept;
       fd_close(sv[1]);
@@ -1616,10 +1618,14 @@ static void *proxy_thread(void * data)
   char buffer[READ_BUFFER];
   struct new_thread_data *p=(struct new_thread_data *)data;
 
+/*  fprintf(stderr,"new proxy thread, from %d to %d.\n",p->fromfd,p->tofd); */
+/*  fprintf(stderr,"Thread started %p.\n",p); */
   while(1)
   {
     long len, w;
+/*     fprintf(stderr,"reading from %d.\n",p->fromfd); */
     len=fd_read(p->fromfd, buffer, READ_BUFFER);
+    if(len==0) break;
     if(len<0)
     {
       if(errno==EINTR) continue;
@@ -1627,17 +1633,24 @@ static void *proxy_thread(void * data)
     }
 
     w=0;
+/*    fprintf(stderr,"writing to %d.\n",p->tofd); */
     while(w<len)
     {
       long wl=fd_write(p->tofd, buffer+w, len-w);
-      if(wl<0) if(errno==EINTR) continue;
+      if(wl<0)
+      {
+	if(errno==EINTR) continue;
+	break;
+      }
       w+=wl;
     }
   }
 
+/*  fprintf(stderr,"Proxy thread (%d - %d) done.\n",p->fromfd,p->tofd); */
   mt_lock(&interpreter_lock);
   free_object(p->from);
   free_object(p->to);
+  num_threads--;
   mt_unlock(&interpreter_lock);
   free((char *)p);
   return 0;
@@ -1648,7 +1661,7 @@ 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);
+  check_all_args("Stdio.File->proxy",args, BIT_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");
@@ -1660,7 +1673,8 @@ void file_proxy(INT32 args)
   p->fromfd=f->fd;
   p->to->refs++;
   p->from->refs++;
-  if(th_create_small(&id,new_thread_func,p))
+  num_threads++;
+  if(th_create_small(&id,proxy_thread,p))
   {
     free((char *)p);
     error("Failed to create thread.\n");
@@ -1677,6 +1691,7 @@ void create_proxy_pipe(struct object *o, int for_reading)
   push_int(fd_INTERPROCESSABLE);
   apply(n,"pipe",1);
   n2=sp[-1].u.object;
+  /* Stack is now: pipe(read), pipe(write) */
   if(for_reading)
   {
     ref_push_object(o);
diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c
index 511b95d8af..76e052bf24 100644
--- a/src/modules/files/socket.c
+++ b/src/modules/files/socket.c
@@ -370,12 +370,11 @@ static void socket_query_address(INT32 args)
 static void init_port_struct(struct object *o)
 {
   THIS->fd=-1;
-  THIS->id.type=T_OBJECT;
+  THIS->id.type=T_INT;
 #ifdef __CHECKER__
   THIS->id.subtype=0;
 #endif
-  THIS->id.u.object=o;
-  o->refs++;
+  THIS->id.u.integer=0;
   THIS->accept_callback.type=T_INT;
   THIS->my_errno=0;
 }
diff --git a/src/pike_memory.c b/src/pike_memory.c
index ad3860956c..78625cd05b 100644
--- a/src/pike_memory.c
+++ b/src/pike_memory.c
@@ -788,6 +788,7 @@ static void cleanup_memhdrs()
 int main(int argc, char *argv[])
 {
   extern int dbm_main(int, char **);
+  mt_init(&debug_malloc_mutex);
   atexit(cleanup_memhdrs);
   return dbm_main(argc, argv);
 }
diff --git a/src/program.h b/src/program.h
index 76d244a394..4d7c64cdc2 100644
--- a/src/program.h
+++ b/src/program.h
@@ -170,7 +170,7 @@ struct inherit
 #define PROGRAM_PASS_1_DONE 8
 
 /* Program will be destructed as soon at it runs out of references. */
-#define PROGRAM_DESTRUCT_IMMEDIATE 15
+#define PROGRAM_DESTRUCT_IMMEDIATE 16
 
 struct program
 {
diff --git a/src/signal_handler.c b/src/signal_handler.c
index cd7a10021d..cd98e0e731 100644
--- a/src/signal_handler.c
+++ b/src/signal_handler.c
@@ -555,12 +555,12 @@ static HANDLE get_inheritable_handle(struct mapping *optional,
       apply(tmp->u.object,"query_fd",0);
       if(sp[-1].type == T_INT)
       {
-	if(!(fd_query_properties(sp[-1].u.integer) & fd_INTERPROCESSABLE))
+	if(!(fd_query_properties(sp[-1].u.integer, 0) & 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);
+	  apply(sp[-1].u.object, "query_fd", 0);
 	}
 	
 	  
@@ -669,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",0);
+      t1=get_inheritable_handle(optional, "stdin",1);
       if(t1!=INVALID_HANDLE_VALUE) info.hStdInput=t1;
 
-      t2=get_inheritable_handle(optional, "stdout",1);
+      t2=get_inheritable_handle(optional, "stdout",0);
       if(t2!=INVALID_HANDLE_VALUE) info.hStdOutput=t2;
 
-      t3=get_inheritable_handle(optional, "stderr",1);
+      t3=get_inheritable_handle(optional, "stderr",0);
       if(t3!=INVALID_HANDLE_VALUE) info.hStdError=t3;
 
 	if((tmp=simple_mapping_string_lookup(optional, "env")))
-- 
GitLab