[pypy-svn] r74738 - in pypy/trunk/pypy/rpython/module: . test

afa at codespeak.net afa at codespeak.net
Tue May 25 18:10:02 CEST 2010


Author: afa
Date: Tue May 25 18:10:00 2010
New Revision: 74738

Modified:
   pypy/trunk/pypy/rpython/module/ll_os_stat.py
   pypy/trunk/pypy/rpython/module/test/test_ll_os_stat.py
Log:
On Windows, make os.fstat() work on non-disk files, stdout for example.


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 May 25 18:10:00 2010
@@ -317,6 +317,11 @@
             'ERROR_SHARING_VIOLATION')
         _S_IFDIR = platform.ConstantInteger('_S_IFDIR')
         _S_IFREG = platform.ConstantInteger('_S_IFREG')
+        _S_IFCHR = platform.ConstantInteger('_S_IFCHR')
+        _S_IFIFO = platform.ConstantInteger('_S_IFIFO')
+        FILE_TYPE_UNKNOWN = platform.ConstantInteger('FILE_TYPE_UNKNOWN')
+        FILE_TYPE_CHAR = platform.ConstantInteger('FILE_TYPE_CHAR')
+        FILE_TYPE_PIPE = platform.ConstantInteger('FILE_TYPE_PIPE')
 
         WIN32_FILE_ATTRIBUTE_DATA = platform.Struct(
             'WIN32_FILE_ATTRIBUTE_DATA',
@@ -365,6 +370,12 @@
         rwin32.BOOL,
         calling_conv='win')
 
+    GetFileType = rffi.llexternal(
+        'GetFileType',
+        [rwin32.HANDLE],
+        rwin32.DWORD,
+        calling_conv='win')
+
     FindFirstFile = rffi.llexternal(
         'FindFirstFileA',
         [rffi.CCHARP, lltype.Ptr(WIN32_FIND_DATA)],
@@ -477,9 +488,29 @@
     win32_lstat_llimpl = win32_stat_llimpl
 
     def win32_fstat_llimpl(fd):
-        info = lltype.malloc(BY_HANDLE_FILE_INFORMATION, flavor='raw')
+        handle = rwin32._get_osfhandle(fd)
+
+        filetype = GetFileType(handle)
+        if filetype == FILE_TYPE_CHAR:
+            # console or LPT device
+            return make_stat_result((_S_IFCHR,
+                                     0, 0, 0, 0, 0,
+                                     0, 0, 0, 0))
+        elif filetype == FILE_TYPE_PIPE:
+            # socket or named pipe
+            return make_stat_result((_S_IFIFO,
+                                     0, 0, 0, 0, 0,
+                                     0, 0, 0, 0))
+        elif filetype == FILE_TYPE_UNKNOWN:
+            error = rwin32.GetLastError()
+            if error != 0:
+                raise WindowsError(error, "os_fstat failed")
+            # else: unknown but valid file
+
+        # normal disk file (FILE_TYPE_DISK)
+        info = lltype.malloc(BY_HANDLE_FILE_INFORMATION, flavor='raw',
+                             zero=True)
         try:
-            handle = rwin32._get_osfhandle(fd)
             res = GetFileInformationByHandle(handle, info)
             if res == 0:
                 raise WindowsError(rwin32.GetLastError(), "os_fstat failed")

Modified: pypy/trunk/pypy/rpython/module/test/test_ll_os_stat.py
==============================================================================
--- pypy/trunk/pypy/rpython/module/test/test_ll_os_stat.py	(original)
+++ pypy/trunk/pypy/rpython/module/test/test_ll_os_stat.py	Tue May 25 18:10:00 2010
@@ -15,3 +15,7 @@
         check('c:/')
         check('c:/temp')
         check('c:/pagefile.sys')
+
+    def test_fstat(self):
+        stat = ll_os_stat.win32_fstat_llimpl(0) # stdout
+        assert stat.st_mode != 0



More information about the Pypy-commit mailing list