diff --git a/src/fdlib.c b/src/fdlib.c
index 6df4029196c279580ac66dd839a45d92f461b81f..e587fedc9ddff931a9951b9454973a6bb297dbd1 100644
--- a/src/fdlib.c
+++ b/src/fdlib.c
@@ -3,7 +3,7 @@
 #include "error.h"
 #include <math.h>
 
-RCSID("$Id: fdlib.c,v 1.24 1999/05/13 07:25:41 hubbe Exp $");
+RCSID("$Id: fdlib.c,v 1.25 1999/05/19 14:24:19 mirar Exp $");
 
 #ifdef HAVE_WINSOCK_H
 
@@ -517,6 +517,30 @@ long debug_fd_lseek(FD fd, long pos, int where)
   return ret;
 }
 
+long debug_fd_ftruncate(FD fd, long len)
+{
+  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);
+
+  would you mind filling this one out? /Mirar
+
+  ret=i dont know((HANDLE)ret, len);
+  if(ret == 0xffffffff)
+  {
+    errno=GetLastError();
+    return -1;
+  }
+  return ret;
+}
+
 int debug_fd_flock(FD fd, int oper)
 {
   long ret;
diff --git a/src/fdlib.h b/src/fdlib.h
index c96e0ecd0f4e057c8ecb0880dc957a0843694040..ef25e897e0b2d2acaba5901ff2d12ac46dc34071 100644
--- a/src/fdlib.h
+++ b/src/fdlib.h
@@ -1,5 +1,5 @@
 /*
- * $Id: fdlib.h,v 1.23 1999/05/13 17:48:26 grubba Exp $
+ * $Id: fdlib.h,v 1.24 1999/05/19 14:24:20 mirar Exp $
  */
 #ifndef FDLIB_H
 #define FDLIB_H
@@ -87,6 +87,7 @@ typedef int FD;
 #define fd_write(fd,X,Y) debug_fd_write(dmalloc_touch_fd(fd),(X),(Y))
 #define fd_read(fd,X,Y) debug_fd_read(dmalloc_touch_fd(fd),(X),(Y))
 #define fd_lseek(fd,X,Y) debug_fd_lseek(dmalloc_touch_fd(fd),(X),(Y))
+#define fd_ftruncate(fd,X,Y) debug_fd_ftruncate(dmalloc_touch_fd(fd),(X),(Y))
 #define fd_flock(fd,X) debug_fd_flock(dmalloc_touch_fd(fd),(X))
 #define fd_fstat(fd,X) debug_fd_fstat(dmalloc_touch_fd(fd),(X))
 #define fd_select debug_fd_select /* fixme */
@@ -119,6 +120,7 @@ int debug_fd_close(FD fd);
 long debug_fd_write(FD fd, void *buf, long len);
 long debug_fd_read(FD fd, void *to, long len);
 long debug_fd_lseek(FD fd, long pos, int where);
+long debug_fd_ftruncate(FD fd, long len);
 int debug_fd_flock(FD fd, int oper);
 int debug_fd_fstat(FD fd, struct stat *s);
 int debug_fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t);
@@ -269,6 +271,7 @@ typedef int FD;
 #define fd_write(fd,X,Y) write(dmalloc_touch_fd(fd),(X),(Y))
 #define fd_read(fd,X,Y) read(dmalloc_touch_fd(fd),(X),(Y))
 #define fd_lseek(fd,X,Y) lseek(dmalloc_touch_fd(fd),(X),(Y))
+#define fd_ftruncate(fd,X) ftruncate(dmalloc_touch_fd(fd),(X))
 #define fd_fstat(fd,X) fstat(dmalloc_touch_fd(fd),(X))
 #define fd_select select /* fixme */
 #define fd_ioctl(fd,X,Y) ioctl(dmalloc_touch_fd(fd),(X),(Y))
diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index 82e39f98f4d97d3a6bfc0be21537fc0f97709594..b320c1d52add0512a2bddda19ca1a487ec89e1e8 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -1,4 +1,4 @@
-# $Id: configure.in,v 1.65 1999/05/18 17:08:11 mirar Exp $
+# $Id: configure.in,v 1.66 1999/05/19 14:23:25 mirar Exp $
 AC_INIT(file.c)
 AC_CONFIG_HEADER(file_machine.h)
 
@@ -430,6 +430,7 @@ if test x$ac_cv_func_statvfs = xyes ; then
     if test x$pike_cv_struct_statfs_f_fstr = xyes; then
       AC_DEFINE(HAVE_STATVFS_F_FSTR)
     else :; fi
