rpm  5.4.15
rpmfd-py.c
Go to the documentation of this file.
1 
5 #include "system-py.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_RETURN_NONE;
103 }
104 
107 /*@null@*/
108 static PyObject *
109 rpmfd_Fopen(/*@unused@*/ PyObject * s, PyObject * args, PyObject * kwds)
110  /*@globals fdhead, fdtail @*/
111  /*@modifies fdhead, fdtail @*/
112 {
113  char * path;
114  char * mode = "r.fdio";
115  FDlist *node;
116  char * kwlist[] = {"path", "mode", NULL};
117 
118  if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &path, &mode))
119  return NULL;
120 
121  node = xmalloc (sizeof(FDlist));
122 
123  node->fd = Fopen(path, mode);
124  node->fd = fdLink(node->fd, "doFopen");
125  node->note = xstrdup (path);
126 
127  if (!node->fd) {
128  (void) PyErr_SetFromErrno(pyrpmError);
129  node = _free (node);
130  return NULL;
131  }
132 
133  if (Ferror(node->fd)) {
134  const char *err = Fstrerror(node->fd);
135  node = _free(node);
136  if (err)
137  PyErr_SetString(pyrpmError, err);
138  return NULL;
139  }
140 
141  node->f = fdGetFp(node->fd);
142  if (!node->f) {
143  PyErr_SetString(pyrpmError, "FD_t has no FILE*");
144  free(node);
145  return NULL;
146  }
147 
148  node->next = NULL;
149 /*@-branchstate@*/
150  if (!fdhead) {
151  fdhead = fdtail = node;
152  } else if (fdtail) {
153  fdtail->next = node;
154  } else {
155  fdhead = node;
156  }
157 /*@=branchstate@*/
158  fdtail = node;
159 
160  return PyFile_FromFile (node->f, path, mode, closeCallback);
161 }
162 
167 /*@-fullinitblock@*/
168 /*@unchecked@*/ /*@observer@*/
169 static struct PyMethodDef rpmfd_methods[] = {
170  {"Debug", (PyCFunction)rpmfd_Debug, METH_VARARGS|METH_KEYWORDS,
171  NULL},
172  {"Fopen", (PyCFunction)rpmfd_Fopen, METH_VARARGS|METH_KEYWORDS,
173  NULL},
174  {NULL, NULL} /* sentinel */
175 };
176 /*@=fullinitblock@*/
177 
178 /* ---------- */
179 
182 static void
183 rpmfd_dealloc(/*@only@*/ /*@null@*/ rpmfdObject * s)
184  /*@modifies s @*/
185 {
186  if (s) {
187  Fclose(s->fd);
188  s->fd = NULL;
189  PyObject_Del(s);
190  }
191 }
192 
195 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds)
196  /*@modifies s @*/
197 {
198  char * path;
199  char * mode = "r";
200  char * kwlist[] = {"path", "mode", NULL};
201 
202 if (_rpmfd_debug)
203 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds);
204 
205  if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:rpmfd_init", kwlist,
206  &path, &mode))
207  return -1;
208 
209  s->fd = Fopen(path, mode);
210 
211  if (s->fd == NULL) {
212  (void) PyErr_SetFromErrno(pyrpmError);
213  return -1;
214  }
215 
216  if (Ferror(s->fd)) {
217  const char *err = Fstrerror(s->fd);
218  if (s->fd)
219  Fclose(s->fd);
220  if (err)
221  PyErr_SetString(pyrpmError, err);
222  return -1;
223  }
224  return 0;
225 }
226 
229 static void rpmfd_free(/*@only@*/ rpmfdObject * s)
230  /*@modifies s @*/
231 {
232 if (_rpmfd_debug)
233 fprintf(stderr, "%p -- fd %p\n", s, s->fd);
234  if (s->fd)
235  Fclose(s->fd);
236 
237  PyObject_Del((PyObject *)s);
238 }
239 
242 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems)
243  /*@*/
244 {
245  PyObject * s = PyType_GenericAlloc(subtype, nitems);
246 
247 if (_rpmfd_debug)
248 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s);
249  return s;
250 }
251 
254 /*@null@*/
255 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
256  /*@*/
257 {
258  rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
259 
260  /* Perform additional initialization. */
261  if (rpmfd_init(s, args, kwds) < 0) {
262  rpmfd_free(s);
263  return NULL;
264  }
265 
266 if (_rpmfd_debug)
267 fprintf(stderr, "%p ++ fd %p\n", s, s->fd);
268 
269  return s;
270 }
271 
274 /*@unchecked@*/ /*@observer@*/
275 static char rpmfd_doc[] =
276 "";
277 
280 /*@-fullinitblock@*/
281 PyTypeObject rpmfd_Type = {
282  PyVarObject_HEAD_INIT(&PyType_Type, 0)
283  "rpm.fd", /* tp_name */
284  sizeof(rpmfdObject), /* tp_size */
285  0, /* tp_itemsize */
286  /* methods */
287  (destructor) rpmfd_dealloc, /* tp_dealloc */
288  0, /* tp_print */
289  (getattrfunc)0, /* tp_getattr */
290  (setattrfunc)0, /* tp_setattr */
291  (cmpfunc)0, /* tp_compare */
292  (reprfunc)0, /* tp_repr */
293  0, /* tp_as_number */
294  0, /* tp_as_sequence */
295  0, /* tp_as_mapping */
296  (hashfunc)0, /* tp_hash */
297  (ternaryfunc)0, /* tp_call */
298  (reprfunc)0, /* tp_str */
299  PyObject_GenericGetAttr, /* tp_getattro */
300  PyObject_GenericSetAttr, /* tp_setattro */
301  0, /* tp_as_buffer */
302  Py_TPFLAGS_DEFAULT, /* tp_flags */
303  rpmfd_doc, /* tp_doc */
304 #if Py_TPFLAGS_HAVE_ITER
305  0, /* tp_traverse */
306  0, /* tp_clear */
307  0, /* tp_richcompare */
308  0, /* tp_weaklistoffset */
309  0, /* tp_iter */
310  0, /* tp_iternext */
311  rpmfd_methods, /* tp_methods */
312  0, /* tp_members */
313  0, /* tp_getset */
314  0, /* tp_base */
315  0, /* tp_dict */
316  0, /* tp_descr_get */
317  0, /* tp_descr_set */
318  0, /* tp_dictoffset */
319  (initproc) rpmfd_init, /* tp_init */
320  (allocfunc) rpmfd_alloc, /* tp_alloc */
321  (newfunc) rpmfd_new, /* tp_new */
322  (freefunc) rpmfd_free, /* tp_free */
323  0, /* tp_is_gc */
324 #endif
325 };
326 /*@=fullinitblock@*/
327 
329 {
330  rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
331  if (s == NULL)
332  return NULL;
333  s->fd = fd;
334  return s;
335 }
FILE * f
Definition: rpmfd-py.c:37
static void rpmfd_dealloc(rpmfdObject *s)
Definition: rpmfd-py.c:183
static int _rpmfd_debug
Definition: rpmfd-py.c:22
static int rpmfd_init(rpmfdObject *s, PyObject *args, PyObject *kwds)
Definition: rpmfd-py.c:195
static void rpmfd_free(rpmfdObject *s)
Definition: rpmfd-py.c:229
static void * fdGetFp(FD_t fd)
static FDlist * fdtail
Definition: rpmfd-py.c:49
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2840
const char * note
Definition: rpmfd-py.c:39
FD_t fd
Definition: rpmfd-py.c:38
FD_t fdLink(void *cookie, const char *msg)
static int closeCallback(FILE *f)
Definition: rpmfd-py.c:53
static PyObject * rpmfd_Fopen(PyObject *s, PyObject *args, PyObject *kwds)
Definition: rpmfd-py.c:109
const char * Fstrerror(FD_t fd)
strerror(3) clone.
Definition: rpmio.c:2401
const char * mode
Definition: mongo.h:440
FD_t fdFree(FD_t fd, const char *msg)
rpmfdObject * rpmfd_Wrap(FD_t fd)
Definition: rpmfd-py.c:328
FDlist * next
Definition: rpmfd-py.c:40
mongo_error_t err
Definition: mongo.h:922
static PyObject * rpmfd_Debug(rpmfdObject *s, PyObject *args, PyObject *kwds)
Definition: rpmfd-py.c:92
The FD_t File Handle data structure.
static FDlist * fdhead
Definition: rpmfd-py.c:45
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2534
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2951
PyTypeObject rpmfd_Type
Definition: rpmfd-py.c:281
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
struct rpmfdObject_s rpmfdObject
PyObject * pyrpmError
Definition: rpmmodule.c:51
static struct PyMethodDef rpmfd_methods[]
Definition: rpmfd-py.c:169
#define xmalloc
Definition: system.h:32
static char rpmfd_doc[]
Definition: rpmfd-py.c:275
static PyObject * rpmfd_alloc(PyTypeObject *subtype, int nitems)
Definition: rpmfd-py.c:242
static rpmfdObject * rpmfd_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
Definition: rpmfd-py.c:255
static int nitems
Definition: rpmcache.c:81