[pypy-commit] pypy use-file-star-for-file: fix ftruncate on win32

bdkearns noreply at buildbot.pypy.org
Tue Sep 16 19:35:14 CEST 2014


Author: Brian Kearns <bdkearns at gmail.com>
Branch: use-file-star-for-file
Changeset: r73556:43946fb28835
Date: 2014-09-16 10:34 -0700
http://bitbucket.org/pypy/pypy/changeset/43946fb28835/

Log:	fix ftruncate on win32

diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -13,6 +13,8 @@
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 
 MS_WINDOWS = os.name == 'nt'
+if MS_WINDOWS:
+    from rpython.rlib.rwin32 import _get_osfhandle, SetEndOfFile, INVALID_HANDLE_VALUE
 
 includes = ['stdio.h', 'sys/types.h']
 if os.name == "posix":
@@ -612,11 +614,25 @@
         if res != 0:
             c_clearerr(ll_file)
             raise _from_errno(IOError)
-        # XXX use fseek/SetEndOfFile on windows
-        res = c_ftruncate(c_fileno(ll_file), arg)
-        if res != 0:
-            c_clearerr(ll_file)
-            raise _from_errno(IOError)
+        if MS_WINDOWS:
+            ret = c_fseek(ll_file, arg, os.SEEK_SET)
+            if ret:
+                c_clearerr(ll_file)
+                raise _from_errno(IOError)
+            handle = _get_osfhandle(c_fileno(ll_file))
+            ret = handle == INVALID_HANDLE_VALUE
+            if ret == 0:
+                ret = SetEndOfFile(handle) == 0
+                if ret:
+                    rposix.set_errno(errno.EACCES)
+            if ret:
+                c_clearerr(ll_file)
+                raise _from_errno(IOError)
+        else:
+            ret = c_ftruncate(c_fileno(ll_file), arg)
+            if ret != 0:
+                c_clearerr(ll_file)
+                raise _from_errno(IOError)
         res = c_fseek(ll_file, pos, os.SEEK_SET)
         if res != 0:
             c_clearerr(ll_file)
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -154,6 +154,8 @@
             raise WindowsError(ERROR_INVALID_HANDLE, "Invalid file handle")
         return handle
 
+    SetEndOfFile = rffi.llexternal('SetEndOfFile', [HANDLE], BOOL)
+
     def build_winerror_to_errno():
         """Build a dictionary mapping windows error numbers to POSIX errno.
         The function returns the dict, and the default value for codes not
diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py
--- a/rpython/rlib/streamio.py
+++ b/rpython/rlib/streamio.py
@@ -188,15 +188,13 @@
 
 
 if sys.platform == "win32":
-    from rpython.rlib.rwin32 import BOOL, HANDLE, get_osfhandle, GetLastError
+    from rpython.rlib.rwin32 import get_osfhandle, GetLastError, SetEndOfFile
     from rpython.translator.tool.cbuild import ExternalCompilationInfo
     from rpython.rtyper.lltypesystem import rffi
 
     _eci = ExternalCompilationInfo()
     _setmode = rffi.llexternal('_setmode', [rffi.INT, rffi.INT], rffi.INT,
                                compilation_info=_eci)
-    SetEndOfFile = rffi.llexternal('SetEndOfFile', [HANDLE], BOOL,
-                                   compilation_info=_eci)
 
     def _setfd_binary(fd):
         # Allow this to succeed on invalid fd's


More information about the pypy-commit mailing list