diff --git a/lib/modules/Stdio.pmod b/lib/modules/Stdio.pmod
index cbef6ab082a96be50ec5aafd7343591c311317a6..c20ca74f231a4884c4471c61679c854c0247c666 100644
--- a/lib/modules/Stdio.pmod
+++ b/lib/modules/Stdio.pmod
@@ -1,4 +1,4 @@
-// $Id: Stdio.pmod,v 1.30 1998/07/19 03:24:09 hubbe Exp $
+// $Id: Stdio.pmod,v 1.31 1998/07/26 10:25:02 hubbe Exp $
 
 #include <string.h>
 
@@ -29,6 +29,9 @@ class File
   int open(string file, string mode, void|int bits)
   {
     _fd=Fd();
+#ifdef __STDIO_DEBUG
+    __closed_backtrace=0;
+#endif
     if(query_num_arg()<3) bits=0666;
     return ::open(file,mode,bits);
   }
@@ -36,6 +39,9 @@ class File
   int open_socket(int|void port, string|void address)
   {
     _fd=Fd();
+#ifdef __STDIO_DEBUG
+    __closed_backtrace=0;
+#endif
     switch(query_num_arg()) {
     case 0:
       return ::open_socket();
@@ -49,12 +55,18 @@ class File
   int connect(string host, int port)
   {
     if(!_fd) _fd=Fd();
+#ifdef __STDIO_DEBUG
+    __closed_backtrace=0;
+#endif
     return ::connect(host,port);
   }
 
   object(File) pipe(void|int how)
   {
     _fd=Fd();
+#ifdef __STDIO_DEBUG
+    __closed_backtrace=0;
+#endif
     if(query_num_arg()==0)
       how=PROP_NONBLOCK | PROP_BIDIRECTIONAL;
     if(object(Fd) fd=::pipe(how))
@@ -73,55 +85,83 @@ class File
     {
       case "stdin":
 	_fd=_stdin;
+#ifdef __STDIO_DEBUG
+	__closed_backtrace=0;
+#endif
       case 0:
 	break;
 	
       case "stdout":
 	_fd=_stdout;
+#ifdef __STDIO_DEBUG
+	__closed_backtrace=0;
+#endif
 	break;
 	
       case "stderr":
 	_fd=_stderr;
+#ifdef __STDIO_DEBUG
+	__closed_backtrace=0;
+#endif
 	break;
 	
       default:
 	_fd=Fd();
+#ifdef __STDIO_DEBUG
+	__closed_backtrace=0;
+#endif
 	if(query_num_arg()<3) bits=0666;
 	::open(file,mode,bits);
     }
   }
 
-  // Don't allow overloading of this function.
-  static private nomask int do_assign(object to, object from)
+  int assign(object o)
   {
-    if((program)Fd == (program)object_program(from))
+    if((program)Fd == (program)object_program(o))
     {
-      to->_fd = from->dup();
+      _fd = o->dup();
     }else{
-      to->_fd = from->_fd;
-      to->___read_callback = from->___read_callback;
-      to->___write_callback = from->___write_callback;
-      to->___close_callback = from->___close_callback;
+      _fd = o->_fd;
+      if(___read_callback = o->___read_callback)
+	_fd->_read_callback=__stdio_read_callback;
+
+      if(___write_callback = o->___write_callback)
+	_fd->_write_callback=__stdio_write_callback;
+
+      ___close_callback = o->___close_callback;
 #if constant(__HAVE_OOB__)_
-      to->___read_oob_callback = from->___read_oob_callback;
-      to->___write_oob_callback = from->___write_oob_callback;
+      if(___read_oob_callback = o->___read_oob_callback)
+	_fd->_read_oob_callback = __stdio_read_oob_callbac;
+
+      if(___write_oob_callback = o->___write_oob_callback)
+	_fd->_write_oob_callback = __stdio_write_oob_callbac;
 #endif
-      to->___id = from->___id;
+      ___id = o->___id;
+      
     }
     return 0;
   }
 
-  int assign(object o)
-  {
-    return do_assign(this_object(), o);
-  }
-
   object dup()
   {
-    object o;
-    o = File();
-    do_assign(o, this_object());
-    return o;
+    object to = File();
+    to->_fd = _fd;
+    if(to->___read_callback = ___read_callback)
+      _fd->_read_callback=to->__stdio_read_callback;
+
+    if(to->___write_callback = ___write_callback)
+      _fd->_write_callback=to->__stdio_write_callback;
+
+    to->___close_callback = ___close_callback;
+#if constant(__HAVE_OOB__)_
+    if(to->___read_oob_callback = ___read_oob_callback)
+      _fd->_read_oob_callback=to->__stdio_read_oob_callback;
+
+    if(to->___write_oob_callback = ___write_oob_callback)
+      _fd->_write_oob_callback=to->__stdio_write_oob_callback;
+#endif
+    to->___id = ___id;
+    return to;
   }
 
 
@@ -146,7 +186,7 @@ class File
 #endif
   }
 
-  static void my_read_callback()
+  static void __stdio_read_callback()
   {
 #if defined(__STDIO_DEBUG) && !defined(__NT__)
     if(!::peek())
@@ -162,10 +202,10 @@ class File
     }
   }
 
-  static void my_write_callback() { ___write_callback(___id); }
+  static void __stdio_write_callback() { ___write_callback(___id); }
 
 #if constant(__HAVE_OOB__)_
-  static void my_read_oob_callback()
+  static void __stdio_read_oob_callback()
   {
     string s=::read_oob(8192,1);
     if(s && strlen(s))
@@ -176,10 +216,11 @@ class File
     }
   }
 
-  static void my_write_oob_callback() { ___write_oob_callback(___id); }
+  static void __stdio_write_oob_callback() { ___write_oob_callback(___id); }
 #endif
 
-#define SET(X,Y) ::set_##X ((___##X = (Y)) && my_##X)
+#define SET(X,Y) ::set_##X ((___##X = (Y)) && __stdio_##X)
+#define _SET(X,Y) do { _##X=__stdio_##X; ___##X = (Y); }while(0)
 
 #define CBFUNC(X)					\
   void set_##X (mixed l##X)				\
@@ -225,15 +266,30 @@ class File
       
     }
 #endif
-    SET(read_callback,rcb);
-    SET(write_callback,wcb);
+    ::_disable_callbacks(); // Thread safing
+
+    _SET(read_callback,rcb);
+    _SET(write_callback,wcb);
     ___close_callback=ccb;
 
 #if constant(__HAVE_OOB__)_
-    SET(read_oob_callback,roobcb);
-    SET(write_oob_callback,woobcb);
+    _SET(read_oob_callback,roobcb);
+    _SET(write_oob_callback,woobcb);
 #endif
+#ifdef __STDIO_DEBUG
+    if(mixed x=catch { ::set_nonblocking(); })
+    {
+      x[0]+=(__closed_backtrace ? 
+	   sprintf("File was closed from:\n    %-=200s\n",__closed_backtrace) :
+	   "This file has never been open.\n" )+
+	(_fd?"_fd is nonzero\n":"_fd is zero\n");
+      throw(x);
+    }
+#else
     ::set_nonblocking();
+#endif
+    ::_enable_callbacks();
+
   }
 
   void set_blocking()