[pypy-commit] pypy winconsoleio: Work in progress.

andrewjlawrence pypy.commits at gmail.com
Sat Jun 1 17:49:55 EDT 2019


Author: andrewjlawrence
Branch: winconsoleio
Changeset: r96726:462ddd6f090c
Date: 2019-06-01 22:48 +0100
http://bitbucket.org/pypy/pypy/changeset/462ddd6f090c/

Log:	Work in progress.

diff --git a/pypy/module/_io/interp_win32consoleio.py b/pypy/module/_io/interp_win32consoleio.py
--- a/pypy/module/_io/interp_win32consoleio.py
+++ b/pypy/module/_io/interp_win32consoleio.py
@@ -1,19 +1,47 @@
 import sys
 
+from pypy.interpreter.error import oefmt
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
 from pypy.module._io.interp_iobase import (W_RawIOBase, DEFAULT_BUFFER_SIZE)
+from pypy.interpreter.unicodehelper import fsdecode
+from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib import rwin32
 
-def _get_console_type():
-    pass
+SMALLBUF = 4
 
-def _pyio_get_console_type():
-    pass
+def _get_console_type(handle):
+    try:
+        mode = lltype.malloc(rffi.DWORD,0,flavor='raw')
+        peek_count = lltype.malloc(rffi.DWORD,0,flavor='raw')
+
+        if handle == INVALID_HANDLE_VALUE:
+            return '\0'
+
+        if not rwin32.GetConsoleMode(handle, mode):
+            return '\0'
+
+        # Peek at the handle to see whether it is an input or output handle
+        if rwin32.GetNumberOfConsoleInputEvents(handle, peek_count):
+            return 'r'
+        return 'w'
+    finally:
+        lltype.free(mode, flavor='raw')
+        lltype.free(peek_count, flavor='raw')
+
+def _pyio_get_console_type(path_or_fd):
+    fd = int(path_or_fd)
+    if fd >= 0:
+        handle = rwin32.get_osfhandle(fd)
+        if handle == rwin32.INVALID_HANDLE_VALUE:
+            return '\0'
+        return _get_console_type(handle)
+
+    #if not fsdecode(path_or_fd, decoded):
+    #    return '\0';
+
 
 class W_WinConsoleIO(W_RawIOBase):
-    SMALLBUF = 4
-    
     def __init__(self, space):
         W_RawIOBase.__init__(self, space)
         self.handle = rwin32.INVALID_HANDLE_VALUE
@@ -36,97 +64,100 @@
         console_type = '\0'
         self.buf = lltype.malloc(rffi.CCHARPP.TO,SMALLBUF,flavor='raw')
 
-        self.fd = space.int_w(w_nameobj)
-        closefd = space.bool_w(w_closefd)
+        try:
+            self.fd = space.int_w(w_nameobj)
+            closefd = space.bool_w(w_closefd)
 
