Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: fileops2
Changeset: r67182:d55b0202cef0
Date: 2013-10-07 17:16 +0200
http://bitbucket.org/pypy/pypy/changeset/d55b0202cef0/

Log:    ftruncate

diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -6,18 +6,27 @@
 
 import os
 from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rtyper.tool import rffi_platform as platform
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 from rpython.rlib.rarithmetic import r_uint, intmask
 from rpython.rlib import rposix
 from rpython.rlib.rstring import StringBuilder
 
-eci = ExternalCompilationInfo(includes=['stdio.h'])
+eci = ExternalCompilationInfo(includes=['stdio.h', 'unistd.h', 'sys/types.h'])
 
 def llexternal(*args):
     return rffi.llexternal(*args, compilation_info=eci)
 
 FILE = lltype.Struct('FILE') # opaque type maybe
 
+class CConfig(object):
+    _compilation_info_ = eci
+
+    off_t = platform.SimpleType('off_t')
+
+CC = platform.configure(CConfig)
+OFF_T = CC['off_t']
+
 c_open = llexternal('fopen', [rffi.CCHARP, rffi.CCHARP], lltype.Ptr(FILE))
 c_close = llexternal('fclose', [lltype.Ptr(FILE)], rffi.INT)
 c_write = llexternal('fwrite', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T,
@@ -32,7 +41,8 @@
 c_tmpfile = llexternal('tmpfile', [], lltype.Ptr(FILE))
 c_fileno = llexternal('fileno', [lltype.Ptr(FILE)], rffi.INT)
 c_ftell = llexternal('ftell', [lltype.Ptr(FILE)], lltype.Signed)
-c_fflush = llexternal('fflush', [lltype.Ptr(FILE)], lltype.Signed)
+c_fflush = llexternal('fflush', [lltype.Ptr(FILE)], rffi.INT)
+c_ftruncate = llexternal('ftruncate', [rffi.INT, OFF_T], rffi.INT)
 
 BASE_BUF_SIZE = 4096
 
@@ -166,6 +176,17 @@
             return
         raise ValueError("I/O operation on closed file")
 
+    def truncate(self, arg=-1):
+        if self.ll_file:
+            if arg == -1:
+                arg = self.tell()
+            res = c_ftruncate(self.fileno(), arg)
+            if res == -1:
+                errno = rposix.get_errno()
+                raise OSError(errno, os.strerror(errno))
+            return
+        raise ValueError("I/O operation on closed file")
+
     def __del__(self):
         self.close()
 
diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py
--- a/rpython/rlib/test/test_rfile.py
+++ b/rpython/rlib/test/test_rfile.py
@@ -107,7 +107,7 @@
         assert res == 3
 
     def test_flush(self):
-        fname = str(self.tmpdir.join('file_trunc'))
+        fname = str(self.tmpdir.join('file_flush'))
 
         def f():
             f = open(fname, "w")
@@ -119,3 +119,19 @@
             f.close()
 
         self.interpret(f, [])
+
+    def test_truncate(self):
+        fname = str(self.tmpdir.join('file_trunc'))
+
+        def f():
+            f = open(fname, "w")
+            f.write("xyz")
+            f.seek(0)
+            f.truncate(2)
+            f.close()
+            f2 = open(fname)
+            assert f2.read() == "xy"
+            f2.close()
+
+        f()
+        self.interpret(f, [])
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to