[pypy-svn] r46268 - in pypy/branch/pypy-more-rtti-inprogress/rpython: lltypesystem module

arigo at codespeak.net arigo at codespeak.net
Mon Sep 3 13:40:27 CEST 2007


Author: arigo
Date: Mon Sep  3 13:40:26 2007
New Revision: 46268

Modified:
   pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py
   pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_os.py
Log:
Windozify listdir() and pipe().


Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py	Mon Sep  3 13:40:26 2007
@@ -96,6 +96,9 @@
 if os.name != 'nt':
     TYPES.append('mode_t')
     TYPES.append('pid_t')
+else:
+    MODE_T = lltype.Signed
+    PID_T = lltype.Signed
 
 def setup():
     """ creates necessary c-level types

Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_os.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_os.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_os.py	Mon Sep  3 13:40:26 2007
@@ -44,8 +44,6 @@
                            ('tms_cutime', rffi.INT),
                            ('tms_cstime', rffi.INT)])
 
-    NAME_MAX = platform.DefinedConstantInteger('NAME_MAX')
-
     SEEK_SET = platform.DefinedConstantInteger('SEEK_SET')
     SEEK_CUR = platform.DefinedConstantInteger('SEEK_CUR')
     SEEK_END = platform.DefinedConstantInteger('SEEK_END')
@@ -192,7 +190,7 @@
     @registering(os.times)
     def register_os_times(self):
         if sys.platform.startswith('win'):
-            HANDLE = rffi.LONG
+            HANDLE = rffi.ULONG
             FILETIME = rffi.CStruct('_FILETIME', ('dwLowDateTime', rffi.LONG),
                                                  ('dwHighDateTime', rffi.LONG))
             GetCurrentProcess = self.llexternal('GetCurrentProcess', [],
@@ -322,11 +320,7 @@
 
     @registering(os.open)
     def register_os_open(self):
-        if os.name == 'nt':
-            mode_t = rffi.INT
-        else:
-            mode_t = rffi.MODE_T
-        os_open = self.llexternal('open', [rffi.CCHARP, rffi.INT, mode_t],
+        os_open = self.llexternal('open', [rffi.CCHARP, rffi.INT, rffi.MODE_T],
                                   rffi.INT)
 
         def os_open_llimpl(path, flags, mode):
@@ -523,14 +517,80 @@
     def register_os_listdir(self):
         # we need a different approach on Windows and on Posix
         if sys.platform.startswith('win'):
-            XXX   # FindFirstFile, FindNextFile
-        else:
+            class CConfig:
+                _includes_ = ['windows.h']
+                WIN32_FIND_DATA = platform.Struct('struct _WIN32_FIND_DATAA',
+                    [('cFileName', lltype.FixedSizeArray(rffi.CHAR, 1))])
+                INVALID_HANDLE_VALUE = platform.ConstantInteger(
+                    'INVALID_HANDLE_VALUE')
+                ERROR_FILE_NOT_FOUND = platform.ConstantInteger(
+                    'ERROR_FILE_NOT_FOUND')
+                ERROR_NO_MORE_FILES = platform.ConstantInteger(
+                    'ERROR_NO_MORE_FILES')
+
+            config = platform.configure(CConfig)
+            WIN32_FIND_DATA      = config['WIN32_FIND_DATA']
+            INVALID_HANDLE_VALUE = config['INVALID_HANDLE_VALUE']
+            ERROR_FILE_NOT_FOUND = config['ERROR_FILE_NOT_FOUND']
+            ERROR_NO_MORE_FILES  = config['ERROR_NO_MORE_FILES']
+            LPWIN32_FIND_DATA    = lltype.Ptr(WIN32_FIND_DATA)
+            HANDLE               = rffi.ULONG
+            #MAX_PATH = WIN32_FIND_DATA.c_cFileName.length
+
+            GetLastError = self.llexternal('GetLastError', [], lltype.Signed)
+            FindFirstFile = self.llexternal('FindFirstFile',
+                                            [rffi.CCHARP, LPWIN32_FIND_DATA],
+                                            HANDLE)
+            FindNextFile = self.llexternal('FindNextFile',
+                                           [HANDLE, LPWIN32_FIND_DATA],
+                                           rffi.INT)
+            FindClose = self.llexternal('FindClose',
+                                        [HANDLE],
+                                        rffi.INT)
+
+            def os_listdir_llimpl(path):
+                if path and path[-1] not in ('/', '\\', ':'):
+                    path += '/'
+                path += '*.*'
+                filedata = lltype.malloc(WIN32_FIND_DATA, flavor='raw')
+                try:
+                    result = []
+                    hFindFile = FindFirstFile(path, filedata)
+                    if hFindFile == INVALID_HANDLE_VALUE:
+                        error = GetLastError()
+                        if error == ERROR_FILE_NOT_FOUND:
+                            return result
+                        else:
+                            # XXX guess error code :-(
+                            raise OSError(errno.ENOENT, "FindFirstFile failed")
+                    while True:
+                        name = rffi.charp2str(rffi.cast(rffi.CCHARP,
+                                                        filedata.c_cFileName))
+                        if name != "." and name != "..":   # skip these
+                            result.append(name)
+                        if not FindNextFile(hFindFile, filedata):
+                            break
+                    # FindNextFile sets error to ERROR_NO_MORE_FILES if
+                    # it got to the end of the directory
+                    error = GetLastError()
+                    FindClose(hFindFile)
+                    if error == ERROR_NO_MORE_FILES:
+                        return result
+                    else:
+                        # XXX guess error code :-(
+                        raise OSError(errno.EIO, "FindNextFile failed")
+                finally:
+                    lltype.free(filedata, flavor='raw')
+
+        else:
+            class CConfig:
+                DIRENT = platform.Struct('dirent',
+                    [('d_name', lltype.FixedSizeArray(rffi.CHAR, 1))])
+
+            config = platform.configure(CConfig)
+            DIRENT = config['DIRENT']
+            DIRENTP = lltype.Ptr(DIRENT)
             DIRP = rffi.COpaquePtr('DIR')
-            DIRENTP = rffi.CStructPtr('dirent',
-                ('d_name', lltype.FixedSizeArray(lltype.Char, self.NAME_MAX+1)),
-                                   )
-            # XXX so far, DIRENTP cannot be handled by ll2ctypes because
-            #     it contains other fields before 'd_name', at least on Linux
             os_opendir = self.llexternal('opendir', [rffi.CCHARP], DIRP)
             os_readdir = self.llexternal('readdir', [DIRP], DIRENTP)
             os_closedir = self.llexternal('closedir', [DIRP], rffi.INT)
@@ -555,16 +615,41 @@
                     raise OSError(error, "os_readdir failed")
                 return result
 
-            return extdef([str],  # a single argument which is a str
-                          [str],  # returns a list of strings
-                          "ll_os.ll_os_listdir",
-                          llimpl=os_listdir_llimpl)
+        return extdef([str],  # a single argument which is a str
+                      [str],  # returns a list of strings
+                      "ll_os.ll_os_listdir",
+                      llimpl=os_listdir_llimpl)
 
     @registering(os.pipe)
     def register_os_pipe(self):
         # we need a different approach on Windows and on Posix
         if sys.platform.startswith('win'):
-            XXX   # CreatePipe, _open_osfhandle
+            HANDLE = rffi.ULONG
+            HANDLEP = lltype.Ptr(lltype.FixedSizeArray(HANDLE, 1))
+            CreatePipe = self.llexternal('CreatePipe', [HANDLEP,
+                                                        HANDLEP,
+                                                        rffi.VOIDP,
+                                                        rffi.ULONG],
+                                         rffi.INT)
+            _open_osfhandle = self.llexternal('_open_osfhandle', [rffi.ULONG,
+                                                                  rffi.INT],
+                                              rffi.INT)
+            null = lltype.nullptr(rffi.VOIDP.TO)
+
+            def os_pipe_llimpl():
+                pread  = lltype.malloc(HANDLEP.TO, flavor='raw')
+                pwrite = lltype.malloc(HANDLEP.TO, flavor='raw')
+                ok = CreatePipe(pread, pwrite, null, 0)
+                hread = pread[0]
+                hwrite = pwrite[0]
+                lltype.free(pwrite, flavor='raw')
+                lltype.free(pread, flavor='raw')
+                if not ok:    # XXX guess the error, can't use GetLastError()
+                    raise OSError(errno.EMFILE, "os_pipe failed")
+                fdread = _open_osfhandle(hread, 0)
+                fdwrite = _open_osfhandle(hwrite, 1)
+                return (fdread, fdwrite)
+
         else:
             INT_ARRAY_P = lltype.Ptr(lltype.FixedSizeArray(rffi.INT, 2))
             os_pipe = self.llexternal('pipe', [INT_ARRAY_P], rffi.INT)
@@ -579,9 +664,9 @@
                     raise OSError(rffi.get_errno(), "os_pipe failed")
                 return (read_fd, write_fd)
 
-            return extdef([], (int, int),
-                          "ll_os.ll_os_pipe",
-                          llimpl=os_pipe_llimpl)
+        return extdef([], (int, int),
+                      "ll_os.ll_os_pipe",
+                      llimpl=os_pipe_llimpl)
 
     @registering_if(os, 'readlink')
     def register_os_readlink(self):
@@ -747,14 +832,11 @@
 
     @registering(os.chmod)
     def register_os_chmod(self):
-        if os.name == 'nt':
-            MODE_T = rffi.INT
-        else:
-            MODE_T = rffi.MODE_T
-        os_chmod = self.llexternal('chmod', [rffi.CCHARP, MODE_T], rffi.INT)
+        os_chmod = self.llexternal('chmod', [rffi.CCHARP, rffi.MODE_T],
+                                   rffi.INT)
 
         def chmod_llimpl(path, mode):
-            res = os_chmod(path, rffi.cast(MODE_T, mode))
+            res = os_chmod(path, rffi.cast(rffi.MODE_T, mode))
             if res < 0:
                 raise OSError(rffi.get_errno(), "os_chmod failed")
 
@@ -776,14 +858,10 @@
 
     @registering(os.umask)
     def register_os_umask(self):
-        if os.name == 'nt':
-            mode_t = rffi.INT
-        else:
-            mode_t = rffi.MODE_T
-        os_umask = self.llexternal('umask', [mode_t], mode_t)
+        os_umask = self.llexternal('umask', [rffi.MODE_T], rffi.MODE_T)
 
         def umask_llimpl(fd):
-            res = os_umask(rffi.cast(mode_t, fd))
+            res = os_umask(rffi.cast(rffi.MODE_T, fd))
             return rffi.cast(lltype.Signed, res)
 
         return extdef([int], int, llimpl=umask_llimpl,



More information about the Pypy-commit mailing list