-        if self.fd < 0:
-            decodedname = space.fsdecode_w(w_nameobj)
-            name = rffi.cast(rffi.CWCHARP, decodedname)
-            console_type = _pyio_get_console_type(decodedname)
-            if not console_type:
+            if self.fd < 0:
+                decodedname = space.fsdecode_w(w_nameobj)
+                name = rffi.cast(rffi.CWCHARP, decodedname)
+                console_type = _pyio_get_console_type(decodedname)
+                if not console_type:
+                    raise oefmt(space.w_ValueError,
+                            "Invalid console type")
+                if console_type == '\0':
+                    raise oefmt(space.w_ValueError,
+                            "Cannot open non-console file")
+            s = space.text_w(w_mode)
+            
+            for char in s:
+                if char in "+abx":
+                    # OK do nothing
+                    pass
+                elif char == "r":
+                    if rwa:
+                        raise oefmt(space.w_ValueError,
+                                "invalid mode: %s", space.text_w(w_mode))
+                    rwa = True
+                    self.readable = True
+                    if console_type == "x":
+                        console_type = "r"
+                elif char == "w":
+                    if rwa:
+                        raise oefmt(space.w_ValueError,
+                                "invalid mode: %s", space.text_w(w_mode))
+                    rwa = True
+                    self.writable = True;
+                    if console_type == 'x':
+                        console_type = 'w'
+                else:
+                    raise oefmt(space.w_ValueError,
+                                "invalid mode: %s", space.text_w(w_mode))
+            if not rwa:
                 raise oefmt(space.w_ValueError,
-                        "Invalid console type")
-            if console_type == '\0':
-                raise oefmt(space.w_ValueError,
-                        "Cannot open non-console file")
-        s = space.text_w(w_mode)
-        
-        for char in s:
-            if char in "+abx":
-                # OK do nothing
-                pass
-            elif char == "r":
-                if rwa:
+                            "Must have exactly one of read or write mode")
+            
+            if self.fd >= 0:
+                self.handle = rwin32.get_osfhandle(self.fd)
+                self.closehandle = False
+            else:
+                access = rwin32.GENERIC_READ
+                self.closehandle = True
+                if not closefd:
                     raise oefmt(space.w_ValueError,
-                            "invalid mode: %.200s", mode)
-                rwa = True
-                self.readable = True
-                if console_type == "x":
-                    console_type = "r"
-            elif char == "w":
-                if rwa:
+                            "Cannot use closefd=False with a file name")
+                if self.writeable:
+                    access = rwin32.GENERIC_WRITE
+            
+                from rpython.rlib._os_support import _preferred_traits, string_trait
+                traits = _preferred_traits(name)
+                if not (traits.str is unicode):
                     raise oefmt(space.w_ValueError,
-                            "invalid mode: %.200s", mode)
-                rwa = True
-                self.writable = True;
-                if console_type == 'x':
-                    console_type = 'w'
-            else:
-                raise oefmt(space.w_ValueError,
-                            "invalid mode: %.200s", mode)
-        if not rwa:
-            raise oefmt(space.w_ValueError,
-                        "Must have exactly one of read or write mode")
-        
-        if self.fd >= 0:
-            self.handle = rwin32.get_osfhandle(self.fd)
-            self.closehandle = False
-        else:
-            access = rwin32.GENERIC_READ
-            self.closehandle = True
-            if not closefd:
-                raise oefmt(space.w_ValueError,
-                        "Cannot use closefd=False with a file name")
-            if self.writeable:
-                access = rwin32.GENERIC_WRITE
-        
-            from rpython.rlib._os_support import _preferred_traits, string_trait
-            traits = _preferred_traits(name)
-            if not (traits.str is unicode):
-                raise oefmt(space.w_ValueError,
-                            "Non-unicode string name %s", traits.str)
-            win32traits = make_win32_traits(traits)
-            self.handle = win32traits.CreateFile(name, 
-                rwin32.GENERIC_READ | rwin32.GENERIC_WRITE,
-                rwin32.FILE_SHARE_READ | rwin32.FILE_SHARE_WRITE,
-                rffi.NULL, win32traits.OPEN_EXISTING, 0, rffi.NULL)
-            if self.handle == rwin32.INVALID_HANDLE_VALUE:
+                                "Non-unicode string name %s", traits.str)
+                win32traits = make_win32_traits(traits)
                 self.handle = win32traits.CreateFile(name, 
-                    access,
+                    rwin32.GENERIC_READ | rwin32.GENERIC_WRITE,
                     rwin32.FILE_SHARE_READ | rwin32.FILE_SHARE_WRITE,
                     rffi.NULL, win32traits.OPEN_EXISTING, 0, rffi.NULL)
+                if self.handle == rwin32.INVALID_HANDLE_VALUE:
+                    self.handle = win32traits.CreateFile(name, 
+                        access,
+                        rwin32.FILE_SHARE_READ | rwin32.FILE_SHARE_WRITE,
+                        rffi.NULL, win32traits.OPEN_EXISTING, 0, rffi.NULL)
 
-            if self.handle == rwin32.INVALID_HANDLE_VALUE:
-                raise WindowsError(rwin32.GetLastError_saved(),
-                                   "Failed to open handle")
-        
-        if console_type == '\0':
-            console_type = _get_console_type(self.handle)
+                if self.handle == rwin32.INVALID_HANDLE_VALUE:
+                    raise WindowsError(rwin32.GetLastError_saved(),
+                                       "Failed to open handle")
+            
+            if console_type == '\0':
+                console_type = _get_console_type(self.handle)
 
-        if console_type == '\0': 
-            raise oefmt(space.w_ValueError,
-                        "Cannot open non-console file")
-        
-        if self.writable and console_type != 'w':
-            raise oefmt(space.w_ValueError,
-                        "Cannot open input buffer for writing")
+            if console_type == '\0': 
+                raise oefmt(space.w_ValueError,
+                            "Cannot open non-console file")
+            
+            if self.writable and console_type != 'w':
+                raise oefmt(space.w_ValueError,
+                            "Cannot open input buffer for writing")
 
-        if self.readable and console_type != 'r':
-            raise oefmt(space.w_ValueError,
-                        "Cannot open output buffer for reading")
+            if self.readable and console_type != 'r':
+                raise oefmt(space.w_ValueError,
+                            "Cannot open output buffer for reading")
 
-        self.blksize = DEFAULT_BUFFER_SIZE
-        rffi.c_memset(self.buf, 0, SMALLBUF)
+            self.blksize = DEFAULT_BUFFER_SIZE
+            rffi.c_memset(self.buf, 0, SMALLBUF)
+        finally:
+           lltype.free(self.buf, flavor='raw')
 
 W_WinConsoleIO.typedef = TypeDef(
     '_io.WinConsoleIO', W_WinConsoleIO.typedef,
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -560,3 +560,9 @@
                 os.close(fd2)
                 raise
         return res
+    
+    GetConsoleMode = winexternal(
+        'GetConsoleMode', [HANDLE, LPDWORD], BOOL)
+        
+    GetNumberOfConsoleInputEvents = winexternal(
+        'GetNumberOfConsoleInputEvents', [HANDLE, LPDWORD], BOOL)


More information about the pypy-commit mailing list