[pypy-svn] r62817 - in pypy/trunk/pypy: rlib rpython/module rpython/module/test

afa at codespeak.net afa at codespeak.net
Tue Mar 10 16:53:18 CET 2009


Author: afa
Date: Tue Mar 10 16:53:17 2009
New Revision: 62817

Added:
   pypy/trunk/pypy/rpython/module/test/test_ll_os_stat.py
Modified:
   pypy/trunk/pypy/rlib/rwin32.py
   pypy/trunk/pypy/rpython/module/ll_os_stat.py
Log:
The llinterpreter has trouble when passing strings,
but we can still execute the fake implementation directly.

and While we're at it, fix one test in test_os.py,
when os.stat is applied to a locked file:
CPython falls back to reading the directory entry.


Modified: pypy/trunk/pypy/rlib/rwin32.py
==============================================================================
--- pypy/trunk/pypy/rlib/rwin32.py	(original)
+++ pypy/trunk/pypy/rlib/rwin32.py	Tue Mar 10 16:53:17 2009
@@ -64,6 +64,7 @@
     HANDLE = rffi.ULONG
     LPHANDLE = rffi.CArrayPtr(HANDLE)
     HMODULE = HANDLE
+    INVALID_HANDLE_VALUE = rffi.cast(HANDLE, -1)
     PFILETIME = rffi.CArrayPtr(FILETIME)
 
     GetLastError = winexternal('GetLastError', [], DWORD)

Modified: pypy/trunk/pypy/rpython/module/ll_os_stat.py
==============================================================================
--- pypy/trunk/pypy/rpython/module/ll_os_stat.py	(original)
+++ pypy/trunk/pypy/rpython/module/ll_os_stat.py	Tue Mar 10 16:53:17 2009
@@ -309,6 +309,8 @@
             'FILE_ATTRIBUTE_DIRECTORY')
         FILE_ATTRIBUTE_READONLY = platform.ConstantInteger(
             'FILE_ATTRIBUTE_READONLY')
+        ERROR_SHARING_VIOLATION = platform.ConstantInteger(
+            'ERROR_SHARING_VIOLATION')
         _S_IFDIR = platform.ConstantInteger('_S_IFDIR')
         _S_IFREG = platform.ConstantInteger('_S_IFREG')
 
@@ -333,6 +335,16 @@
              ('ftLastAccessTime', rwin32.FILETIME),
              ('ftLastWriteTime', rwin32.FILETIME)])
 
+        WIN32_FIND_DATA = platform.Struct(
+            'WIN32_FIND_DATAA',
+            # Only interesting fields
+            [('dwFileAttributes', rwin32.DWORD),
+             ('nFileSizeHigh', rwin32.DWORD),
+             ('nFileSizeLow', rwin32.DWORD),
+             ('ftCreationTime', rwin32.FILETIME),
+             ('ftLastAccessTime', rwin32.FILETIME),
+             ('ftLastWriteTime', rwin32.FILETIME)])
+
     globals().update(platform.configure(CConfig))
     GET_FILEEX_INFO_LEVELS = rffi.ULONG # an enumeration
 
@@ -349,6 +361,18 @@
         rwin32.BOOL,
         calling_conv='win')
 
+    FindFirstFile = rffi.llexternal(
+        'FindFirstFileA',
+        [rffi.CCHARP, lltype.Ptr(WIN32_FIND_DATA)],
+        rwin32.HANDLE,
+        calling_conv='win')
+
+    FindClose = rffi.llexternal(
+        'FindClose',
+        [rwin32.HANDLE],
+        rwin32.BOOL,
+        calling_conv='win')
+
     def attributes_to_mode(attributes):
         m = 0
         if attributes & FILE_ATTRIBUTE_DIRECTORY:
@@ -384,9 +408,9 @@
         result = (st_mode,
                   0, 0, 0, 0, 0,
                   st_size,
-                  atime + atime_ns * 1e-9,
-                  mtime + mtime_ns * 1e-9,
-                  ctime + ctime_ns * 1e-9)
+                  float(atime) + atime_ns * 1e-9,
+                  float(mtime) + mtime_ns * 1e-9,
+                  float(ctime) + ctime_ns * 1e-9)
 
         return make_stat_result(result)
 
@@ -411,14 +435,33 @@
 
         return make_stat_result(result)
 
+    def attributes_from_dir(l_path, data):
+        filedata = lltype.malloc(WIN32_FIND_DATA, flavor='raw')
+        hFindFile = FindFirstFile(l_path, filedata)
+        if hFindFile == rwin32.INVALID_HANDLE_VALUE:
+            return 0
+        FindClose(hFindFile)
+        data.c_dwFileAttributes = filedata.c_dwFileAttributes
+        rffi.structcopy(data.c_ftCreationTime, filedata.c_ftCreationTime)
+        rffi.structcopy(data.c_ftLastAccessTime, filedata.c_ftLastAccessTime)
+        rffi.structcopy(data.c_ftLastWriteTime, filedata.c_ftLastWriteTime)
+        data.c_nFileSizeHigh    = filedata.c_nFileSizeHigh
+        data.c_nFileSizeLow     = filedata.c_nFileSizeLow
+        return 1
+
     def win32_stat_llimpl(path):
         data = lltype.malloc(WIN32_FILE_ATTRIBUTE_DATA, flavor='raw')
         try:
             l_path = rffi.str2charp(path)
             res = GetFileAttributesEx(l_path, GetFileExInfoStandard, data)
+            errcode = rwin32.GetLastError()
+            if res == 0:
+                if errcode == ERROR_SHARING_VIOLATION:
+                    res = attributes_from_dir(l_path, data)
+                    errcode = rwin32.GetLastError()
             rffi.free_charp(l_path)
             if res == 0:
-                raise WindowsError(rwin32.GetLastError(), "os_stat failed")
+                raise WindowsError(errcode, "os_stat failed")
             return attribute_data_to_stat(data)
         finally:
             lltype.free(data, flavor='raw')

Added: pypy/trunk/pypy/rpython/module/test/test_ll_os_stat.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/rpython/module/test/test_ll_os_stat.py	Tue Mar 10 16:53:17 2009
@@ -0,0 +1,17 @@
+from pypy.rpython.module import ll_os_stat
+import sys, os
+import py
+
+class TestWin32Implementation:
+    def setup_class(cls):
+        if sys.platform != 'win32':
+            py.test.skip("win32 specific tests")
+
+    def test_stat(self):
+        stat = ll_os_stat.win32_stat_llimpl
+        def check(f):
+            assert stat(f).st_mtime == os.stat(f).st_mtime
+
+        check('c:/')
+        check('c:/temp')
+        check('c:/pagefile.sys')



More information about the Pypy-commit mailing list