ctypes allows to write extensions in pure Python. It is also part of the
Python's standard library and more portable across different
implementations and versions. This is also a first step to support
Python3.

A compatibility layer to the old vdeplug_python is also supplied as like
to the VdePlug module.
---
 vde-2/configure.ac                     |  15 ---
 vde-2/src/lib/python/Makefile.am       |  15 +--
 vde-2/src/lib/python/VdePlug.py        |  96 ++-------------
 vde-2/src/lib/python/vdeplug.py        | 219 +++++++++++++++++++++++++++++++++
 vde-2/src/lib/python/vdeplug_python.c  | 102 ---------------
 vde-2/src/lib/python/vdeplug_python.py |  15 +++
 6 files changed, 248 insertions(+), 214 deletions(-)
 create mode 100644 vde-2/src/lib/python/vdeplug.py
 delete mode 100644 vde-2/src/lib/python/vdeplug_python.c
 create mode 100644 vde-2/src/lib/python/vdeplug_python.py

diff --git a/vde-2/configure.ac b/vde-2/configure.ac
index c8f6d32..947aae6 100644
--- a/vde-2/configure.ac
+++ b/vde-2/configure.ac
@@ -223,21 +223,6 @@ AC_ARG_ENABLE([python],
 if test x"$enable_python" = x"yes"; then
   # check python
   AM_PATH_PYTHON([2.5])
-  AC_PATH_PROG(PYTHON_CONFIG, python$PYTHON_VERSION-config)
-  if test x"$PYTHON_CONFIG" = x""; then
-    AC_PATH_PROG(PYTHON_CONFIG, python-config)
-  fi
-  if test x"$PYTHON_CONFIG" = x""; then
-    # not found, give up
-    enable_python=no
-  else
-    PYTHON_CFLAGS=`$PYTHON_CONFIG --includes`
-    PYTHON_LIBS=`$PYTHON_CONFIG --libs`
-    PYTHON_INCLUDES="$PYTHON_CFLAGS"
-  fi
-  AC_SUBST(PYTHON_CFLAGS)
-  AC_SUBST(PYTHON_INCLUDES)
-  AC_SUBST(PYTHON_LIBS)
 fi
 
 
diff --git a/vde-2/src/lib/python/Makefile.am b/vde-2/src/lib/python/Makefile.am
index b4d6e2b..4bfe5ef 100644
--- a/vde-2/src/lib/python/Makefile.am
+++ b/vde-2/src/lib/python/Makefile.am
@@ -1,12 +1,3 @@
-moddir = $(pythondir)
-
-AM_LIBTOOLFLAGS = --tag=disable-static
-
-LIBADD = $(top_builddir)/src/lib/libvdeplug.so
-
-mod_LTLIBRARIES = vdeplug_python.la
-dist_python_SCRIPTS = VdePlug.py
-
-vdeplug_python_la_CFLAGS = -I$(top_srcdir)/include $(PYTHON_CFLAGS) 
$(PYTHON_INCLUDES)
-vdeplug_python_la_LIBADD = $(PYTHON_LIBS) $(top_builddir)/src/lib/libvdeplug.la
-vdeplug_python_la_LDFLAGS = -module -avoid-version
+python_PYTHON = VdePlug.py \
+                               vdeplug.py \
+                               vdeplug_python.py
diff --git a/vde-2/src/lib/python/VdePlug.py b/vde-2/src/lib/python/VdePlug.py
index 241c832..8035855 100755
--- a/vde-2/src/lib/python/VdePlug.py
+++ b/vde-2/src/lib/python/VdePlug.py
@@ -1,89 +1,15 @@
-#!/usr/bin/python
+from vdeplug import VdeStream, VdePlug
+import warnings
 
-'''
 
- LibVdePlug/python wrapper
- Copyright  2010 Daniele Lacamera
+__all__ = ["VdeStream", "VdePlug"]
 
- Released under the terms of GNU LGPL v. 2.1
- (see COPYING.libvdeplug in the main project directory)
-
-'''
-
-import vdeplug_python, os, sys, struct
-from array import array
-
-
-class VdeStream:
-       def __init__(self, parent, outf, frecv = None, ferr = None):
-               self.conn = parent
-               self.outf = outf
-               self.frecv = frecv
-               self.ferr = ferr
-               self.conn._streams.append(self)
-               if (self.frecv == None):
-                       self.frecv=self.conn.send
-               
-       def recv(self, buf):
-               (toth, totl) = struct.unpack("BB", buf[0:2])
-               tot = (toth << 8) + totl
-               buffer = buf[2:]
-               if (len(buffer) < tot):
-                       sys.stderr.write("stream recv: wrong size %d, pkt is 
%d\n" % (tot, len(buffer)))
-                       return -1
-               elif (len(buffer) > tot):
-                       self.frecv(buffer[0:tot])
-                       return self.recv(buffer[tot:]) # Recursion for 
remaining data
-               elif (self.frecv(buffer) < 0):
-                       return -1
-               
-       def send(self, buf):
-               if self.outf is None:
-                       return -1 
-               lh = (len(buf)>>8) & 0xFF 
-               ll = len(buf) & 0xFF
-               a = struct.pack("BB", lh, ll)
-               self.outf.write(a)
-               self.outf.write(buf)
-               self.outf.flush()
-       
-       
-       
-
-
-class VdePlug:
-
-       def __init__(self, sock=None, descr="Python", port=0, group=None, 
mode=0):
-               self._magic = vdeplug_python.open(sock, descr)
-               self._ctl = os.fdopen(vdeplug_python.ctlfd(self._magic))
-               self._data = os.fdopen(vdeplug_python.datafd(self._magic), 
'wb+', os.O_NONBLOCK)
-               self._streams = []
-
-       def ctlfd(self):
-               return self._ctl
-
-       def datafd(self):
-               return self._data
-
-       def send(self, buffer):
-               a = array('B', buffer)
-               r = self._data.write(a)
-               self._data.flush()
-               return r
-
-       def recv(self, size):
-               return os.read(self._data.fileno(), size)
-
-       def recvfrom_streams(self, buf):
-               for s in self._streams:
-                       s.recv(buf)
-
-       def sendto_streams(self, buf):
-               for s in self._streams:
-                       s.send(buf)
-
-       def close(self):
-               vdeplug_python.close(self._magic)
-               self._magic = None
-               
+msg = """The module VdePlug is deprecated. Please use the module \
+vdeplug. Change your code as following:
 
+    try:
+        from vdeplug import VdePlug, VdeStream
+    except ImportError:
+        from VdePlug import VdePlug, VdeStream
+"""
+warnings.warn(msg, DeprecationWarning)
diff --git a/vde-2/src/lib/python/vdeplug.py b/vde-2/src/lib/python/vdeplug.py
new file mode 100644
index 0000000..6a63f08
--- /dev/null
+++ b/vde-2/src/lib/python/vdeplug.py
@@ -0,0 +1,219 @@
+# libvdeplug wrapper
+# Copyright (C) 2015 Marco Giusti
+#
+# Released under the terms of GNU LGPL v. 2.1
+# (see COPYING.libvdeplug in the main project directory)
+
+import os
+import ctypes
+import ctypes.util
+
+
+__all__ = ["LIBVDEPLUG_INTERFACE_VERSION", "VdeError", "open", "close",
+           "ctlfd", "datafd", "libvdeplug"]
+__version__ = "0.1"
+
+
+LIBVDEPLUG_INTERFACE_VERSION = 1
+
+
+# VdeError derives from RuntimeError only because of compatibility reasons
+
+class VdeError(EnvironmentError, RuntimeError):
+
+    def __init__(self, *args):
+        if not args:
+            errno = ctypes.get_errno()
+            args = errno, os.strerror(errno)
+        super(VdeError, self).__init__(*args)
+
+
+def open(sock, desc, port=0, group=None, mode=0o777):
+    """Open a VDE connection.
+
+    @param sock: switch id (path)
+    @type sock: str
+    @param desc: description that appear in the port description on the
+        switch
+    @type desc: str
+    @param port: connect to a specific port of the switch [default=0]
+    @type port: int
+    @param group: change the ownership of the communication port to a specific
+        group (None=no change) [default=None]
+    @type group: str
+    @param mode: set communication port mode (if 0 standard socket mode
+        applies) [default=0]
+    @type mode: int
+    """
+
+    args = _VdeOpenArgs(int(port), str(group), int(mode))
+    fd = libvdeplug.vde_open_real(sock, desc, LIBVDEPLUG_INTERFACE_VERSION,
+                                  ctypes.byref(args))
+    if not fd:
+        raise VdeError()
+    return fd
+
+
+def _invoke(func, conn):
+    i = func(conn)
+    if i < 0:
+        raise VdeError()
+    return i
+
+
+def ctlfd(conn):
+    """
+    for select/poll. the ctl socket is silent after the initial handshake.
+    when EOF the switch has closed the connection.
+    """
+
+    return _invoke(libvdeplug.vde_ctlfd, conn)
+
+
+def datafd(conn):
+    """
+    for select/poll when this fd receive data, there are packets to recv (call
+    vde_recv)
+    """
+
+    return _invoke(libvdeplug.vde_datafd, conn)
+
+
+def close(conn):
+    """Close a connection."""
+
+    return _invoke(libvdeplug.vde_close, conn)
+
+
+class Plug(object):
+
+    def __init__(self, sock, desc, port=0, group=None, mode=0o777):
+        self._conn = open(sock, desc, port, group, mode)
+        try:
+            self._ctlfd = os.fdopen(ctlfd(self._conn))
+            self._datafd = os.fdopen(datafd(self._conn), "wb+")
+        except:
+            self.close()
+            raise
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self.close()
+
+    def ctlfd(self):
+        return self._ctlfd
+
+    def datafd(self):
+        return self._datafd
+
+    def close(self):
+        close(self._conn)
+
+
+class _VdeOpenArgs(ctypes.Structure):
+
+    _fields_ = [("port", ctypes.c_int),
+                ("group", ctypes.c_char_p),
+                ("mode", ctypes.c_int)]
+
+
+def _initializeModule(libvdeplug):
+    libvdeplug.vde_open_real.argtypes = [ctypes.c_char_p, ctypes.c_char_p,
+                                         ctypes.c_int,
+                                         ctypes.POINTER(_VdeOpenArgs)]
+    libvdeplug.vde_open_real.restype = ctypes.c_void_p
+    libvdeplug.vde_recv.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
+                                    ctypes.c_size_t, ctypes.c_int]
+    libvdeplug.vde_recv.restype = ctypes.c_ssize_t
+    libvdeplug.vde_send.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
+                                    ctypes.c_size_t, ctypes.c_int]
+    libvdeplug.vde_send.restype = ctypes.c_ssize_t
+    libvdeplug.vde_datafd.argtypes = [ctypes.c_void_p]
+    libvdeplug.vde_datafd.restype = ctypes.c_int
+    libvdeplug.vde_ctlfd.argtypes = [ctypes.c_void_p]
+    libvdeplug.vde_ctlfd.restype = ctypes.c_int
+    libvdeplug.vde_close.argtypes = [ctypes.c_void_p]
+    libvdeplug.vde_close.restype = ctypes.c_int
+
+
+name = ctypes.util.find_library("vdeplug")
+if not name:
+    raise ImportError("Can't find vdeplug library.")
+libvdeplug = ctypes.CDLL(name, use_errno=True)
+del name
+_initializeModule(libvdeplug)
+
+
+# old VdePlug compatibility
+
+# LibVdePlug/python wrapper
+# Copyright  2010 Daniele Lacamera
+#
+# Released under the terms of GNU LGPL v. 2.1
+# (see COPYING.libvdeplug in the main project directory)
+
+import sys
+import struct
+from array import array
+
+
+class VdePlug(Plug):
+
+    def __init__(self, sock=None, descr="Python", port=0, group=None, mode=0):
+        super(VdePlug, self).__init__(sock, descr, port, group, mode)
+        self._streams = []
+
+    def send(self, buffer):
+        a = array("B", buffer)
+        r = self._datafd.write(a)
+        self._datafd.flush()
+        return r
+
+    def recv(self, size):
+        return self._datafd.read(size)
+
+    def recvfrom_streams(self, buf):
+        for s in self._streams:
+            s.recv(buf)
+
+    def sendto_streams(self, buf):
+        for s in self._streams:
+            s.send(buf)
+
+
+class VdeStream:
+
+    def __init__(self, parent, outf, frecv=None, ferr=None):
+        self.conn = parent
+        self.outf = outf
+        self.frecv = frecv
+        self.ferr = ferr
+        self.conn._streams.append(self)
+        if self.frecv is None:
+            self.frecv = self.conn.send
+
+    def recv(self, buf):
+        toth, totl = struct.unpack("BB", buf[0:2])
+        tot = (toth << 8) + totl
+        buffer = buf[2:]
+        if len(buffer) < tot:
+            sys.stderr.write("stream recv: wrong size %d, pkt is %d\n" %
+                             (tot, len(buffer)))
+            return -1
+        elif len(buffer) > tot:
+            self.frecv(buffer[0:tot])
+            return self.recv(buffer[tot:])  # Recursion for remaining data
+        elif self.frecv(buffer) < 0:
+            return -1
+
+    def send(self, buf):
+        if self.outf is None:
+            return -1
+        lh = (len(buf) >> 8) & 0xFF
+        ll = len(buf) & 0xFF
+        a = struct.pack("BB", lh, ll)
+        self.outf.write(a)
+        self.outf.write(buf)
+        self.outf.flush()
diff --git a/vde-2/src/lib/python/vdeplug_python.c 
b/vde-2/src/lib/python/vdeplug_python.c
deleted file mode 100644
index 9d70e72..0000000
--- a/vde-2/src/lib/python/vdeplug_python.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * LibVdePlug/python wrapper
- * Copyright © 2010 Daniele Lacamera
- *
- * Released under the terms of GNU LGPL v. 2.1
- * (see COPYING.libvdeplug in the main project directory)
- *
- */
-#include "Python.h"
-#include <stdio.h>
-#include "libvdeplug.h"
-
-
-static PyObject *vdeplug_open(PyObject *self, PyObject *args)
-{
-       struct vde_open_args vde_args = {0,NULL,0777};
-       char *vde_sock = NULL, *vde_descr = NULL;
-       VDECONN *ret;
-
-       if (!PyArg_ParseTuple(args, "ss|isi", &vde_sock, &vde_descr, 
&vde_args.port, &vde_args.group, &vde_args.mode))
-               goto failure; 
-
-       ret = vde_open_real(vde_sock, vde_descr, 1, &vde_args);
-       if (!ret)
-               goto failure;
-       else
-               return PyLong_FromUnsignedLong((unsigned long) ret);
-
-       
-failure:
-       return PyErr_SetFromErrno(PyExc_RuntimeError);
-}
-
-static PyObject *vdeplug_ctlfd(PyObject *self, PyObject *args)
-{
-       VDECONN *conn;
-       unsigned long vde_magic = 0;
-
-       if (!PyArg_ParseTuple(args, "k", &vde_magic))
-               goto failure; 
-       conn = (VDECONN *) vde_magic;
-
-       if (!conn)
-               goto failure;
-
-       return Py_BuildValue("i", vde_ctlfd(conn));
-       
-failure:
-       return PyErr_SetFromErrno(PyExc_RuntimeError);
-}
-
-static PyObject *vdeplug_datafd(PyObject *self, PyObject *args)
-{
-       VDECONN *conn;
-       unsigned long vde_magic = 0;
-
-       if (!PyArg_ParseTuple(args, "k", &vde_magic))
-               goto failure; 
-       conn = (VDECONN *) vde_magic;
-
-       if (!conn)
-               goto failure;
-
-       return Py_BuildValue("i", vde_datafd(conn));
-       
-failure:
-       return PyErr_SetFromErrno(PyExc_RuntimeError);
-}
-
-static PyObject *vdeplug_close(PyObject *self, PyObject *args)
-{
-       VDECONN *conn;
-       unsigned long vde_magic = 0;
-
-       if (!PyArg_ParseTuple(args, "k", &vde_magic))
-               goto failure; 
-       conn = (VDECONN *) vde_magic;
-
-       if (!conn)
-               goto failure;
-
-       return Py_BuildValue("i", vde_close(conn));
-       
-failure:
-       return PyErr_SetFromErrno(PyExc_RuntimeError);
-}
-
-
-
-static PyMethodDef vdeplug_methods[] = {
-    {"open",  vdeplug_open, METH_VARARGS},
-    {"ctlfd",  vdeplug_ctlfd, METH_VARARGS},
-    {"datafd",  vdeplug_datafd, METH_VARARGS},
-    {"close",  vdeplug_close, METH_VARARGS},
-    {NULL,      NULL}        /* Sentinel */
-};
-
-void initvdeplug_python(void)
-{
-       (void) Py_InitModule("vdeplug_python", vdeplug_methods);
-//     PyErr_SetString(PyExc_RuntimeError,"vdeplug error");
-}
diff --git a/vde-2/src/lib/python/vdeplug_python.py 
b/vde-2/src/lib/python/vdeplug_python.py
new file mode 100644
index 0000000..96738f3
--- /dev/null
+++ b/vde-2/src/lib/python/vdeplug_python.py
@@ -0,0 +1,15 @@
+from vdeplug import open, ctlfd, datafd, close
+import warnings
+
+
+__all__ = ["open", "ctlfd", "datafd", "close"]
+
+msg = """The module vdeplug_python is deprecated. Please use the module \
+vdeplug. Change your code as following:
+
+    try:
+        import vdeplug as vp
+    except ImportError:
+        import vdeplug_python as vp
+"""
+warnings.warn(msg, DeprecationWarning)
-- 
2.1.4


------------------------------------------------------------------------------
_______________________________________________
vde-users mailing list
vde-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vde-users

Reply via email to