diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index deb96b9132c61d60a6ecf467ee9809a0ee3237b7..2a1cdf33d05653a18470d7416512835c27b2495c 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -13,7 +13,7 @@ if test "$ac_cv_lib_socket" = yes -o "${ac_cv_lib_ucb}" = yes; then
  AC_CHECK_LIB(nsl, main)
 fi
 
-AC_HAVE_FUNCS(socketpair getwd)
+AC_HAVE_FUNCS(socketpair getwd strerror)
 
 AC_MSG_CHECKING(size of socket buffers)
 AC_CACHE_VAL(lpc_cv_socket_buffer_max,
diff --git a/src/modules/files/doc/strerror b/src/modules/files/doc/strerror
new file mode 100644
index 0000000000000000000000000000000000000000..bcb7a061204ef821538f8e7ded0c0b0024ee3b1f
--- /dev/null
+++ b/src/modules/files/doc/strerror
@@ -0,0 +1,15 @@
+NAME
+	strerror - return a string describing an error
+
+SYNTAX
+	string strerror(int errno);
+
+DESCRIPTION
+	This function returns a description of an error code. The error
+	code is usually obtained from the file->errno() call.
+
+KEYWORDS
+	file
+
+NOTA BENE
+	This function may not be available on all platforms.
diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c
index d5ba2293684bc49d1a10104dd71c2eb34a3f1238..09b389f622df249d6f862c2a32acd4f94aae04a7 100644
--- a/src/modules/files/efuns.c
+++ b/src/modules/files/efuns.c
@@ -342,6 +342,25 @@ void f_mv(INT32 args)
   push_int(!i);
 }
 
+#ifdef HAVE_STRERROR
+void f_strerror(INT32 args)
+{
+  char *s;
+
+  if(!args) 
+    error("Too few arguments to strerror()\n");
+  if(sp[-args].type != T_INT)
+    error("Bad argument 1 to strerror()\n");
+
+  s=strerror(sp[-args].u.integer);
+  pop_n_elems(args);
+  if(s)
+    push_text(s);
+  else
+    push_int(0);
+}
+#endif
+
 void init_files_efuns()
 {
   set_close_on_exec(0,1);
@@ -359,4 +378,8 @@ void init_files_efuns()
   add_efun("getcwd",f_getcwd,"function(:string)",OPT_EXTERNAL_DEPEND);
   add_efun("fork",f_fork,"function(:int)",OPT_SIDE_EFFECT);
   add_efun("exece",f_exece,"function(string,mixed*,void|mapping(string:string):int)",OPT_SIDE_EFFECT); 
+
+#ifdef HAVE_STRERROR
+  add_efun("strerror",f_strerror,"function(int:string)",0);
+#endif
 }
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 372c47658cfa7cfdf77632cddbd8a378f2b7833f..85aca57d8cc26c6200e24406c02813cab9a8225c 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -20,6 +20,7 @@
 #include "file.h"
 #include "error.h"
 #include "lpc_signal.h"
+#include "lpc_types.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1144,6 +1145,27 @@ static void file_query_address(INT32 args)
   push_string(make_shared_string(buffer));
 }
 
+static void file_lsh(INT32 args)
+{
+  INT32 len;
+  if(args != 1)
+    error("Too few/many args to file->`<<\n");
+
+  if(sp[-1].type != T_STRING)
+  {
+    push_string(string_type_string);
+    string_type_string->refs++;
+    f_cast();
+  }
+
+  len=sp[-1].u.string->len;
+  file_write(1);
+  if(len != sp[-1].u.integer) error("File << failed.\n");
+  pop_stack();
+
+  push_object(this_object());
+}
+
 static void file_create(INT32 args)
 {
   char *s;
@@ -1221,6 +1243,7 @@ void init_files_programs()
   add_function("connect",file_connect,"function(string,int:int)",0);
   add_function("query_address",file_query_address,"function(int|void:int)",0);
   add_function("create",file_create,"function(void|string:void)",0);
+  add_function("`<<",file_lsh,"function(mixed:object)",0);
 
   set_init_callback(init_file_struct);
   set_exit_callback(exit_file_struct);
diff --git a/src/modules/files/file.h b/src/modules/files/file.h
index 76aace9fd8728cc45cd50fa250d1ea47491b7765..e7114ad62276378b306f6db773ae9b139ce9b999 100644
--- a/src/modules/files/file.h
+++ b/src/modules/files/file.h
@@ -37,6 +37,7 @@ struct my_file
 
 /* Prototypes begin here */
 struct object *file_make_object_from_fd(int fd, int mode);
+int socketpair(int family, int type, int protocol, int sv[2]);
 void get_inet_addr(struct sockaddr_in *addr,char *name);
 void exit_files();
 void init_files_programs();
diff --git a/src/modules/files/file_machine.h.in b/src/modules/files/file_machine.h.in
index 8564e516d2e9c6360b1322292888fde5d0acda74..9b3ee80b42461dfba665d430f631d90efc4bb19f 100644
--- a/src/modules/files/file_machine.h.in
+++ b/src/modules/files/file_machine.h.in
@@ -37,6 +37,9 @@
 /* Define if you have getwd.  */
 #undef HAVE_GETWD
 
+/* Define if you have strerror.  */
+#undef HAVE_STRERROR
+
 /* Define if you have a working getcwd */
 #undef HAVE_WORKING_GETCWD