• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

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 }

Generated on Mon Nov 29 2010 05:18:45 for rpm by  doxygen 1.7.2