diff --git a/NT/tools/lib b/NT/tools/lib
index d99d5b048c37e640648805b43d2473e58e6fc205..7b908b97821d409e73ecaaff1428409681c7bbdc 100644
--- a/NT/tools/lib
+++ b/NT/tools/lib
@@ -1,5 +1,5 @@
 CLEANUP=yes
-DEBUG=yes
+DEBUG=no
 
 if [ $DEBUG = yes ]; then
   set -x
diff --git a/bin/test_pike.pike b/bin/test_pike.pike
index f05c9eff6e07ce940000ff7e92d8db8165549c93..edd8a137f12108270bca16c239f42cb56ee90905 100755
--- a/bin/test_pike.pike
+++ b/bin/test_pike.pike
@@ -1,6 +1,6 @@
 #!/usr/local/bin/pike
 
-/* $Id: test_pike.pike,v 1.4 1997/05/31 22:03:40 grubba Exp $ */
+/* $Id: test_pike.pike,v 1.5 1998/01/03 07:11:24 hubbe Exp $ */
 
 #include <simulate.h>
 
@@ -12,7 +12,7 @@
 int main(int argc, string *argv)
 {
   int e, verbose, successes, errors, t, check;
-  string *tests;
+  string *tests,tmp;
   program testprogram;
   int start, fail, mem;
   int loop=1;
@@ -81,21 +81,27 @@ int main(int argc, string *argv)
 	  perror("Unknown argument: "+opt+".\n");
 	  exit(1);
 	}
-	tests=(read_bytes(argv[e])||"")/"\n....\n";
+	tmp=read_bytes(argv[e]);
+	if(!tmp)
+	{
+	  perror("Failed to read test file, errno="+errno()+".\n");
+	  exit(1);
+	}
     }
   }
 
-  if(!tests)
+  if(!tmp)
   {
-    tests=(clone((program)"/precompiled/file","stdin")->read(0x7fffffff)||"")/"\n....\n";
+    tmp=Stdio.stdin->read(0x7fffffff);
+    if(!tmp)
+    {
+      perror("Failed to read test file, errno="+errno()+".\n");
+      exit(1);
+    }
   }
 
-  if(!tests)
-  {
-    perror("Failed to read test file!\n");
-    exit(1);
-  }
 
+  tests=tmp/"\n....\n";
   tests=tests[0..sizeof(tests)-2];
 
   while(loop--)
diff --git a/lib/modules/Stdio.pmod b/lib/modules/Stdio.pmod
index c972fa8a8c3bd1312aa28c77bdc06e2ae12b3e84..5f07e008886ee0756349c928213e9c7ddd94c01d 100644
--- a/lib/modules/Stdio.pmod
+++ b/lib/modules/Stdio.pmod
@@ -193,7 +193,8 @@ string read_bytes(string filename,void|int start,void|int len)
   case 2:
     len=0x7fffffff;
   case 3:
-    f->seek(start);
+    if(start)
+      f->seek(start);
   }
   ret=f->read(len);
   f->close();
diff --git a/src/fdlib.c b/src/fdlib.c
index 99c68614ebd4a1494b9be0ae5391e86bf62d4e7c..d958ba98a546062a67cf7e87e592635b3c00bde8 100644
--- a/src/fdlib.c
+++ b/src/fdlib.c
@@ -1,4 +1,5 @@
 #include "fdlib.h"
+#include <math.h>
 
 #ifdef HAVE_WINSOCK_H
 
@@ -11,6 +12,8 @@ long da_handle[MAX_OPEN_FILEDESCRIPTORS];
 static int fd_type[MAX_OPEN_FILEDESCRIPTORS];
 int first_free_handle;
 