+    AC_MSG_CHECKING(if the struct statfs has the member f_basetype)
     AC_CACHE_VAL(pike_cv_struct_statvfs_f_basetype, [
       AC_TRY_COMPILE([
 #ifndef _LARGEFILE_SOURCE
diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c
index 7c9a14adda3227e330e632ea5398edb3d3014f93..aa518b2f0905986bda91ca650111dd0ecc600d10 100644
--- a/src/modules/files/efuns.c
+++ b/src/modules/files/efuns.c
@@ -24,7 +24,7 @@
 #include "file_machine.h"
 #include "file.h"
 
-RCSID("$Id: efuns.c,v 1.68 1999/04/05 22:07:38 hubbe Exp $");
+RCSID("$Id: efuns.c,v 1.69 1999/05/19 14:23:26 mirar Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -138,6 +138,35 @@ void f_file_stat(INT32 args)
     push_array(encode_stat(&st));
   }
 }
+
+void f_file_truncate(INT32 args)
+{
+#ifdef HAVE_LSEEK64
+  long long len;
+#else
+  INT32 len;
+#endif
+  char *s;
+  int res;
+
+  if(args<1 || sp[-args].type != T_STRING)
+    error("Bad argument 1 to file_truncate(string filename,int length).\n");
+  if(args<2 || sp[1-args].type != T_INT)
+    error("Bad argument 2 to file_truncate(string filename,int length).\n");
+
+  s = sp[-args].u.string->str;
+  len = sp[1-args].u.integer;
+
+  VALID_FILE_IO("file_truncate","write");
+
+  res=truncate(s,len);
+  // NT: fixme?  /Mirar
+
+  pop_n_elems(args);
+
+  push_int(!res);
+}
+
 #ifdef __NT__
 
 void f_filesystem_stat( INT32 args )
@@ -916,6 +945,10 @@ void init_files_efuns(void)
   
 /* function(string,int|void:int *) */
   ADD_EFUN("file_stat",f_file_stat,tFunc(tStr tOr(tInt,tVoid),tArr(tInt)), OPT_EXTERNAL_DEPEND);
+
+  ADD_EFUN("file_truncate",f_file_truncate,tFunc(tStr tInt,tInt),0);
+
+
 #if defined(HAVE_STATVFS) || defined(HAVE_STATFS) || defined(HAVE_USTAT) || defined(__NT__)
   
 /* function(string:mapping(string:string|int)) */
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 30a83117b278d1eb1b892c3895638c2e24e7fdc4..3281e764990f872800e053a5b25dde3a2c5a8b9f 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: file.c,v 1.155 1999/05/17 20:29:40 hubbe Exp $");
+RCSID("$Id: file.c,v 1.156 1999/05/19 14:23:28 mirar Exp $");
 #include "fdlib.h"
 #include "interpret.h"
 #include "svalue.h"
@@ -1407,6 +1407,34 @@ static void file_tell(INT32 args)
   push_int(to);
 }
 
+static void file_truncate(INT32 args)
+{
+#ifdef HAVE_LSEEK64
+  long long len;
+#else
+  INT32 len;
+#endif
+  int res;
+
+  if(args<1 || sp[-args].type != T_INT)
+    error("Bad argument 1 to file->truncate(int length).\n");
+
+  if(FD < 0)
+    error("File not open.\n");
+
+  len = sp[-args].u.integer;
+  
+  ERRNO=0;
+  res=fd_ftruncate(FD, len);
+
+  pop_n_elems(args);
+
+  if(res<0) 
+     ERRNO=errno;
+
+  push_int(!res);
+}
+
 struct array *encode_stat(struct stat *);
 
 static void file_stat(INT32 args)
diff --git a/src/modules/files/file_functions.h b/src/modules/files/file_functions.h
index 689e94bf28b2f4263f4b81f9bdf9a46ed33ee8a3..5dd0a28676ab53c19302dc846a334e256b18cfac 100644
--- a/src/modules/files/file_functions.h
+++ b/src/modules/files/file_functions.h
@@ -12,6 +12,7 @@
 
   FILE_FUNC("seek",file_seek,"function(int,int|void,int|void:int)")
   FILE_FUNC("tell",file_tell,"function(:int)")
+  FILE_FUNC("truncate",file_truncate,"function(int:int)");
   FILE_FUNC("stat",file_stat,"function(:int *)")
   FILE_FUNC("errno",file_errno,"function(:int)")
   FILE_FUNC("mode",file_mode,"function(:int)")
diff --git a/tutorial/tutorial.wmml b/tutorial/tutorial.wmml
index 07a320dfd71e2464c833828eb03c2e7d2321df7a..eb279963438ad142149a964396deb6261aacfeda 100644
--- a/tutorial/tutorial.wmml
+++ b/tutorial/tutorial.wmml
@@ -3705,6 +3705,18 @@ Returns the current position in the file.
 </method>
 
 
+<method name=truncate title="truncate a file">
+<man_syntax>
+int truncate(int length);<br>
+</man_syntax>
+<man_description>
+Truncates a file to that length.
+Returns 1 if ok, 0 if failed.
+</man_description>
+<man_see>Stdio.File-&gt;open</man_see>
+</method>
+
+
 <method name=stat title="do file_stat on an open file">
 <man_syntax>
 array(int) stat();<br>
@@ -11137,6 +11149,19 @@ You can never get -3 as size if you don't give a second argument.<br>
 <man_see>get_dir</man_see>
 </function>
 
+<HR NEWPAGE>
+
+<function name=file_truncate title="truncate a file" fullpath>
+<man_syntax>
+int file_truncate(string <I>file</I>,int <I>length</I>);<br>
+</man_syntax>
+<man_description>
+Truncates a file to that length.
+Returns 1 if ok, 0 if failed.
+</man_description>
+</function>
+
+
 <HR NEWPAGE>
 
 <function name=find_call_out title="find a call out in the queue">