rpm 5.2.1

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

- File List
- Globals

rpmfd-py.c
Go to the documentation of this file.
1
5 #include "system.h"
6
7 #include <glob.h> /* XXX rpmio.h */
8 #include <dirent.h> /* XXX rpmio.h */
9 #include <rpmio_internal.h>
10 #include <rpmcb.h> /* XXX fnpyKey */
11 #include <rpmtypes.h>
12 #include <rpmtag.h>
13
14 #include "header-py.h" /* XXX pyrpmError */
15 #include "rpmfd-py.h"
16
17 #include "debug.h"
18
19 /*@access FD_t @*/
20
21 /*@unchecked@*/
22 static int _rpmfd_debug = 1;
23
32 typedef struct FDlist_t FDlist;
33
36 struct FDlist_t {
37 FILE * f;
38 FD_t fd;
39 const char * note;
40 FDlist * next;
41 } ;
42
45 static FDlist *fdhead = NULL;
46
49 static FDlist *fdtail = NULL;
50
53 static int closeCallback(FILE * f)
54 /*@globals fdhead @*/
55 /*@modifies fdhead @*/
56 {
57 FDlist *node, *last;
58
59 node = fdhead;
60 last = NULL;
61 while (node) {
62 if (node->f == f)
63 break;
64 last = node;
65 node = node->next;
66 }
67 /*@-branchstate@*/
68 if (node) {
69 if (last)
70 last->next = node->next;
71 else
72 fdhead = node->next;
73 node->note = _free (node->note);
74 node->fd = fdLink(node->fd, "closeCallback");
75 (void) Fclose (node->fd);
76 while (node->fd)
77 node->fd = fdFree(node->fd, "closeCallback");
78 node = _free (node);
79 }
80 /*@=branchstate@*/
81 return 0;
82 }
83
90 /*@null@*/
91 static PyObject *
92 rpmfd_Debug(/*@unused@*/ rpmfdObject * s, PyObject * args,
93 PyObject * kwds)
94 /*@globals _Py_NoneStruct @*/
95 /*@modifies _Py_NoneStruct @*/
96 {
97 char * kwlist[] = {"debugLevel", NULL};
98
99 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfd_debug))
100 return NULL;
101
102 Py_INCREF(Py_None);
103 return Py_None;
104 }
105
108 /*@null@*/
109 static PyObject *
110 rpmfd_Fopen(/*@unused@*/ PyObject * s, PyObject * args, PyObject * kwds)
111 /*@globals fdhead, fdtail @*/
112 /*@modifies fdhead, fdtail @*/
113 {
114 char * path;
115 char * mode = "r.fdio";
116 FDlist *node;
117 char * kwlist[] = {"path", "mode", NULL};
118
119 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &path, &mode))
120 return NULL;
121
122 node = xmalloc (sizeof(FDlist));
123
124 node->fd = Fopen(path, mode);
125 node->fd = fdLink(node->fd, "doFopen");
126 node->note = xstrdup (path);
127
128 if (!node->fd) {
129 (void) PyErr_SetFromErrno(pyrpmError);
130 node = _free (node);
131 return NULL;
132 }
133
134 if (Ferror(node->fd)) {
135 const char *err = Fstrerror(node->fd);
136 node = _free(node);
137 if (err)
138 PyErr_SetString(pyrpmError, err);
139 return NULL;
140 }
141
142 node->f = fdGetFp(node->fd);
143 if (!node->f) {
144 PyErr_SetString(pyrpmError, "FD_t has no FILE*");
145 free(node);
146 return NULL;
147 }
148
149 node->next = NULL;
150 /*@-branchstate@*/
151 if (!fdhead) {
152 fdhead = fdtail = node;
153 } else if (fdtail) {
154 fdtail->next = node;
155 } else {
156 fdhead = node;
157 }
158 /*@=branchstate@*/
159 fdtail = node;
160
161 return PyFile_FromFile (node->f, path, mode, closeCallback);
162 }
163
168 /*@-fullinitblock@*/
169 /*@unchecked@*/ /*@observer@*/
170 static struct PyMethodDef rpmfd_methods[] = {
171 {"Debug", (PyCFunction)rpmfd_Debug, METH_VARARGS|METH_KEYWORDS,
172 NULL},
173 {"Fopen", (PyCFunction)rpmfd_Fopen, METH_VARARGS|METH_KEYWORDS,
174 NULL},
175 {NULL, NULL} /* sentinel */
176 };
177 /*@=fullinitblock@*/
178
179 /* ---------- */
180
183 static void
184 rpmfd_dealloc(/*@only@*/ /*@null@*/ rpmfdObject * s)
185 /*@modifies s @*/
186 {
187 if (s) {
188 Fclose(s->fd);
189 s->fd = NULL;
190 PyObject_Del(s);
191 }
192 }
193
194 static PyObject * rpmfd_getattro(PyObject * o, PyObject * n)
195 /*@*/
196 {
197 return PyObject_GenericGetAttr(o, n);
198 }
199
200 static int rpmfd_setattro(PyObject * o, PyObject * n, PyObject * v)
201 /*@*/
202 {
203 return PyObject_GenericSetAttr(o, n, v);
204 }
205
208 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds)
209 /*@modifies s @*/
210 {
211 char * path;
212 char * mode = "r";
213 char * kwlist[] = {"path", "mode", NULL};
214
215 if (_rpmfd_debug)
216 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds);
217
218 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:rpmfd_init", kwlist,
219 &path, &mode))
220 return -1;
221
222 s->fd = Fopen(path, mode);
223
224 if (s->fd == NULL) {
225 (void) PyErr_SetFromErrno(pyrpmError);
226 return -1;
227 }
228
229 if (Ferror(s->fd)) {
230 const char *err = Fstrerror(s->fd);
231 if (s->fd)
232 Fclose(s->fd);
233 if (err)
234 PyErr_SetString(pyrpmError, err);
235 return -1;
236 }
237 return 0;
238 }
239
242 static void rpmfd_free(/*@only@*/ rpmfdObject * s)
243 /*@modifies s @*/
244 {
245 if (_rpmfd_debug)
246 fprintf(stderr, "%p -- fd %p\n", s, s->fd);
247 if (s->fd)
248 Fclose(s->fd);
249
250 PyObject_Del((PyObject *)s);
251 }
252
255 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems)
256 /*@*/
257 {
258 PyObject * s = PyType_GenericAlloc(subtype, nitems);
259
260 if (_rpmfd_debug)
261 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s);
262 return s;
263 }
264
267 /*@null@*/
268 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
269 /*@*/
270 {
271 rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
272
273 /* Perform additional initialization. */
274 if (rpmfd_init(s, args, kwds) < 0) {
275 rpmfd_free(s);
276 return NULL;
277 }
278
279 if (_rpmfd_debug)
280 fprintf(stderr, "%p ++ fd %p\n", s, s->fd);
281
282 return s;
283 }
284
287 /*@unchecked@*/ /*@observer@*/
288 static char rpmfd_doc[] =
289 "";
290
293 /*@-fullinitblock@*/
294 PyTypeObject rpmfd_Type = {
295 PyObject_HEAD_INIT(&PyType_Type)
296 0, /* ob_size */
297 "rpm.fd", /* tp_name */
298 sizeof(rpmfdObject), /* tp_size */
299 0, /* tp_itemsize */
300 /* methods */
301 (destructor) rpmfd_dealloc, /* tp_dealloc */
302 0, /* tp_print */
303 (getattrfunc)0, /* tp_getattr */
304 (setattrfunc)0, /* tp_setattr */
305 (cmpfunc)0, /* tp_compare */
306 (reprfunc)0, /* tp_repr */
307 0, /* tp_as_number */
308 0, /* tp_as_sequence */
309 0, /* tp_as_mapping */
310 (hashfunc)0, /* tp_hash */
311 (ternaryfunc)0, /* tp_call */
312 (reprfunc)0, /* tp_str */
313 (getattrofunc) rpmfd_getattro, /* tp_getattro */
314 (setattrofunc) rpmfd_setattro, /* tp_setattro */
315 0, /* tp_as_buffer */
316 Py_TPFLAGS_DEFAULT, /* tp_flags */
317 rpmfd_doc, /* tp_doc */
318 #if Py_TPFLAGS_HAVE_ITER
319 0, /* tp_traverse */
320 0, /* tp_clear */
321 0, /* tp_richcompare */
322 0, /* tp_weaklistoffset */
323 0, /* tp_iter */
324 0, /* tp_iternext */
325 rpmfd_methods, /* tp_methods */
326 0, /* tp_members */
327 0, /* tp_getset */
328 0, /* tp_base */
329 0, /* tp_dict */
330 0, /* tp_descr_get */
331 0, /* tp_descr_set */
332 0, /* tp_dictoffset */
333 (initproc) rpmfd_init, /* tp_init */
334 (allocfunc) rpmfd_alloc, /* tp_alloc */
335 (newfunc) rpmfd_new, /* tp_new */
336 (freefunc) rpmfd_free, /* tp_free */
337 0, /* tp_is_gc */
338 #endif
339 };
340 /*@=fullinitblock@*/
341
342 rpmfdObject * rpmfd_Wrap(FD_t fd)
343 {
344 rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
345 if (s == NULL)
346 return NULL;
347 s->fd = fd;
348 return s;
349 }