+#define FDDEBUG(X)
+
 void fd_init()
 {
   int e;
@@ -20,14 +23,14 @@ void fd_init()
   {
     fatal("No winsock available.\n");
   }
-/*  fprintf(stderr,"Using %s\n",wsadata.szDescription); */
+  FDDEBUG(fprintf(stderr,"Using %s\n",wsadata.szDescription));
   
   fd_type[0]=FD_CONSOLE;
-  da_handle[0]=GetStdHandle(STD_INPUT_HANDLE);
+  da_handle[0]=(long)GetStdHandle(STD_INPUT_HANDLE);
   fd_type[1]=FD_CONSOLE;
-  da_handle[1]=GetStdHandle(STD_OUTPUT_HANDLE);
+  da_handle[1]=(long)GetStdHandle(STD_OUTPUT_HANDLE);
   fd_type[2]=FD_CONSOLE;
-  da_handle[2]=GetStdHandle(STD_ERROR_HANDLE);
+  da_handle[2]=(long)GetStdHandle(STD_ERROR_HANDLE);
 
   first_free_handle=3;
   for(e=3;e<MAX_OPEN_FILEDESCRIPTORS-1;e++)
@@ -46,6 +49,7 @@ FD fd_open(char *file, int open_mode, int create_mode)
   FD fd;
   DWORD omode,cmode,amode;
   omode=0;
+  FDDEBUG(fprintf(stderr,"fd_open(%s,0x%x,%o)\n",file,open_mode,create_mode));
   if(first_free_handle == FD_NO_MORE_FREE)
   {
     errno=EMFILE;
@@ -101,10 +105,13 @@ FD fd_open(char *file, int open_mode, int create_mode)
     return -1;
   }
 
+
   fd=first_free_handle;
   first_free_handle=fd_type[fd];
   fd_type[fd]=FD_FILE;
-  da_handle[fd]=x;
+  da_handle[fd]=(long)x;
+
+  FDDEBUG(fprintf(stderr,"Opened %s file as %d (%d)\n",file,fd,x));
 
   return fd;
 }
@@ -128,7 +135,9 @@ FD fd_socket(int domain, int type, int proto)
   fd=first_free_handle;
   first_free_handle=fd_type[fd];
   fd_type[fd]=FD_SOCKET;
-  da_handle[fd]=(HANDLE)s;
+  da_handle[fd]=(long)s;
+
+  FDDEBUG(fprintf(stderr,"New socket: %d (%d)\n",fd,s));
 
   return fd;
 }
@@ -154,21 +163,26 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen)
     return -1;
   }
   
