From: Amit Bawer <abawer(a)redhat.com>
This helper allows accessing the inner bytes of
PyObject according to python version:
- Py2: String object
- Py3: Unicode object
This method is mostly used for paths as a temp
solution until we add the path convertor.
---
python/sanlock.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/python/sanlock.c b/python/sanlock.c
index aa3b9a8..108a7b8 100644
--- a/python/sanlock.c
+++ b/python/sanlock.c
@@ -69,10 +69,32 @@ __set_exception(int en, char *msg)
PyErr_SetObject(py_exception, exc_tuple);
Py_DECREF(exc_tuple);
}
}
+/*
+ * Returns NULL-terminated representation of the contents of obj.
+ *
+ * obj must be a string object (py2) or Unicode object (py3), otherwise returns NULL
+ * and raises TypeError.[1][2]
+ *
+ * The returned pointer refers to the internal buffer of string, not a copy. It must not
be
+ * deallocated, and the object must be kept alive as long as the retruned pointer is
used.
+ * [1]
https://docs.python.org/2/c-api/string.html#c.PyString_AsString
+ * [2]
https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_AsUTF8
+ *
+ */
+static const char*
+pystring_as_cstring(PyObject *obj)
+{
+#if PY_MAJOR_VERSION == 2
+ return PyString_AsString(obj);
+#else
+ return PyUnicode_AsUTF8(obj);
+#endif
+}
+
static int
__parse_resource(PyObject *obj, struct sanlk_resource **res_ret)
{
int i, num_disks, res_len;
struct sanlk_resource *res;
@@ -90,11 +112,11 @@ __parse_resource(PyObject *obj, struct sanlk_resource **res_ret)
memset(res, 0, res_len);
res->num_disks = num_disks;
for (i = 0; i < num_disks; i++) {
- char *p = NULL;
+ const char *p = NULL;
PyObject *tuple, *path = NULL, *offset = NULL;
tuple = PyList_GetItem(obj, i);
if (PyTuple_Check(tuple)) {
@@ -104,11 +126,11 @@ __parse_resource(PyObject *obj, struct sanlk_resource **res_ret)
}
path = PyTuple_GetItem(tuple, 0);
offset = PyTuple_GetItem(tuple, 1);
- p = PyString_AsString(path);
+ p = pystring_as_cstring(path);
if (!PyInt_Check(offset)) {
__set_exception(EINVAL, "Invalid resource offset");
goto exit_fail;
}
@@ -193,11 +215,11 @@ static void
set_value_error(const char* format, PyObject* obj)
{
const char* str_rep = "";
PyObject* rep = PyObject_Repr(obj);
if (rep)
- str_rep = PyString_AsString(rep);
+ str_rep = pystring_as_cstring(rep);
PyErr_Format(PyExc_ValueError, format, str_rep);
Py_XDECREF(rep);
}
static PyObject *
@@ -1313,11 +1335,11 @@ py_killpath(PyObject *self __unused, PyObject *args, PyObject
*keywds)
/* creating the arguments string from a python list */
for (i = 0, n = 0; i < num_args; i++) {
size_t arg_len;
item = PyList_GetItem(argslist, i);
- p = PyString_AsString(item);
+ p = pystring_as_cstring(item);
if (p == NULL) {
__set_exception(EINVAL, "Killpath argument not a string");
return NULL;
}
--
2.17.2