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

Generated on Fri Oct 12 08:44:54 2007 for rpm by  doxygen 1.5.2