-  fd=first_free_handle;
-  first_free_handle=fd_type[fd];
-  fd_type[fd]=FD_SOCKET;
-  da_handle[fd]=(HANDLE)s;
-  return fd;
+  new_fd=first_free_handle;
+  first_free_handle=fd_type[new_fd];
+  fd_type[new_fd]=FD_SOCKET;
+  da_handle[new_fd]=(long)s;
+
+  FDDEBUG(fprintf(stderr,"Accept on %d (%d) returned new socket: %d (%d)\n",fd,da_handle[fd],new_fd,s));
+
+  return new_fd;
 }
 
 #define SOCKFUN(NAME,X1,X2) \
 int PIKE_CONCAT(fd_,NAME) X1 { int ret; \
+  FDDEBUG(fprintf(stderr, #NAME " on %d (%d)\n",fd,da_handle[fd])); \
   if(fd_type[fd] != FD_SOCKET) { \
      errno=ENOTSUPP; \
      return -1; \
    } \
    ret=NAME X2; \
    if(ret == SOCKET_ERROR) errno=WSAGetLastError(); \
+   FDDEBUG(fprintf(stderr, #NAME " returned %d (%d)\n",ret,errno)); \
    return ret; \
 }
 
@@ -202,7 +216,8 @@ SOCKFUN1(listen, int)
 
 int fd_close(FD fd)
 {
-  if(!CloseHandle(da_handle[fd]))
+  FDDEBUG(fprintf(stderr,"Closing %d (%d)\n",fd,da_handle[fd]));
+  if(!CloseHandle((HANDLE)da_handle[fd]))
   {
     errno=GetLastError();
     return -1;
@@ -215,6 +230,7 @@ int fd_close(FD fd)
 long fd_write(FD fd, void *buf, long len)
 {
   DWORD ret;
+  FDDEBUG(fprintf(stderr,"Writing %d bytes to %d (%d)\n",len,fd,da_handle[fd]));
   switch(fd_type[fd])
   {
     case FD_SOCKET:
@@ -228,7 +244,7 @@ long fd_write(FD fd, void *buf, long len)
 
     case FD_CONSOLE:
     case FD_FILE:
-      if(!WriteFile(da_handle[fd], buf, len, &ret,0) && !ret)
+      if(!WriteFile((HANDLE)da_handle[fd], buf, len, &ret,0) && !ret)
       {
 	errno=GetLastError();
 	return -1;
@@ -241,27 +257,32 @@ long fd_write(FD fd, void *buf, long len)
   }
 }
 
-long fd_read(FD fd, void *buf, long len)
+long fd_read(FD fd, void *to, long len)
 {
   DWORD ret;
+  FDDEBUG(fprintf(stderr,"Reading %d bytes from %d (%d) to %lx\n",len,fd,da_handle[fd],(int)(char *)to));
   switch(fd_type[fd])
   {
     case FD_SOCKET:
-      ret=recv((SOCKET)da_handle[fd], buf, len, 0);
+      ret=recv((SOCKET)da_handle[fd], to, len, 0);
       if(ret<0)
       {
 	errno=WSAGetLastError();
 	return -1;
       }
+      FDDEBUG(fprintf(stderr,"Read returned %ld\n",ret));
       return ret;
 
     case FD_CONSOLE:
     case FD_FILE:
-      if(!ReadFile(da_handle[fd], buf, len, &ret,0) && !ret)
+      ret=0;
+      if(!ReadFile((HANDLE)da_handle[fd], to, len, &ret,0) && !ret)
       {
 	errno=GetLastError();
+	FDDEBUG(fprintf(stderr,"Read failed %d\n",errno));
 	return -1;
       }
+      FDDEBUG(fprintf(stderr,"Read returned %ld\n",ret));
       return ret;
 
     default:
@@ -288,22 +309,63 @@ long fd_lseek(FD fd, long pos, int where)
   return ret;
 }
 
+static long convert_filetime_to_time_t(FILETIME tmp)
+{
+  double t;
+  t=tmp.dwHighDateTime * pow(2.0,32.0) + (double)tmp.dwLowDateTime;
+  t/=10000000.0;
+  t-=11644473600.0;
+  return (long)floor(t);
+}
+
 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;
     return -1;
   }
 
-  ret=fstat(da_handle[fd], s);
-  if(ret<0)
+  MEMSET(s, 0, sizeof(struct stat));
+  s->st_nlink=1;
+
+  switch(fd_type[fd])
   {
-    errno=GetLastError();
-    return -1;
+    case FD_SOCKET:
+      s->st_mode=S_IFSOCK;
+      break;
+
+    default:
+      switch(GetFileType((HANDLE)da_handle[fd]))
+      {
+	default:
+	case FILE_TYPE_UNKNOWN: s->st_mode=0;        break;
+	case FILE_TYPE_DISK:
+	  s->st_mode=S_IFREG; 
+	  s->st_size=GetFileSize((HANDLE)da_handle[fd],&x);
+	  if(x)
+	  {
+	    s->st_size=0x7fffffff;
+	  }
+	  if(!GetFileTime((HANDLE)da_handle[fd], &c, &a, &m))
+	  {
+	    errno=GetLastError();
+	    return -1;
+	  }
+	  s->st_ctime=convert_filetime_to_time_t(c);
+	  s->st_atime=convert_filetime_to_time_t(a);
+	  s->st_mtime=convert_filetime_to_time_t(m);
+	  break;
+	case FILE_TYPE_CHAR:    s->st_mode=S_IFCHR;  break;
+	case FILE_TYPE_PIPE:    s->st_mode=S_IFFIFO; break;
+      }
   }
-  return ret;
+  s->st_mode |= 0666;
+  return 0;
 }
 
 int fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t)
@@ -340,16 +402,58 @@ int fd_ioctl(FD fd, int cmd, void *data)
 }
 
 
-FD fd_dup(FD fd)
+FD fd_dup(FD from)
 {
-  errno=ENOTSUPP;
-  return -1;
+  FD fd;
+  HANDLE x,p=GetCurrentProcess();
+  if(!DuplicateHandle(p,(HANDLE)da_handle[from],p,&x,NULL,1,DUPLICATE_SAME_ACCESS))
+  {
+    errno=GetLastError();
+    return -1;
+  }
+
+  fd=first_free_handle;
+  first_free_handle=fd_type[fd];
+  fd_type[fd]=fd_type[from];
+  da_handle[fd]=(long)x;
+  
+  FDDEBUG(fprintf(stderr,"Dup %d (%d) to %d (%d)\n",from,da_handle[from],fd,x));
+  return fd;
 }
 
 FD fd_dup2(FD to, FD from)
 {
-  errno=ENOTSUPP;
-  return -1;
+  HANDLE x,p=GetCurrentProcess();
+  if(!DuplicateHandle(p,(HANDLE)da_handle[from],p,&x,NULL,1,DUPLICATE_SAME_ACCESS))
+  {
+    errno=GetLastError();
+    return -1;
+  }
+
+  if(fd_type[to] < FD_NO_MORE_FREE)
+  {
+    if(!CloseHandle((HANDLE)da_handle[to]))
+    {
+      errno=GetLastError();
+      return -1;
+    }
+  }else{
+    int *prev,next;
+    for(prev=&first_free_handle;(next=*prev) != FD_NO_MORE_FREE;prev=fd_type+next)
+    {
+      if(next==to)
+      {
+	*prev=fd_type[next];
+	break;
+      }
+    }
+  }
+  fd_type[to]=fd_type[from];
+  da_handle[to]=(long)x;
+
+  FDDEBUG(fprintf(stderr,"Dup2 %d (%d) to %d (%d)\n",from,da_handle[from],to,x));
+
+  return to;
 }
 
 #endif
diff --git a/src/fdlib.h b/src/fdlib.h
index 1159c41d057fc7c8ca92798c77c11a4d3d47b87a..be123d7369b335fbea2655ccb9153284630d5d2c 100644
--- a/src/fdlib.h
+++ b/src/fdlib.h
@@ -15,6 +15,10 @@
 #include <errno.h>
 #endif
 
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
 #ifdef HAVE_WINSOCK_H
 
 
@@ -102,6 +106,10 @@ extern long da_handle[MAX_OPEN_FILEDESCRIPTORS];
 #define fd_FD_ISSET(X,Y) FD_ISSET((SOCKET)da_handle[X],Y)
 #define fd_FD_ZERO(X) FD_ZERO(X)
 
+#ifndef S_IFSOCK
+#define S_IFSOCK 0140000
+#endif
+
 #else
 
 
diff --git a/src/modules/Image/font.c b/src/modules/Image/font.c
index 4673c869ecffb2be16f2ca737038ff91712e048c..d22e2a161f7a7325f4d5bf9621fbae2e713de164 100644
--- a/src/modules/Image/font.c
+++ b/src/modules/Image/font.c
@@ -1,4 +1,4 @@
-/* $Id: font.c,v 1.23 1997/12/28 09:29:32 hubbe Exp $ */
+/* $Id: font.c,v 1.24 1998/01/03 07:12:40 hubbe Exp $ */
 #include <config.h>
 
 #define SPACE_CHAR 'i'
@@ -6,7 +6,7 @@
 /*
 **! module Image
 **! note
-**!	$Id: font.c,v 1.23 1997/12/28 09:29:32 hubbe Exp $
+**!	$Id: font.c,v 1.24 1998/01/03 07:12:40 hubbe Exp $
 **! class font
 **!
 **! note
@@ -94,6 +94,7 @@ Kerningtable types:
 
 
 #include "global.h"
+#include "fdlib.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -212,10 +213,10 @@ static INLINE int char_width(struct font *this, unsigned char c)
 }  
 
 #ifndef HAVE_MMAP
-static INLINE int my_read(int from, char *buf, int towrite)
+static INLINE int my_read(int from, void *t, int towrite)
 {
   int res;
-  while((res = read(from, buf, towrite)) < 0)
+  while((res = fd_read(from, t, towrite)) < 0)
   {
     switch(errno)
     {
@@ -235,7 +236,7 @@ static INLINE long file_size(int fd)
 {
   struct stat tmp;
   int res;
-  if((!fstat(fd, &tmp)) &&
+  if((!fd_fstat(fd, &tmp)) &&
      (tmp.st_mode & S_IFREG)) {
     return res = tmp.st_size;
   }
@@ -300,29 +301,32 @@ void font_load(INT32 args)
 #ifdef FONT_DEBUG
      fprintf(stderr,"FONT open '%s'\n",sp[-args].u.string->str);
 #endif
-     fd = open(sp[-args].u.string->str,O_RDONLY);
+     fd = fd_open(sp[-args].u.string->str,fd_RDONLY,0);
    } while(fd < 0 && errno == EINTR);
 
    if (fd >= 0)
    {
       long size;
-      struct font *new;
+      struct font *new_font;
 
       size = file_size(fd);
       if (size > 0)
       {
-	 new=THIS=(struct font *)xalloc(sizeof(struct font));
+	 new_font=THIS=(struct font *)xalloc(sizeof(struct font));
 
 	 THREADS_ALLOW();
 #ifdef HAVE_MMAP
-	 new->mem = 
+	 new_font->mem = 
 	    mmap(0,size,PROT_READ,MAP_SHARED,fd,0);
-	 new->mmaped_size=size;
+	 new_font->mmaped_size=size;
 #else
-	 new->mem = malloc(size);
-	 if ((new->mem) && (!my_read(fd,new->mem,size))) {
-	   free(new->mem);
-	   new->mem = NULL;
+	 new_font->mem = malloc(size);
+#ifdef FONT_DEBUG
+	 fprintf(stderr,"FONT Malloced %p (%d)\n",new_font->mem,size);
+#endif
+	 if ((new_font->mem) && (!my_read(fd,new_font->mem,size))) {
+	   free(new_font->mem);
+	   new_font->mem = NULL;
 	 }
 #endif
 	 THREADS_DISALLOW();
@@ -366,18 +370,18 @@ void font_load(INT32 args)
 
 		  THIS->chars=ntohl(fh->chars);
 
-		  new=malloc(sizeof(struct font)+
+		  new_font=malloc(sizeof(struct font)+
 			     sizeof(struct _char)*(THIS->chars-1));
-		  new->mem=THIS->mem;
+		  new_font->mem=THIS->mem;
 #ifdef HAVE_MMAP
-		  new->mmaped_size=THIS->mmaped_size;
+		  new_font->mmaped_size=THIS->mmaped_size;
 #endif
-		  new->chars=THIS->chars;
-		  new->xspacing_scale = 1.0;
-		  new->yspacing_scale = 1.0;
-		  new->justification = J_LEFT;
+		  new_font->chars=THIS->chars;
+		  new_font->xspacing_scale = 1.0;
+		  new_font->yspacing_scale = 1.0;
+		  new_font->justification = J_LEFT;
 		  free(THIS);
-		  THIS=new;
+		  THIS=new_font;
 
 		  THIS->height=ntohl(fh->height);
 		  THIS->baseline=ntohl(fh->baseline);
@@ -400,7 +404,7 @@ void font_load(INT32 args)
 			fprintf(stderr,"FONT failed on char %02xh %d '%c'\n",
 				i,i,i);
 #endif
-			free_font_struct(new);
+			free_font_struct(new_font);
 			THIS=NULL;
 			pop_n_elems(args);
 			push_int(0);
@@ -409,7 +413,7 @@ void font_load(INT32 args)
 
 		  }
 
-		  close(fd);
+		  fd_close(fd);
 		  pop_n_elems(args);
 		  THISOBJ->refs++;
 		  push_object(THISOBJ);   /* success */
@@ -435,7 +439,7 @@ void font_load(INT32 args)
 #ifdef FONT_DEBUG
       else fprintf(stderr,"FONT size failure\n");
 #endif
-      close(fd);
+      fd_close(fd);
    } /* fd failure */
 #ifdef FONT_DEBUG
    else fprintf(stderr,"FONT fd failure\n");
diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c
index 71e4afe495d1ba95e88a3d088e4296ef2e5f604c..7a1cfba574149b082d723b204010362043d0a3f2 100644
--- a/src/modules/files/efuns.c
+++ b/src/modules/files/efuns.c
@@ -4,6 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
+#include "fdlib.h"
 #include "interpret.h"
 #include "svalue.h"
 #include "stralloc.h"
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 2953bf0776e05aed10f5db171b8b180b6889e744..9daad37195613623cba995b831c5f3bd7d0657d3 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.63 1998/01/02 01:06:33 hubbe Exp $");
+RCSID("$Id: file.c,v 1.64 1998/01/03 07:13:05 hubbe Exp $");
 #include "fdlib.h"
 #include "interpret.h"
 #include "svalue.h"
@@ -260,14 +260,14 @@ static int map(int flags)
   ret=0;
   switch(flags & (FILE_READ|FILE_WRITE))
   {
-  case FILE_READ: ret=O_RDONLY; break;
-  case FILE_WRITE: ret=O_WRONLY; break;
-  case FILE_READ | FILE_WRITE: ret=O_RDWR; break;
+  case FILE_READ: ret=fd_RDONLY; break;
+  case FILE_WRITE: ret=fd_WRONLY; break;
+  case FILE_READ | FILE_WRITE: ret=fd_RDWR; break;
   }
-  if(flags & FILE_APPEND) ret|=O_APPEND;
-  if(flags & FILE_CREATE) ret|=O_CREAT;
-  if(flags & FILE_TRUNC) ret|=O_TRUNC;
-  if(flags & FILE_EXCLUSIVE) ret|=O_EXCL;
+  if(flags & FILE_APPEND) ret|=fd_APPEND;
+  if(flags & FILE_CREATE) ret|=fd_CREAT;
+  if(flags & FILE_TRUNC) ret|=fd_TRUNC;
+  if(flags & FILE_EXCLUSIVE) ret|=fd_EXCL;
   return ret;
 }
 
@@ -295,7 +295,7 @@ static struct pike_string *do_read(int fd,
     do{
       int fd=FD;
       THREADS_ALLOW();
-      i=read(fd, str->str+bytes_read, r);
+      i=fd_read(fd, str->str+bytes_read, r);
       THREADS_DISALLOW();
 
       check_signals(0,0,0);
@@ -350,7 +350,7 @@ static struct pike_string *do_read(int fd,
       buf = low_make_buf_space(try_read, &b);
 
       THREADS_ALLOW();
-      i=read(fd, buf, try_read);
+      i=fd_read(fd, buf, try_read);
       THREADS_DISALLOW();
 
       check_signals(0,0,0);
@@ -456,7 +456,7 @@ static void file_write(INT32 args)
   {
     int fd=FD;
     THREADS_ALLOW();
-    i=write(fd, str->str + written, str->len - written);
+    i=fd_write(fd, str->str + written, str->len - written);
     THREADS_DISALLOW();
 
 #ifdef _REENTRANT
@@ -1268,7 +1268,7 @@ static void file_dup2(INT32 args)
   if(fd < 0)
     error("File given to dup2 not open.\n");
 
-  if(dup2(FD,fd) < 0)
+  if(fd_dup2(FD,fd) < 0)
   {
     ERRNO=errno;
     pop_n_elems(args);
diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c
index ce609254b9d00d2fbe2086433713bc8f6a317e61..a497d97962b8dd86647d142e1d308c90f93cb596 100644
--- a/src/modules/files/socket.c
+++ b/src/modules/files/socket.c
@@ -223,7 +223,7 @@ static void port_bind(INT32 args)
   addr.sin_family = AF_INET;
 
   THREADS_ALLOW();
-  tmp=fd_bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 || listen(fd, 16384) < 0;
+  tmp=fd_bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 || fd_listen(fd, 16384) < 0;
   THREADS_DISALLOW();
 
   if(tmp)
diff --git a/src/modules/files/testsuite.in b/src/modules/files/testsuite.in
index 379e04d2da0377195f9d6399bfbb9b33355e1514..03dec921ca44f185c3ff91d51a13131e7da30470 100644
--- a/src/modules/files/testsuite.in
+++ b/src/modules/files/testsuite.in
@@ -19,7 +19,7 @@ test_true(rm("conftest"))
 test_eq(file_stat("conftest"),0)
 
 // - file->write
-test_any(int e; object o=clone(Stdio.File); if(!o->open("conftest","wct")) return -1; e=o->write("sune"); if(!o->close()) return -1; return e,4)
+test_any(int e; object o=clone(Stdio.File); if(!o->open("conftest","wct")) return -3; e=o->write("sune"); if(!o->close()) return -2; return e,4)
 
 // - file->read
 test_any(string s; object o=clone(Stdio.File); if(!o->open("conftest","r")) return -1; s=o->read(4); if(!o->close()) return -1; return s,"sune")
@@ -35,7 +35,7 @@ test_any(string s; object o=clone(Stdio.File); if(!o->open("conftest","r")) retu
 test_any(object o=clone(Stdio.File); return o->open("conftest","r") && o->read(4711) && o->tell() == 4711 && o->close(),1)
 
 // - file->stat
-test_any(object o=clone(Stdio.File); return equal(o->open("conftest","r") && o->stat(), file_stat("conftest")),1)
+test_equal([[Stdio.File("conftest","r")->stat()]],[[file_stat("conftest")]])
 
 // - file->errno
 test_do(clone(Stdio.File,"stdin")->errno())
@@ -69,7 +69,7 @@ test_any([[object o=clone(Stdio.File); o->open("conftest","r"); o=o->dup(); retu
 est_any([[object o=clone(Stdio.File),o2=clone(Stdio.File); o->open("conftest","r"); o2->assign(o); return o2->read(100)]] ,sprintf("%'+-*'100s",""))
 
 // - file->dup2
-test_any([[object o=clone(Stdio.File),o2=clone(Stdio.File); o2->pipe(); o->open("conftest","r"); o->dup2(o2); return o2->read(100)]] ,sprintf("%'+-*'100s",""))
+test_any([[object o=clone(Stdio.File),o2=clone(Stdio.File); o2->pipe(); o->open("conftest","r"); o2->dup2(o); return o2->read(100)]] ,sprintf("%'+-*'100s",""))
 
 test_eq(Process.popen("echo foo"),"foo\n")
 
diff --git a/src/port.c b/src/port.c
index 4c9d28a907071a14ed1a01cf981cfade66383442..317cbe5374b35e3142879feb28d74b6224f2bde9 100644
--- a/src/port.c
+++ b/src/port.c
@@ -26,14 +26,14 @@ time_t time PROT((time_t *));
 
 void GETTIMEOFDAY(struct timeval *t)
 {
-  double t;
+  double t2;
   FILETIME tmp;
   GetSystemTimeAsFileTime(&tmp);
-  t=tmp.dwHighDateTime * pow(2.0,32) + (double)tmp.dwLowDateTime;
-  t/=10000000.0;
-  t+=11644473600.0;
-  t->tv_sec=floor(t);
-  t->tv_usec=(t - t->tv_sec)*1000000.0;
+  t2=tmp.dwHighDateTime * pow(2.0,32.0) + (double)tmp.dwLowDateTime;
+  t2/=10000000.0;
+  t2-=11644473600.0;
+  t->tv_sec=floor(t2);
+  t->tv_usec=(t2 - t->tv_sec)*1000000.0;
 }
 
 #else
diff --git a/src/testsuite.in b/src/testsuite.in
index 5fae3d71ab64c55ca6a10c54f4800767b0e01df9..0a35be4b6673de8506584b8aadb09627a346a0a4 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.62 1997/12/03 22:46:18 hubbe Exp $"]])
+test_true([["$Id: testsuite.in,v 1.63 1998/01/03 07:12:11 hubbe Exp $"]])
 test_eq(1e1,10.0)
 test_eq(1E1,10.0)
 test_eq(1e+1,10.0)
@@ -396,20 +396,20 @@ test_eq(foo->i[0],17)
 test_do(add_constant("foo"));
 
 // signum, signame
-test_eq(signum("SIGKILL"),9)
-test_eq(signum("SIGINT"),2)
-test_eq(signame(9),"SIGKILL")
-test_eq(signame(2),"SIGINT")
+test_true(intp(signum("SIGKILL")))
 
 // kill, signal, getpid
 test_true(intp(getpid()))
-test_do(signal(signum("SIGFPE"),lambda() { add_constant("AFJLLAF",17); }))
-test_do(kill(getpid(),signum("SIGFPE")))
-test_do(sleep(2))
-test_eq(AFJLLAF,17)
-test_do(add_constant("AFJLLAF"))
-test_do(signal(signum("SIGFPE",0)))
-test_do(signal(signum("SIGFPE")))
+cond([[all_constants()->kill]],
+[[
+  test_do(signal(signum("SIGFPE"),lambda() { add_constant("AFJLLAF",17); }))
+  test_do(kill(getpid(),signum("SIGFPE")))
+  test_do(sleep(2))
+  test_eq(AFJLLAF,17)
+  test_do(add_constant("AFJLLAF"))
+  test_do(signal(signum("SIGFPE",0)))
+  test_do(signal(signum("SIGFPE")))
+]])
 
 // typeof
 test_eq(typeof(1),"int")
diff --git a/src/threads.c b/src/threads.c
index f9d9a8691b9832e5807deac3ae000a7560ccdbf5..6221538f632125e77b9d170618a19675300d81ae 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.49 1998/01/02 08:18:43 hubbe Exp $");
+RCSID("$Id: threads.c,v 1.50 1998/01/03 07:12:12 hubbe Exp $");
 
 int num_threads = 1;
 int threads_disabled = 0;
@@ -15,6 +15,74 @@ int threads_disabled = 0;
 #include "program.h"
 #include "gc.h"
 
+#ifdef SIMULATE_COND_WITH_EVENT
+int co_wait(COND_T *c, MUTEX_T *m)
+{
+  struct cond_t_queue me;
+  event_init(&me.event);
+  mt_lock(& c->lock);
+
+  me.next=c->tail;
+  c->tail=&me;
+  if(!c->head) c->head=&me;
+
+  mt_unlock(& c->lock);
+  mt_unlock(m);
+  event_wait(&me.event);
+  mt_lock(m);
+
+  event_destroy(& me.event);
+  /* Cancellation point?? */
+
+  return 0;
+}
+
+int co_signal(COND_T *c)
+{
+  struct cond_t_queue *t;
+  mt_lock(& c->lock);
+  if(t=c->head)
+  {
+    c->head=t->next;
+    t->next=0;
+    if(!c->head) c->tail=0;
+  }
+  mt_unlock(& c->lock);
+  if(t)
+    event_signal(& t->event);
+  return 0;
+}
+
+int co_broadcast(COND_T *c)
+{
+  struct cond_t_queue *t,*n;
+  mt_lock(& c->lock);
+  n=c->head;
+  c->head=c->tail=0;
+  mt_unlock(& c->lock);
+
+  while((t=n))
+  {
+    n=t->next;
+    event_signal(& t->event);
+  }
+
+  return 0;
+}
+
+int co_destroy(COND_T *c)
+{
+  struct cond_t_queue *t;
+  mt_lock(& c->lock);
+  n=c->head;
+  c->head=c->tail=0;
+  if(t) return EBUSY;
+  return 0;
+}
+
+#endif
+
+
 #define THIS_THREAD ((struct thread_state *)fp->current_storage)
 
 struct object *thread_id;
diff --git a/src/threads.h b/src/threads.h
index a857e23579d143375776423088dc64e5e4b9d0fe..4e3866d7e18b475ef225113adfdcf447d59dd184 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -155,21 +155,58 @@ extern struct object *thread_id;
 #ifdef NT_THREADS
 #include <process.h>
 
-#define MUTEX_T HANDLE
-#define mt_init(X)
-#define mt_lock(X)
-#define mt_trylock(X)
-#define mt_unlock(X)
-#define mt_destroy(X)
-
 #define THREAD_T HANDLE
 #define th_setconcurrency(X)
 #define th_create(ID,fun,arg)  _beginthreadex(NULL, 2*1024*1024, fun, arg, 0, ID)
 #define th_exit(foo) _endthreadex(foo)
-#define th_self() 
+#define th_self() GetCurrentThread()
+#define th_destroy(X) CloseHandle(*(X))
+#define th_yield() Sleep(0)
+
+#define MUTEX_T HANDLE
+#define mt_init(X) (*(X)=CreateMutex(NULL, 0, NULL))
+#define mt_lock(X) WaitForSingleObject(*(X), INFINITE)
+#define mt_trylock(X) WaitForSingleObject(*(X), 0)
+#define mt_unlock(X) ReleaseMutex(*(X))
+#define mt_destroy(X) CloseHandle(*(X))
+
+#define EVENT_T HANDLE
+#define event_init(X) (*(X)=CreateEvent(NULL, 1, 0, NULL))
+#define event_signal(X) SetEvent(*(X))
+#define event_destroy(X) CloseHandle(*(X))
+#define event_wait(X) WaitForSingleObject(*(X), INFINITE) 
 
 #endif
 
+
+#if !defined(COND_T) && defined(EVENT_T) && defined(MUTEX_T)
+
+#define SIMULATE_COND_WITH_EVENT
+
+struct cond_t_queue
+{
+  struct cond_t_queue *next;
+  EVENT_T event;
+};
+
+struct cond_t_s
+{
+  MUTEX_T lock;
+  struct cond_t_queue *head, *tail
+} COND_T;
+
+#define COND_T struct cond_t_s
+
+#define co_init(X) mt_init(& (X)->lock)
+
+int co_wait(COND_T *c, MUTEX_T *m);
+int co_signal(COND_T *c);
+int co_broadcast(COND_T *c);
+int co_destroy(COND_T *c);
+
+#endif
+
+
 extern MUTEX_T interpreter_lock;
 
 
@@ -195,6 +232,14 @@ struct thread_state {
   struct object * thread_id;
 };
 
+#ifndef th_destroy
+#define th_destroy(X)
+#endif
+
+#ifndef th_yield
+#define th_yield()
+#endif
+
 /* Define to get a debug-trace of some of the threads operations. */
 /* #define VERBOSE_THREADS_DEBUG */