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

python/rpmfd-py.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include "Python.h"
00008 #ifdef __LCLINT__
00009 #undef  PyObject_HEAD
00010 #define PyObject_HEAD   int _PyObjectHead;
00011 #endif
00012 
00013 #include <glob.h>       /* XXX rpmio.h */
00014 #include <dirent.h>     /* XXX rpmio.h */
00015 #include <rpmio_internal.h>
00016 
00017 #include <rpmlib.h>     /* XXX _free */
00018 
00019 #include "header-py.h"  /* XXX pyrpmError */
00020 #include "rpmfd-py.h"
00021 
00022 #include "debug.h"
00023 
00024 /*@access FD_t @*/
00025 
00026 /*@unchecked@*/
00027 static int _rpmfd_debug = 1;
00028 
00035 static PyObject *
00036 rpmfd_Debug(/*@unused@*/ rpmfdObject * s, PyObject * args)
00037         /*@globals _Py_NoneStruct @*/
00038         /*@modifies _Py_NoneStruct @*/
00039 {
00040     if (!PyArg_ParseTuple(args, "i", &_rpmfd_debug)) return NULL;
00041     Py_INCREF(Py_None);
00042     return Py_None;
00043 }
00044 
00047 typedef struct FDlist_t FDlist;
00048 
00051 struct FDlist_t {
00052     FILE * f;
00053     FD_t fd;
00054     const char * note;
00055     FDlist * next;
00056 } ;
00057 
00060 static FDlist *fdhead = NULL;
00061 
00064 static FDlist *fdtail = NULL;
00065 
00068 static int closeCallback(FILE * f)
00069         /*@globals fdhead @*/
00070         /*@modifies fdhead @*/
00071 {
00072     FDlist *node, *last;
00073 
00074     node = fdhead;
00075     last = NULL;
00076     while (node) {
00077         if (node->f == f)
00078             break;
00079         last = node;
00080         node = node->next;
00081     }
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     return 0; 
00095 }
00096 
00099 static PyObject *
00100 rpmfd_Fopen(/*@unused@*/ PyObject * s, PyObject * args)
00101         /*@globals fdhead, fdtail @*/
00102         /*@modifies fdhead, fdtail @*/
00103 {
00104     char * path;
00105     char * mode = "r.ufdio";
00106     FDlist *node;
00107     
00108     if (!PyArg_ParseTuple(args, "s|s", &path, &mode))
00109         return NULL;
00110     
00111     node = xmalloc (sizeof(FDlist));
00112     
00113     node->fd = Fopen(path, mode);
00114     node->fd = fdLink(node->fd, "doFopen");
00115     node->note = xstrdup (path);
00116 
00117     if (!node->fd) {
00118         PyErr_SetFromErrno(pyrpmError);
00119         node = _free (node);
00120         return NULL;
00121     }
00122     
00123     if (Ferror(node->fd)) {
00124         const char *err = Fstrerror(node->fd);
00125         node = _free(node);
00126         if (err)
00127             PyErr_SetString(pyrpmError, err);
00128         return NULL;
00129     }
00130 
00131     node->f = fdGetFp(node->fd);
00132     if (!node->f) {
00133         PyErr_SetString(pyrpmError, "FD_t has no FILE*");
00134         free(node);
00135         return NULL;
00136     }
00137 
00138     node->next = NULL;
00139     if (!fdhead) {
00140         fdhead = fdtail = node;
00141     } else if (fdtail) {
00142         fdtail->next = node;
00143     } else {
00144         fdhead = node;
00145     }
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 
00181 static PyObject * rpmfd_getattr(rpmfdObject * o, char * name)
00182         /*@*/
00183 {
00184     return Py_FindMethod(rpmfd_methods, (PyObject *) o, name);
00185 }
00186 
00189 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds)
00190         /*@modifies s @*/
00191 {
00192     char * path;
00193     char * mode = "r.ufdio";
00194 
00195 if (_rpmfd_debug)
00196 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds);
00197 
00198     if (!PyArg_ParseTuple(args, "s|s:rpmfd_init", &path, &mode))
00199         return -1;
00200 
00201     s->fd = Fopen(path, mode);
00202 
00203     if (s->fd == NULL) {
00204         PyErr_SetFromErrno(pyrpmError);
00205         return -1;
00206     }
00207 
00208     if (Ferror(s->fd)) {
00209         const char *err = Fstrerror(s->fd);
00210         if (s->fd)
00211             Fclose(s->fd);
00212         if (err)
00213             PyErr_SetString(pyrpmError, err);
00214         return -1;
00215     }
00216     return 0;
00217 }
00218 
00221 static void rpmfd_free(/*@only@*/ rpmfdObject * s)
00222         /*@modifies s @*/
00223 {
00224 if (_rpmfd_debug)
00225 fprintf(stderr, "%p -- fd %p\n", s, s->fd);
00226     if (s->fd)
00227         Fclose(s->fd);
00228 
00229     PyObject_Del((PyObject *)s);
00230 }
00231 
00234 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems)
00235         /*@*/
00236 {
00237     PyObject * s = PyType_GenericAlloc(subtype, nitems);
00238 
00239 if (_rpmfd_debug)
00240 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s);
00241     return s;
00242 }
00243 
00246 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
00247         /*@*/
00248 {
00249     rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
00250 
00251     /* Perform additional initialization. */
00252     if (rpmfd_init(s, args, kwds) < 0) {
00253         rpmfd_free(s);
00254         return NULL;
00255     }
00256 
00257 if (_rpmfd_debug)
00258 fprintf(stderr, "%p ++ fd %p\n", s, s->fd);
00259 
00260     return s;
00261 }
00262 
00265 /*@unchecked@*/ /*@observer@*/
00266 static char rpmfd_doc[] =
00267 "";
00268 
00271 /*@-fullinitblock@*/
00272 PyTypeObject rpmfd_Type = {
00273         PyObject_HEAD_INIT(&PyType_Type)
00274         0,                              /* ob_size */
00275         "rpm.fd",                       /* tp_name */
00276         sizeof(rpmfdObject),            /* tp_size */
00277         0,                              /* tp_itemsize */
00278         /* methods */
00279         (destructor) rpmfd_dealloc,     /* tp_dealloc */
00280         0,                              /* tp_print */
00281         (getattrfunc) rpmfd_getattr,    /* tp_getattr */
00282         (setattrfunc)0,                 /* tp_setattr */
00283         (cmpfunc)0,                     /* tp_compare */
00284         (reprfunc)0,                    /* tp_repr */
00285         0,                              /* tp_as_number */
00286         0,                              /* tp_as_sequence */
00287         0,                              /* tp_as_mapping */
00288         (hashfunc)0,                    /* tp_hash */
00289         (ternaryfunc)0,                 /* tp_call */
00290         (reprfunc)0,                    /* tp_str */
00291         0,                              /* tp_getattro */
00292         0,                              /* tp_setattro */
00293         0,                              /* tp_as_buffer */
00294         Py_TPFLAGS_DEFAULT,             /* tp_flags */
00295         rpmfd_doc,                      /* tp_doc */
00296 #if Py_TPFLAGS_HAVE_ITER
00297         0,                              /* tp_traverse */
00298         0,                              /* tp_clear */
00299         0,                              /* tp_richcompare */
00300         0,                              /* tp_weaklistoffset */
00301         0,                              /* tp_iter */
00302         0,                              /* tp_iternext */
00303         rpmfd_methods,                  /* tp_methods */
00304         0,                              /* tp_members */
00305         0,                              /* tp_getset */
00306         0,                              /* tp_base */
00307         0,                              /* tp_dict */
00308         0,                              /* tp_descr_get */
00309         0,                              /* tp_descr_set */
00310         0,                              /* tp_dictoffset */
00311         (initproc) rpmfd_init,          /* tp_init */
00312         (allocfunc) rpmfd_alloc,        /* tp_alloc */
00313         (newfunc) rpmfd_new,            /* tp_new */
00314         (destructor) rpmfd_free,        /* tp_free */
00315         0,                              /* tp_is_gc */
00316 #endif
00317 };
00318 /*@=fullinitblock@*/
00319 
00320 rpmfdObject * rpmfd_Wrap(FD_t fd)
00321 {
00322     rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
00323     if (s == NULL)
00324         return NULL;
00325     s->fd = fd;
00326     return s;
00327 }

Generated on Sun Oct 26 13:02:02 2003 for rpm by doxygen1.2.18