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(a)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