summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2009-10-15 10:11:37 +0300
committerPanu Matilainen <pmatilai@redhat.com>2009-10-15 10:11:37 +0300
commit410bf68fd41a6b8c98e48ca77e093f2f6c6bda75 (patch)
treeec820040f66bd1d053ed57a726b2901a3421a66a
parent50ad087c1030be242ab658c818ba2990dd33855e (diff)
downloadrpm-410bf68fd41a6b8c98e48ca77e093f2f6c6bda75.tar.gz
rpm-410bf68fd41a6b8c98e48ca77e093f2f6c6bda75.tar.bz2
rpm-410bf68fd41a6b8c98e48ca77e093f2f6c6bda75.zip
Accept rpm.fd() types file objects everywhere in python bindings
- turn rpmfdFromPyObject() into a python-level object converter, add a separate C-level getter for the fd pointer itself - take advantage of python refcounting to handle differences between native vs converted rpm.fd in callers so we can simply decref the rpmfdFromPyObject() result without having to worry whether it was converted or not (ie should we close it or not)
-rw-r--r--python/header-py.c17
-rw-r--r--python/rpmfd-py.c51
-rw-r--r--python/rpmfd-py.h6
-rw-r--r--python/rpmts-py.c22
4 files changed, 57 insertions, 39 deletions
diff --git a/python/header-py.c b/python/header-py.c
index 5ca920e84..e51ef0be7 100644
--- a/python/header-py.c
+++ b/python/header-py.c
@@ -272,19 +272,20 @@ static PyObject * hdrWrite(hdrObject *s, PyObject *args, PyObject *kwds)
{
char *kwlist[] = { "file", "magic", NULL };
int magic = 1;
- FD_t fd = NULL;
+ rpmfdObject *fdo = NULL;
int rc;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|i", kwlist,
- rpmFdFromPyObject, &fd, &magic))
+ rpmfdFromPyObject, &fdo, &magic))
return NULL;
Py_BEGIN_ALLOW_THREADS;
- rc = headerWrite(fd, s->h, magic ? HEADER_MAGIC_YES : HEADER_MAGIC_NO);
+ rc = headerWrite(rpmfdGetFd(fdo), s->h,
+ magic ? HEADER_MAGIC_YES : HEADER_MAGIC_NO);
Py_END_ALLOW_THREADS;
if (rc) PyErr_SetFromErrno(PyExc_IOError);
- Fclose(fd); /* avoid messing up errno wrt above */
+ Py_XDECREF(fdo); /* avoid messing up errno with file close */
if (rc) return NULL;
Py_RETURN_NONE;
@@ -359,8 +360,8 @@ static struct PyMethodDef hdr_methods[] = {
static PyObject *hdr_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
{
PyObject *obj = NULL;
+ rpmfdObject *fdo = NULL;
Header h = NULL;
- FD_t fd = NULL;
char *kwlist[] = { "obj", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &obj)) {
@@ -373,11 +374,11 @@ static PyObject *hdr_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
h = headerCopy(((hdrObject*) obj)->h);
} else if (PyString_Check(obj)) {
h = headerCopyLoad(PyString_AsString(obj));
- } else if (rpmFdFromPyObject(obj, &fd)) {
+ } else if (rpmfdFromPyObject(obj, &fdo)) {
Py_BEGIN_ALLOW_THREADS;
- h = headerRead(fd, HEADER_MAGIC_YES);
- Fclose(fd);
+ h = headerRead(rpmfdGetFd(fdo), HEADER_MAGIC_YES);
Py_END_ALLOW_THREADS;
+ Py_XDECREF(fdo);
} else {
PyErr_SetString(PyExc_TypeError, "header, blob or file expected");
return NULL;
diff --git a/python/rpmfd-py.c b/python/rpmfd-py.c
index 8b4f2b1a0..8458410d0 100644
--- a/python/rpmfd-py.c
+++ b/python/rpmfd-py.c
@@ -3,25 +3,36 @@
#include <rpm/rpmstring.h>
#include "rpmfd-py.h"
-int rpmFdFromPyObject(PyObject *obj, FD_t *fdp)
+struct rpmfdObject_s {
+ PyObject_HEAD
+ PyObject *md_dict;
+ FD_t fd;
+};
+
+FD_t rpmfdGetFd(rpmfdObject *fdo)
{
- FD_t fd = NULL;
+ return fdo->fd;
+}
- if (PyInt_Check(obj)) {
- fd = fdDup(PyInt_AsLong(obj));
- } else if (PyFile_Check(obj)) {
- FILE *fp = PyFile_AsFile(obj);
- fd = fdDup(fileno(fp));
+int rpmfdFromPyObject(PyObject *obj, rpmfdObject **fdop)
+{
+ rpmfdObject *fdo = NULL;
+
+ if (rpmfdObject_Check(obj)) {
+ Py_INCREF(obj);
+ fdo = (rpmfdObject *) obj;
} else {
- PyErr_SetString(PyExc_TypeError, "integer or file object expected");
- return 0;
+ fdo = (rpmfdObject *) PyObject_Call((PyObject *)&rpmfd_Type,
+ Py_BuildValue("(O)", obj), NULL);
}
- if (Ferror(fd)) {
- PyErr_SetString(PyExc_IOError, Fstrerror(fd));
- if (fd) Fclose(fd);
+ if (fdo == NULL) return 0;
+
+ if (Ferror(fdo->fd)) {
+ Py_DECREF(fdo);
+ PyErr_SetString(PyExc_IOError, Fstrerror(fdo->fd));
return 0;
}
- *fdp = fd;
+ *fdop = fdo;
return 1;
}
@@ -31,12 +42,6 @@ static PyObject *err_closed(void)
return NULL;
}
-struct rpmfdObject_s {
- PyObject_HEAD
- PyObject *md_dict;
- FD_t fd;
-};
-
static PyObject *rpmfd_new(PyTypeObject *subtype,
PyObject *args, PyObject *kwds)
{
@@ -57,7 +62,13 @@ static PyObject *rpmfd_new(PyTypeObject *subtype,
fd = Fopen(PyString_AsString(fo), m);
Py_END_ALLOW_THREADS
free(m);
- } else if (!rpmFdFromPyObject(fo, &fd)) {
+ } else if (PyInt_Check(fo)) {
+ fd = fdDup(PyInt_AsLong(fo));
+ } else if (PyFile_Check(fo)) {
+ FILE *fp = PyFile_AsFile(fo);
+ fd = fdDup(fileno(fp));
+ } else {
+ PyErr_SetString(PyExc_TypeError, "path or file object expected");
return NULL;
}
diff --git a/python/rpmfd-py.h b/python/rpmfd-py.h
index 3e2a9ca87..b84e17444 100644
--- a/python/rpmfd-py.h
+++ b/python/rpmfd-py.h
@@ -7,7 +7,11 @@ typedef struct rpmfdObject_s rpmfdObject;
extern PyTypeObject rpmfd_Type;
-int rpmFdFromPyObject(PyObject *obj, FD_t *fdp);
+#define rpmfdObject_Check(v) ((v)->ob_type == &rpmfd_Type)
+
+FD_t rpmfdGetFd(rpmfdObject *fdo);
+
+int rpmfdFromPyObject(PyObject *obj, rpmfdObject **fdop);
#endif
diff --git a/python/rpmts-py.c b/python/rpmts-py.c
index 0ac6a5cf6..e228736ca 100644
--- a/python/rpmts-py.c
+++ b/python/rpmts-py.c
@@ -137,8 +137,8 @@
struct rpmtsObject_s {
PyObject_HEAD
PyObject *md_dict; /*!< to look like PyModuleObject */
+ rpmfdObject *scriptFd;
rpmts ts;
- FD_t scriptFd;
rpmtsi tsi;
};
@@ -337,17 +337,17 @@ static PyObject *
rpmts_HdrFromFdno(rpmtsObject * s, PyObject *arg)
{
PyObject *ho = NULL;
+ rpmfdObject *fdo = NULL;
Header h;
- FD_t fd;
rpmRC rpmrc;
- if (!PyArg_Parse(arg, "O&:HdrFromFdno", rpmFdFromPyObject, &fd))
+ if (!PyArg_Parse(arg, "O&:HdrFromFdno", rpmfdFromPyObject, &fdo))
return NULL;
Py_BEGIN_ALLOW_THREADS;
- rpmrc = rpmReadPackageFile(s->ts, fd, "rpmts_HdrFromFdno", &h);
+ rpmrc = rpmReadPackageFile(s->ts, rpmfdGetFd(fdo), "rpmts_HdrFromFdno", &h);
Py_END_ALLOW_THREADS;
- Fclose(fd);
+ Py_XDECREF(fdo);
if (rpmrc == RPMRC_OK) {
ho = hdr_Wrap(&hdr_Type, h);
@@ -676,8 +676,7 @@ static void rpmts_dealloc(rpmtsObject * s)
{
s->ts = rpmtsFree(s->ts);
-
- if (s->scriptFd) Fclose(s->scriptFd);
+ Py_XDECREF(s->scriptFd);
s->ob_type->tp_free((PyObject *)s);
}
@@ -722,11 +721,14 @@ static PyObject *rpmts_get_rootDir(rpmtsObject *s, void *closure)
static int rpmts_set_scriptFd(rpmtsObject *s, PyObject *value, void *closure)
{
+ rpmfdObject *fdo = NULL;
int rc = 0;
- if (PyArg_Parse(value, "O&", rpmFdFromPyObject, &s->scriptFd)) {
- rpmtsSetScriptFd(s->ts, s->scriptFd);
+ if (PyArg_Parse(value, "O&", rpmfdFromPyObject, &fdo)) {
+ Py_XDECREF(s->scriptFd);
+ s->scriptFd = fdo;
+ rpmtsSetScriptFd(s->ts, rpmfdGetFd(s->scriptFd));
} else if (value == Py_None) {
- Fclose(s->scriptFd);
+ Py_XDECREF(s->scriptFd);
s->scriptFd = NULL;
rpmtsSetScriptFd(s->ts, NULL);
} else {