Author: Amaury Forgeot d'Arc <[email protected]>
Branch: kill_ll_termios
Changeset: r75277:25c15bf74988
Date: 2015-01-10 00:19 +0100
http://bitbucket.org/pypy/pypy/changeset/25c15bf74988/

Log:    Move tcsetattr from ll_termios to rtermios

diff --git a/rpython/rlib/rtermios.py b/rpython/rlib/rtermios.py
--- a/rpython/rlib/rtermios.py
+++ b/rpython/rlib/rtermios.py
@@ -3,11 +3,54 @@
 # returns list of mostly-strings of length one, but with few ints
 # inside, so we make sure it works
 
-import termios
-from termios import *
+from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rtyper.tool import rffi_platform
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+
+from rpython.rlib import rposix
+
+eci = ExternalCompilationInfo(
+    includes = ['termios.h', 'unistd.h']
+)
+
+class CConfig:
+    _compilation_info_ = eci
+    NCCS = rffi_platform.DefinedConstantInteger('NCCS')
+    TCSANOW = rffi_platform.ConstantInteger('TCSANOW')
+    _HAVE_STRUCT_TERMIOS_C_ISPEED = rffi_platform.Defined(
+            '_HAVE_STRUCT_TERMIOS_C_ISPEED')
+    _HAVE_STRUCT_TERMIOS_C_OSPEED = rffi_platform.Defined(
+            '_HAVE_STRUCT_TERMIOS_C_OSPEED')
+
+c_config = rffi_platform.configure(CConfig)
+NCCS = c_config['NCCS']
+TCSANOW = c_config['TCSANOW']
+
+TCFLAG_T = rffi.UINT
+CC_T = rffi.UCHAR
+SPEED_T = rffi.UINT
+
+_add = []
+if c_config['_HAVE_STRUCT_TERMIOS_C_ISPEED']:
+    _add.append(('c_ispeed', SPEED_T))
+if c_config['_HAVE_STRUCT_TERMIOS_C_OSPEED']:
+    _add.append(('c_ospeed', SPEED_T))
+TERMIOSP = rffi.CStructPtr('termios', ('c_iflag', TCFLAG_T), ('c_oflag', 
TCFLAG_T),
+                           ('c_cflag', TCFLAG_T), ('c_lflag', TCFLAG_T),
+                           ('c_line', CC_T),
+                           ('c_cc', lltype.FixedSizeArray(CC_T, NCCS)), *_add)
+
+def c_external(name, args, result):
+    return rffi.llexternal(name, args, result, compilation_info=eci)
+
+c_tcsetattr = c_external('tcsetattr', [rffi.INT, rffi.INT, TERMIOSP], rffi.INT)
+c_cfsetispeed = c_external('cfsetispeed', [TERMIOSP, SPEED_T], rffi.INT)
+c_cfsetospeed = c_external('cfsetospeed', [TERMIOSP, SPEED_T], rffi.INT)
+
 
 def tcgetattr(fd):
     # NOT_RPYTHON
+    import termios
     try:
         lst = list(termios.tcgetattr(fd))
     except termios.error, e:
@@ -22,17 +65,23 @@
     lst[-1] = next_cc
     return tuple(lst)
 
