[libvirt] [PATCH 1/7] python: Implement virStreamSend/Recv

Cole Robinson crobinso at redhat.com
Mon Jun 20 19:34:25 UTC 2011


The return values for the python version are different that the C version
of virStreamSend: on success we return a string, an error raises an exception,
and if the stream would block we return int(-2). We need to do this
since strings aren't passed by reference in python.

Signed-off-by: Cole Robinson <crobinso at redhat.com>
---
 python/generator.py                  |    9 +++--
 python/libvirt-override-virStream.py |   35 +++++++++++++++++++
 python/libvirt-override.c            |   62 ++++++++++++++++++++++++++++++++++
 python/typewrappers.c                |   14 ++++++++
 python/typewrappers.h                |    1 +
 5 files changed, 117 insertions(+), 4 deletions(-)

diff --git a/python/generator.py b/python/generator.py
index cb4d8a4..315d3d4 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -348,8 +348,6 @@ skip_impl = (
     'virNWFilterGetUUID',
     'virNWFilterGetUUIDString',
     'virNWFilterLookupByUUID',
-    'virStreamRecv',
-    'virStreamSend',
     'virStoragePoolGetUUID',
     'virStoragePoolGetUUIDString',
     'virStoragePoolLookupByUUID',
@@ -393,9 +391,12 @@ skip_function = (
     'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
     'virSaveLastError', # We have our own python error wrapper
     'virFreeError', # Only needed if we use virSaveLastError
+
     'virStreamFree', # Overridden in libvirt-override-virStream.py
-    'virStreamRecvAll',
-    'virStreamSendAll',
+    'virStreamRecvAll', # XXX: Can be written in pure python?
+    'virStreamSendAll', # XXX: Can be written in pure python?
+    'virStreamRecv', # overridden in libvirt-override-virStream.py
+    'virStreamSend', # overridden in libvirt-override-virStream.py
 
     # 'Ref' functions have no use for bindings users.
     "virConnectRef",
diff --git a/python/libvirt-override-virStream.py b/python/libvirt-override-virStream.py
index 56f1df5..f8a1d0b 100644
--- a/python/libvirt-override-virStream.py
+++ b/python/libvirt-override-virStream.py
@@ -24,3 +24,38 @@
         cbData = {"stream": self, "cb" : cb, "opaque" : opaque}
         ret = libvirtmod.virStreamEventAddCallback(self._o, events, cbData)
         if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed')
+
+    def recv(self, nbytes):
+        """Write a series of bytes to the stream. This method may
+        block the calling application for an arbitrary amount
+        of time.
+
+        Errors are not guaranteed to be reported synchronously
+        with the call, but may instead be delayed until a
+        subsequent call.
+
+        On success, the received data is returned. On failure, an
+        exception is raised. If the stream is a NONBLOCK stream and
+        the request would block, integer -2 is returned.
+        """
+        ret = libvirtmod.virStreamRecv(self._o, nbytes)
+        if ret == None: raise libvirtError ('virStreamRecv() failed')
+        return ret
+
+    def send(self, data):
+        """Write a series of bytes to the stream. This method may
+        block the calling application for an arbitrary amount
+        of time. Once an application has finished sending data
+        it should call virStreamFinish to wait for successful
+        confirmation from the driver, or detect any error
+
+        This method may not be used if a stream source has been
+        registered
+
+        Errors are not guaranteed to be reported synchronously
+        with the call, but may instead be delayed until a
+        subsequent call.
+        """
+        ret = libvirtmod.virStreamSend(self._o, data, len(data))
+        if ret == -1: raise libvirtError ('virStreamSend() failed')
+        return ret
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 55cb61c..63157b4 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -3697,6 +3697,66 @@ libvirt_virStreamEventAddCallback(PyObject *self ATTRIBUTE_UNUSED,
     return py_retval;
 }
 
+static PyObject *
+libvirt_virStreamRecv(PyObject *self ATTRIBUTE_UNUSED,
+                      PyObject *args)
+{
+    PyObject *pyobj_stream;
+    virStreamPtr stream;
+    char *buf = NULL;
+    int ret;
+    int nbytes;
+
+    if (!PyArg_ParseTuple(args, (char *) "Oi:virStreamRecv",
+                          &pyobj_stream, &nbytes)) {
+        DEBUG("%s failed to parse tuple\n", __FUNCTION__);
+        return VIR_PY_NONE;
+    }
+    stream = PyvirStream_Get(pyobj_stream);
+
+    if ((buf = malloc(nbytes+1 > 0 ? nbytes+1 : 1)) == NULL)
+        return VIR_PY_NONE;
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+    ret = virStreamRecv(stream, buf, nbytes);
+    LIBVIRT_END_ALLOW_THREADS;
+
+    buf[ret > -1 ? ret : 0] = '\0';
+    DEBUG("StreamRecv ret=%d strlen=%d\n", ret, (int) strlen(buf));
+
+    if (ret < 0)
+        return libvirt_intWrap(ret);
+    return libvirt_charPtrSizeWrap((char *) buf, (Py_ssize_t) ret);
+}
+
+static PyObject *
+libvirt_virStreamSend(PyObject *self ATTRIBUTE_UNUSED,
+                      PyObject *args)
+{
+    PyObject *py_retval;
+    PyObject *pyobj_stream;
+    virStreamPtr stream;
+    char *data;
+    int ret;
+    int nbytes;
+
+    if (!PyArg_ParseTuple(args, (char *) "Ozi:virStreamRecv",
+                          &pyobj_stream, &data, &nbytes)) {
+        DEBUG("%s failed to parse tuple\n", __FUNCTION__);
+        return VIR_PY_INT_FAIL;
+    }
+    stream = PyvirStream_Get(pyobj_stream);
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+    ret = virStreamSend(stream, data, nbytes);
+    LIBVIRT_END_ALLOW_THREADS;
+
+    DEBUG("StreamSend ret=%d\n", ret);
+
+    py_retval = libvirt_intWrap(ret);
+    return py_retval;
+}
+
 /************************************************************************
  *									*
  *			The registration stuff				*
@@ -3715,6 +3775,8 @@ static PyMethodDef libvirtMethods[] = {
     {(char *) "virConnectDomainEventRegisterAny", libvirt_virConnectDomainEventRegisterAny, METH_VARARGS, NULL},
     {(char *) "virConnectDomainEventDeregisterAny", libvirt_virConnectDomainEventDeregisterAny, METH_VARARGS, NULL},
     {(char *) "virStreamEventAddCallback", libvirt_virStreamEventAddCallback, METH_VARARGS, NULL},
+    {(char *) "virStreamRecv", libvirt_virStreamRecv, METH_VARARGS, NULL},
+    {(char *) "virStreamSend", libvirt_virStreamSend, METH_VARARGS, NULL},
     {(char *) "virDomainGetInfo", libvirt_virDomainGetInfo, METH_VARARGS, NULL},
     {(char *) "virDomainGetState", libvirt_virDomainGetState, METH_VARARGS, NULL},
     {(char *) "virDomainGetControlInfo", libvirt_virDomainGetControlInfo, METH_VARARGS, NULL},
diff --git a/python/typewrappers.c b/python/typewrappers.c
index e39d3cd..b5758b4 100644
--- a/python/typewrappers.c
+++ b/python/typewrappers.c
@@ -77,6 +77,20 @@ libvirt_ulonglongWrap(unsigned long long val)
 }
 
 PyObject *
+libvirt_charPtrSizeWrap(char *str, Py_ssize_t size)
+{
+    PyObject *ret;
+
+    if (str == NULL) {
+        Py_INCREF(Py_None);
+        return (Py_None);
+    }
+    ret = PyString_FromStringAndSize(str, size);
+    free(str);
+    return (ret);
+}
+
+PyObject *
 libvirt_charPtrWrap(char *str)
 {
     PyObject *ret;
diff --git a/python/typewrappers.h b/python/typewrappers.h
index cc98110..305d594 100644
--- a/python/typewrappers.h
+++ b/python/typewrappers.h
@@ -156,6 +156,7 @@ PyObject * libvirt_ulongWrap(unsigned long val);
 PyObject * libvirt_longlongWrap(long long val);
 PyObject * libvirt_ulonglongWrap(unsigned long long val);
 PyObject * libvirt_charPtrWrap(char *str);
+PyObject * libvirt_charPtrSizeWrap(char *str, Py_ssize_t size);
 PyObject * libvirt_constcharPtrWrap(const char *str);
 PyObject * libvirt_charPtrConstWrap(const char *str);
 PyObject * libvirt_virConnectPtrWrap(virConnectPtr node);
-- 
1.7.4.4




More information about the libvir-list mailing list