Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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

Generated on Sun Aug 21 21:56:40 2005 for rpm by  doxygen 1.3.9.1