-def tcsetattr(fd, when, mode):
-    # NOT_RPYTHON
-    # there are some bizarre requirements for that, stealing directly
-    # from cpython
-    mode_l = list(mode)
-    if mode_l[3] & termios.ICANON:
-        cc = mode_l[-1]
-        cc[termios.VMIN] = ord(cc[termios.VMIN])
-        cc[termios.VTIME] = ord(cc[termios.VTIME])
-        mode_l[-1] = cc
-    try:
-        return termios.tcsetattr(fd, when, mode_l)
-    except termios.error, e:
-        raise OSError(*e.args)
+
+# This function is not an exact replacement of termios.tcsetattr:
+# the last attribute must be a list of chars.
+def tcsetattr(fd, when, attributes):
+    with lltype.scoped_alloc(TERMIOSP.TO) as c_struct:
+        rffi.setintfield(c_struct, 'c_c_iflag', attributes[0])
+        rffi.setintfield(c_struct, 'c_c_oflag', attributes[1])
+        rffi.setintfield(c_struct, 'c_c_cflag', attributes[2])
+        rffi.setintfield(c_struct, 'c_c_lflag', attributes[3])
+        ispeed = attributes[4]
+        ospeed = attributes[5]
+        cc = attributes[6]
+        for i in range(NCCS):
+            c_struct.c_c_cc[i] = rffi.r_uchar(ord(cc[i][0]))
+        if c_cfsetispeed(c_struct, ispeed) < 0:
+            raise OSError(rposix.get_errno(), 'tcsetattr failed')
+        if c_cfsetospeed(c_struct, ospeed) < 0:
+            raise OSError(rposix.get_errno(), 'tcsetattr failed')
+        if c_tcsetattr(fd, when, c_struct) < 0:
+            raise OSError(rposix.get_errno(), 'tcsetattr failed')
diff --git a/rpython/rtyper/module/ll_termios.py 
b/rpython/rtyper/module/ll_termios.py
--- a/rpython/rtyper/module/ll_termios.py
+++ b/rpython/rtyper/module/ll_termios.py
@@ -50,11 +50,8 @@
 def c_external(name, args, result):
     return rffi.llexternal(name, args, result, compilation_info=eci)
 
-c_tcsetattr = c_external('tcsetattr', [INT, INT, TERMIOSP], INT)
 c_cfgetispeed = c_external('cfgetispeed', [TERMIOSP], SPEED_T)
 c_cfgetospeed = c_external('cfgetospeed', [TERMIOSP], SPEED_T)
-c_cfsetispeed = c_external('cfsetispeed', [TERMIOSP, SPEED_T], INT)
-c_cfsetospeed = c_external('cfsetospeed', [TERMIOSP, SPEED_T], INT)
 c_tcsendbreak = c_external('tcsendbreak', [INT, INT], INT)
 c_tcdrain = c_external('tcdrain', [INT], INT)
 c_tcflush = c_external('tcflush', [INT, INT], INT)
@@ -81,32 +78,6 @@
 register_external(rtermios.tcgetattr, [int], (int, int, int, int, int, int, 
[str]),
                    llimpl=tcgetattr_llimpl, export_name='termios.tcgetattr')
 
-def tcsetattr_llimpl(fd, when, attributes):
-    c_struct = lltype.malloc(TERMIOSP.TO, flavor='raw')
-    try:
-        c_struct.c_c_iflag = r_uint(attributes[0])
-        c_struct.c_c_oflag = r_uint(attributes[1])
-        c_struct.c_c_cflag = r_uint(attributes[2])
-        c_struct.c_c_lflag = r_uint(attributes[3])
-        ispeed = r_uint(attributes[4])
-        ospeed = r_uint(attributes[5])
-        cc = attributes[6]
-        for i in range(NCCS):
-            c_struct.c_c_cc[i] = rffi.r_uchar(ord(cc[i][0]))
-        if c_cfsetispeed(c_struct, ispeed) < 0:
-            raise OSError(rposix.get_errno(), 'tcsetattr failed')
-        if c_cfsetospeed(c_struct, ospeed) < 0:
-            raise OSError(rposix.get_errno(), 'tcsetattr failed')
-        if c_tcsetattr(fd, when, c_struct) < 0:
-            raise OSError(rposix.get_errno(), 'tcsetattr failed')
-    finally:
-        lltype.free(c_struct, flavor='raw')
-
-r_uint = rffi.r_uint
-register_external(rtermios.tcsetattr, [int, int, (int, int, int,
-                  int, int, int, [str])], llimpl=tcsetattr_llimpl,
-                  export_name='termios.tcsetattr')
-
 # a bit C-c C-v code follows...
 
 def tcsendbreak_llimpl(fd, duration):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to