rpm  5.2.1
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;
39  const char * note;
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 
343 {
344  rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
345  if (s == NULL)
346  return NULL;
347  s->fd = fd;
348  return s;
349 }