- Main Page
- Related Pages
- Modules
- Data Structures
- Files

# python/rpmfd-py.c

Go to the documentation of this file.

    00001
    00005 #include "system.h"
    00006
    00007 #include <glob.h>       /* XXX rpmio.h */
    00008 #include <dirent.h>     /* XXX rpmio.h */
    00009 #include <rpmio_internal.h>
    00010 #include <rpmcb.h>              /* XXX fnpyKey */
    00011
    00012 #include <rpmlib.h>     /* XXX _free */
    00013
    00014 #include "header-py.h"  /* XXX pyrpmError */
    00015 #include "rpmfd-py.h"
    00016
    00017 #include "debug.h"
    00018
    00019 /*@access FD_t @*/
    00020
    00021 /*@unchecked@*/
    00022 static int _rpmfd_debug = 1;
    00023
    00032 typedef struct FDlist_t FDlist;
    00033
    00036 struct FDlist_t {
    00037     FILE * f;
    00038     FD_t fd;
    00039     const char * note;
    00040     FDlist * next;
    00041 } ;
    00042
    00045 static FDlist *fdhead = NULL;
    00046
    00049 static FDlist *fdtail = NULL;
    00050
    00053 static int closeCallback(FILE * f)
    00054         /*@globals fdhead @*/
    00055         /*@modifies fdhead @*/
    00056 {
    00057     FDlist *node, *last;
    00058
    00059     node = fdhead;
    00060     last = NULL;
    00061     while (node) {
    00062         if (node->f == f)
    00063             break;
    00064         last = node;
    00065         node = node->next;
    00066     }
    00067 /*@-branchstate@*/
    00068     if (node) {
    00069         if (last)
    00070             last->next = node->next;
    00071         else
    00072             fdhead = node->next;
    00073         node->note = _free (node->note);
    00074         node->fd = fdLink(node->fd, "closeCallback");
    00075         (void) Fclose (node->fd);
    00076         while (node->fd)
    00077             node->fd = fdFree(node->fd, "closeCallback");
    00078         node = _free (node);
    00079     }
    00080 /*@=branchstate@*/
    00081     return 0;
    00082 }
    00083
    00090 /*@null@*/
    00091 static PyObject *
    00092 rpmfd_Debug(/*@unused@*/ rpmfdObject * s, PyObject * args, PyObject * kwds)
    00093         /*@globals _Py_NoneStruct @*/
    00094         /*@modifies _Py_NoneStruct @*/
    00095 {
    00096     char * kwlist[] = {"debugLevel", NULL};
    00097
    00098     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfd_debug))
    00099         return NULL;
    00100
    00101     Py_INCREF(Py_None);
    00102     return Py_None;
    00103 }
    00104
    00107 /*@null@*/
    00108 static PyObject *
    00109 rpmfd_Fopen(/*@unused@*/ PyObject * s, PyObject * args, PyObject * kwds)
    00110         /*@globals fdhead, fdtail @*/
    00111         /*@modifies fdhead, fdtail @*/
    00112 {
    00113     char * path;
    00114     char * mode = "r.fdio";
    00115     FDlist *node;
    00116     char * kwlist[] = {"path", "mode", NULL};
    00117
    00118     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &path, &mode))
    00119         return NULL;
    00120
    00121     node = xmalloc (sizeof(FDlist));
    00122
    00123     node->fd = Fopen(path, mode);
    00124     node->fd = fdLink(node->fd, "doFopen");
    00125     node->note = xstrdup (path);
    00126
    00127     if (!node->fd) {
    00128         (void) PyErr_SetFromErrno(pyrpmError);
    00129         node = _free (node);
    00130         return NULL;
    00131     }
    00132
    00133     if (Ferror(node->fd)) {
    00134         const char *err = Fstrerror(node->fd);
    00135         node = _free(node);
    00136         if (err)
    00137             PyErr_SetString(pyrpmError, err);
    00138         return NULL;
    00139     }
    00140
    00141     node->f = fdGetFp(node->fd);
    00142     if (!node->f) {
    00143         PyErr_SetString(pyrpmError, "FD_t has no FILE*");
    00144         free(node);
    00145         return NULL;
    00146     }
    00147
    00148     node->next = NULL;
    00149 /*@-branchstate@*/
    00150     if (!fdhead) {
    00151         fdhead = fdtail = node;
    00152     } else if (fdtail) {
    00153         fdtail->next = node;
    00154     } else {
    00155         fdhead = node;
    00156     }
    00157 /*@=branchstate@*/
    00158     fdtail = node;
    00159
    00160     return PyFile_FromFile (node->f, path, mode, closeCallback);
    00161 }
    00162
    00167 /*@-fullinitblock@*/
    00168 /*@unchecked@*/ /*@observer@*/
    00169 static struct PyMethodDef rpmfd_methods[] = {
    00170     {"Debug",   (PyCFunction)rpmfd_Debug,       METH_VARARGS|METH_KEYWORDS,
    00171         NULL},
    00172     {"Fopen",   (PyCFunction)rpmfd_Fopen,       METH_VARARGS|METH_KEYWORDS,
    00173         NULL},
    00174     {NULL,              NULL}           /* sentinel */
    00175 };
    00176 /*@=fullinitblock@*/
    00177
    00178 /* ---------- */
    00179
    00182 static void
    00183 rpmfd_dealloc(/*@only@*/ /*@null@*/ rpmfdObject * s)
    00184         /*@modifies s @*/
    00185 {
    00186     if (s) {
    00187         Fclose(s->fd);
    00188         s->fd = NULL;
    00189         PyObject_Del(s);
    00190     }
    00191 }
    00192
    00193 static PyObject * rpmfd_getattro(PyObject * o, PyObject * n)
    00194         /*@*/
    00195 {
    00196     return PyObject_GenericGetAttr(o, n);
    00197 }
    00198
    00199 static int rpmfd_setattro(PyObject * o, PyObject * n, PyObject * v)
    00200         /*@*/
    00201 {
    00202     return PyObject_GenericSetAttr(o, n, v);
    00203 }
    00204
    00207 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds)
    00208         /*@modifies s @*/
    00209 {
    00210     char * path;
    00211     char * mode = "r";
    00212     char * kwlist[] = {"path", "mode", NULL};
    00213
    00214 if (_rpmfd_debug)
    00215 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds);
    00216
    00217     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:rpmfd_init", kwlist,
    00218             &path, &mode))
    00219         return -1;
    00220
    00221     s->fd = Fopen(path, mode);
    00222
    00223     if (s->fd == NULL) {
    00224         (void) PyErr_SetFromErrno(pyrpmError);
    00225         return -1;
    00226     }
    00227
    00228     if (Ferror(s->fd)) {
    00229         const char *err = Fstrerror(s->fd);
    00230         if (s->fd)
    00231             Fclose(s->fd);
    00232         if (err)
    00233             PyErr_SetString(pyrpmError, err);
    00234         return -1;
    00235     }
    00236     return 0;
    00237 }
    00238
    00241 static void rpmfd_free(/*@only@*/ rpmfdObject * s)
    00242         /*@modifies s @*/
    00243 {
    00244 if (_rpmfd_debug)
    00245 fprintf(stderr, "%p -- fd %p\n", s, s->fd);
    00246     if (s->fd)
    00247         Fclose(s->fd);
    00248
    00249     PyObject_Del((PyObject *)s);
    00250 }
    00251
    00254 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems)
    00255         /*@*/
    00256 {
    00257     PyObject * s = PyType_GenericAlloc(subtype, nitems);
    00258
    00259 if (_rpmfd_debug)
    00260 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s);
    00261     return s;
    00262 }
    00263
    00266 /*@null@*/
    00267 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
    00268         /*@*/
    00269 {
    00270     rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
    00271
    00272     /* Perform additional initialization. */
    00273     if (rpmfd_init(s, args, kwds) < 0) {
    00274         rpmfd_free(s);
    00275         return NULL;
    00276     }
    00277
    00278 if (_rpmfd_debug)
    00279 fprintf(stderr, "%p ++ fd %p\n", s, s->fd);
    00280
    00281     return s;
    00282 }
    00283
    00286 /*@unchecked@*/ /*@observer@*/
    00287 static char rpmfd_doc[] =
    00288 "";
    00289
    00292 /*@-fullinitblock@*/
    00293 PyTypeObject rpmfd_Type = {
    00294         PyObject_HEAD_INIT(&PyType_Type)
    00295         0,                              /* ob_size */
    00296         "rpm.fd",                       /* tp_name */
    00297         sizeof(rpmfdObject),            /* tp_size */
    00298         0,                              /* tp_itemsize */
    00299         /* methods */
    00300         (destructor) rpmfd_dealloc,     /* tp_dealloc */
    00301         0,                              /* tp_print */
    00302         (getattrfunc)0,                 /* tp_getattr */
    00303         (setattrfunc)0,                 /* tp_setattr */
    00304         (cmpfunc)0,                     /* tp_compare */
    00305         (reprfunc)0,                    /* tp_repr */
    00306         0,                              /* tp_as_number */
    00307         0,                              /* tp_as_sequence */
    00308         0,                              /* tp_as_mapping */
    00309         (hashfunc)0,                    /* tp_hash */
    00310         (ternaryfunc)0,                 /* tp_call */
    00311         (reprfunc)0,                    /* tp_str */
    00312         (getattrofunc) rpmfd_getattro,  /* tp_getattro */
    00313         (setattrofunc) rpmfd_setattro,  /* tp_setattro */
    00314         0,                              /* tp_as_buffer */
    00315         Py_TPFLAGS_DEFAULT,             /* tp_flags */
    00316         rpmfd_doc,                      /* tp_doc */
    00317 #if Py_TPFLAGS_HAVE_ITER
    00318         0,                              /* tp_traverse */
    00319         0,                              /* tp_clear */
    00320         0,                              /* tp_richcompare */
    00321         0,                              /* tp_weaklistoffset */
    00322         0,                              /* tp_iter */
    00323         0,                              /* tp_iternext */
    00324         rpmfd_methods,                  /* tp_methods */
    00325         0,                              /* tp_members */
    00326         0,                              /* tp_getset */
    00327         0,                              /* tp_base */
    00328         0,                              /* tp_dict */
    00329         0,                              /* tp_descr_get */
    00330         0,                              /* tp_descr_set */
    00331         0,                              /* tp_dictoffset */
    00332         (initproc) rpmfd_init,          /* tp_init */
    00333         (allocfunc) rpmfd_alloc,        /* tp_alloc */
    00334         (newfunc) rpmfd_new,            /* tp_new */
    00335         (freefunc) rpmfd_free,          /* tp_free */
    00336         0,                              /* tp_is_gc */
    00337 #endif
    00338 };
    00339 /*@=fullinitblock@*/
    00340
    00341 rpmfdObject * rpmfd_Wrap(FD_t fd)
    00342 {
    00343     rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
    00344     if (s == NULL)
    00345         return NULL;
    00346     s->fd = fd;
    00347     return s;
    00348 }