Mercurial > hg
annotate hgext/inotify/linux/_inotify.c @ 6379:d2bb66a8a435
hgweb: add compatibility code for old templates
Up to changeset 3340aa5a64f7, HTTP headers were expected to be embedded
in the "headers" template. Since that changeset, the content-type is
supposed to be defined as the "mimetype" template in the map file.
This changeset makes sure the old templates still work.
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Mon, 24 Mar 2008 13:45:01 -0300 |
parents | 7016f7fb8fe3 |
children | 5d6659cfaa06 |
rev | line source |
---|---|
6239 | 1 /* |
2 * _inotify.c - Python extension interfacing to the Linux inotify subsystem | |
3 * | |
4 * Copyright 2006 Bryan O'Sullivan <bos@serpentine.com> | |
5 * | |
6 * This library is free software; you can redistribute it and/or | |
7 * modify it under the terms of version 2.1 of the GNU Lesser General | |
8 * Public License, incorporated herein by reference. | |
9 */ | |
10 | |
11 #include <Python.h> | |
12 #include <alloca.h> | |
13 #include <sys/inotify.h> | |
14 #include <stdint.h> | |
15 #include <sys/ioctl.h> | |
16 #include <unistd.h> | |
17 | |
18 static PyObject *init(PyObject *self, PyObject *args) | |
19 { | |
20 PyObject *ret = NULL; | |
21 int fd = -1; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
22 |
6239 | 23 if (!PyArg_ParseTuple(args, ":init")) |
24 goto bail; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
25 |
6239 | 26 Py_BEGIN_ALLOW_THREADS |
27 fd = inotify_init(); | |
28 Py_END_ALLOW_THREADS | |
29 | |
30 if (fd == -1) { | |
31 PyErr_SetFromErrno(PyExc_OSError); | |
32 goto bail; | |
33 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
34 |
6239 | 35 ret = PyInt_FromLong(fd); |
36 if (ret == NULL) | |
37 goto bail; | |
38 | |
39 goto done; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
40 |
6239 | 41 bail: |
42 if (fd != -1) | |
43 close(fd); | |
44 | |
45 Py_CLEAR(ret); | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
46 |
6239 | 47 done: |
48 return ret; | |
49 } | |
50 | |
51 PyDoc_STRVAR( | |
52 init_doc, | |
53 "init() -> fd\n" | |
54 "\n" | |
55 "Initialise an inotify instance.\n" | |
56 "Return a file descriptor associated with a new inotify event queue."); | |
57 | |
58 static PyObject *add_watch(PyObject *self, PyObject *args) | |
59 { | |
60 PyObject *ret = NULL; | |
61 uint32_t mask; | |
62 int wd = -1; | |
63 char *path; | |
64 int fd; | |
65 | |
66 if (!PyArg_ParseTuple(args, "isI:add_watch", &fd, &path, &mask)) | |
67 goto bail; | |
68 | |
69 Py_BEGIN_ALLOW_THREADS | |
70 wd = inotify_add_watch(fd, path, mask); | |
71 Py_END_ALLOW_THREADS | |
72 | |
73 if (wd == -1) { | |
74 PyErr_SetFromErrnoWithFilename(PyExc_OSError, path); | |
75 goto bail; | |
76 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
77 |
6239 | 78 ret = PyInt_FromLong(wd); |
79 if (ret == NULL) | |
80 goto bail; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
81 |
6239 | 82 goto done; |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
83 |
6239 | 84 bail: |
85 if (wd != -1) | |
86 inotify_rm_watch(fd, wd); | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
87 |
6239 | 88 Py_CLEAR(ret); |
89 | |
90 done: | |
91 return ret; | |
92 } | |
93 | |
94 PyDoc_STRVAR( | |
95 add_watch_doc, | |
96 "add_watch(fd, path, mask) -> wd\n" | |
97 "\n" | |
98 "Add a watch to an inotify instance, or modify an existing watch.\n" | |
99 "\n" | |
100 " fd: file descriptor returned by init()\n" | |
101 " path: path to watch\n" | |
102 " mask: mask of events to watch for\n" | |
103 "\n" | |
104 "Return a unique numeric watch descriptor for the inotify instance\n" | |
105 "mapped by the file descriptor."); | |
106 | |
107 static PyObject *remove_watch(PyObject *self, PyObject *args) | |
108 { | |
109 PyObject *ret = NULL; | |
110 uint32_t wd; | |
111 int fd; | |
112 int r; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
113 |
6239 | 114 if (!PyArg_ParseTuple(args, "iI:remove_watch", &fd, &wd)) |
115 goto bail; | |
116 | |
117 Py_BEGIN_ALLOW_THREADS | |
118 r = inotify_rm_watch(fd, wd); | |
119 Py_END_ALLOW_THREADS | |
120 | |
121 if (r == -1) { | |
122 PyErr_SetFromErrno(PyExc_OSError); | |
123 goto bail; | |
124 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
125 |
6239 | 126 Py_INCREF(Py_None); |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
127 |
6239 | 128 goto done; |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
129 |
6239 | 130 bail: |
131 Py_CLEAR(ret); | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
132 |
6239 | 133 done: |
134 return ret; | |
135 } | |
136 | |
137 PyDoc_STRVAR( | |
138 remove_watch_doc, | |
139 "remove_watch(fd, wd)\n" | |
140 "\n" | |
141 " fd: file descriptor returned by init()\n" | |
142 " wd: watch descriptor returned by add_watch()\n" | |
143 "\n" | |
144 "Remove a watch associated with the watch descriptor wd from the\n" | |
145 "inotify instance associated with the file descriptor fd.\n" | |
146 "\n" | |
147 "Removing a watch causes an IN_IGNORED event to be generated for this\n" | |
148 "watch descriptor."); | |
149 | |
150 #define bit_name(x) {x, #x} | |
151 | |
152 static struct { | |
153 int bit; | |
154 const char *name; | |
155 PyObject *pyname; | |
156 } bit_names[] = { | |
157 bit_name(IN_ACCESS), | |
158 bit_name(IN_MODIFY), | |
159 bit_name(IN_ATTRIB), | |
160 bit_name(IN_CLOSE_WRITE), | |
161 bit_name(IN_CLOSE_NOWRITE), | |
162 bit_name(IN_OPEN), | |
163 bit_name(IN_MOVED_FROM), | |
164 bit_name(IN_MOVED_TO), | |
165 bit_name(IN_CREATE), | |
166 bit_name(IN_DELETE), | |
167 bit_name(IN_DELETE_SELF), | |
168 bit_name(IN_MOVE_SELF), | |
169 bit_name(IN_UNMOUNT), | |
170 bit_name(IN_Q_OVERFLOW), | |
171 bit_name(IN_IGNORED), | |
172 bit_name(IN_ONLYDIR), | |
173 bit_name(IN_DONT_FOLLOW), | |
174 bit_name(IN_MASK_ADD), | |
175 bit_name(IN_ISDIR), | |
176 bit_name(IN_ONESHOT), | |
177 {0} | |
178 }; | |
179 | |
180 static PyObject *decode_mask(int mask) | |
181 { | |
182 PyObject *ret = PyList_New(0); | |
183 int i; | |
184 | |
185 if (ret == NULL) | |
186 goto bail; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
187 |
6239 | 188 for (i = 0; bit_names[i].bit; i++) { |
189 if (mask & bit_names[i].bit) { | |
190 if (bit_names[i].pyname == NULL) { | |
191 bit_names[i].pyname = PyString_FromString(bit_names[i].name); | |
192 if (bit_names[i].pyname == NULL) | |
193 goto bail; | |
194 } | |
195 Py_INCREF(bit_names[i].pyname); | |
196 if (PyList_Append(ret, bit_names[i].pyname) == -1) | |
197 goto bail; | |
198 } | |
199 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
200 |
6239 | 201 goto done; |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
202 |
6239 | 203 bail: |
204 Py_CLEAR(ret); | |
205 | |
206 done: | |
207 return ret; | |
208 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
209 |
6239 | 210 static PyObject *pydecode_mask(PyObject *self, PyObject *args) |
211 { | |
212 int mask; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
213 |
6239 | 214 if (!PyArg_ParseTuple(args, "i:decode_mask", &mask)) |
215 return NULL; | |
216 | |
217 return decode_mask(mask); | |
218 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
219 |
6239 | 220 PyDoc_STRVAR( |
221 decode_mask_doc, | |
222 "decode_mask(mask) -> list_of_strings\n" | |
223 "\n" | |
224 "Decode an inotify mask value into a list of strings that give the\n" | |
225 "name of each bit set in the mask."); | |
226 | |
227 static char doc[] = "Low-level inotify interface wrappers."; | |
228 | |
229 static void define_const(PyObject *dict, const char *name, uint32_t val) | |
230 { | |
231 PyObject *pyval = PyInt_FromLong(val); | |
232 PyObject *pyname = PyString_FromString(name); | |
233 | |
234 if (!pyname || !pyval) | |
235 goto bail; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
236 |
6239 | 237 PyDict_SetItem(dict, pyname, pyval); |
238 | |
239 bail: | |
240 Py_XDECREF(pyname); | |
241 Py_XDECREF(pyval); | |
242 } | |
243 | |
244 static void define_consts(PyObject *dict) | |
245 { | |
246 define_const(dict, "IN_ACCESS", IN_ACCESS); | |
247 define_const(dict, "IN_MODIFY", IN_MODIFY); | |
248 define_const(dict, "IN_ATTRIB", IN_ATTRIB); | |
249 define_const(dict, "IN_CLOSE_WRITE", IN_CLOSE_WRITE); | |
250 define_const(dict, "IN_CLOSE_NOWRITE", IN_CLOSE_NOWRITE); | |
251 define_const(dict, "IN_OPEN", IN_OPEN); | |
252 define_const(dict, "IN_MOVED_FROM", IN_MOVED_FROM); | |
253 define_const(dict, "IN_MOVED_TO", IN_MOVED_TO); | |
254 | |
255 define_const(dict, "IN_CLOSE", IN_CLOSE); | |
256 define_const(dict, "IN_MOVE", IN_MOVE); | |
257 | |
258 define_const(dict, "IN_CREATE", IN_CREATE); | |
259 define_const(dict, "IN_DELETE", IN_DELETE); | |
260 define_const(dict, "IN_DELETE_SELF", IN_DELETE_SELF); | |
261 define_const(dict, "IN_MOVE_SELF", IN_MOVE_SELF); | |
262 define_const(dict, "IN_UNMOUNT", IN_UNMOUNT); | |
263 define_const(dict, "IN_Q_OVERFLOW", IN_Q_OVERFLOW); | |
264 define_const(dict, "IN_IGNORED", IN_IGNORED); | |
265 | |
266 define_const(dict, "IN_ONLYDIR", IN_ONLYDIR); | |
267 define_const(dict, "IN_DONT_FOLLOW", IN_DONT_FOLLOW); | |
268 define_const(dict, "IN_MASK_ADD", IN_MASK_ADD); | |
269 define_const(dict, "IN_ISDIR", IN_ISDIR); | |
270 define_const(dict, "IN_ONESHOT", IN_ONESHOT); | |
271 define_const(dict, "IN_ALL_EVENTS", IN_ALL_EVENTS); | |
272 } | |
273 | |
274 struct event { | |
275 PyObject_HEAD | |
276 PyObject *wd; | |
277 PyObject *mask; | |
278 PyObject *cookie; | |
279 PyObject *name; | |
280 }; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
281 |
6239 | 282 static PyObject *event_wd(PyObject *self, void *x) |
283 { | |
284 struct event *evt = (struct event *) self; | |
285 Py_INCREF(evt->wd); | |
286 return evt->wd; | |
287 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
288 |
6239 | 289 static PyObject *event_mask(PyObject *self, void *x) |
290 { | |
291 struct event *evt = (struct event *) self; | |
292 Py_INCREF(evt->mask); | |
293 return evt->mask; | |
294 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
295 |
6239 | 296 static PyObject *event_cookie(PyObject *self, void *x) |
297 { | |
298 struct event *evt = (struct event *) self; | |
299 Py_INCREF(evt->cookie); | |
300 return evt->cookie; | |
301 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
302 |
6239 | 303 static PyObject *event_name(PyObject *self, void *x) |
304 { | |
305 struct event *evt = (struct event *) self; | |
306 Py_INCREF(evt->name); | |
307 return evt->name; | |
308 } | |
309 | |
310 static struct PyGetSetDef event_getsets[] = { | |
311 {"wd", event_wd, NULL, | |
312 "watch descriptor"}, | |
313 {"mask", event_mask, NULL, | |
314 "event mask"}, | |
315 {"cookie", event_cookie, NULL, | |
316 "rename cookie, if rename-related event"}, | |
317 {"name", event_name, NULL, | |
318 "file name"}, | |
319 {NULL} | |
320 }; | |
321 | |
322 PyDoc_STRVAR( | |
323 event_doc, | |
324 "event: Structure describing an inotify event."); | |
325 | |
326 static PyObject *event_new(PyTypeObject *t, PyObject *a, PyObject *k) | |
327 { | |
328 return (*t->tp_alloc)(t, 0); | |
329 } | |
330 | |
331 static void event_dealloc(struct event *evt) | |
332 { | |
333 Py_XDECREF(evt->wd); | |
334 Py_XDECREF(evt->mask); | |
335 Py_XDECREF(evt->cookie); | |
336 Py_XDECREF(evt->name); | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
337 |
6239 | 338 (*evt->ob_type->tp_free)(evt); |
339 } | |
340 | |
341 static PyObject *event_repr(struct event *evt) | |
342 { | |
343 int wd = PyInt_AsLong(evt->wd); | |
344 int cookie = evt->cookie == Py_None ? -1 : PyInt_AsLong(evt->cookie); | |
345 PyObject *ret = NULL, *pymasks = NULL, *pymask = NULL; | |
346 PyObject *join = NULL; | |
347 char *maskstr; | |
348 | |
349 join = PyString_FromString("|"); | |
350 if (join == NULL) | |
351 goto bail; | |
352 | |
353 pymasks = decode_mask(PyInt_AsLong(evt->mask)); | |
354 if (pymasks == NULL) | |
355 goto bail; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
356 |
6239 | 357 pymask = _PyString_Join(join, pymasks); |
358 if (pymask == NULL) | |
359 goto bail; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
360 |
6239 | 361 maskstr = PyString_AsString(pymask); |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
362 |
6239 | 363 if (evt->name != Py_None) { |
364 PyObject *pyname = PyString_Repr(evt->name, 1); | |
365 char *name = pyname ? PyString_AsString(pyname) : "???"; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
366 |
6239 | 367 if (cookie == -1) |
368 ret = PyString_FromFormat("event(wd=%d, mask=%s, name=%s)", | |
369 wd, maskstr, name); | |
370 else | |
371 ret = PyString_FromFormat("event(wd=%d, mask=%s, " | |
372 "cookie=0x%x, name=%s)", | |
373 wd, maskstr, cookie, name); | |
374 | |
375 Py_XDECREF(pyname); | |
376 } else { | |
377 if (cookie == -1) | |
378 ret = PyString_FromFormat("event(wd=%d, mask=%s)", | |
379 wd, maskstr); | |
380 else { | |
381 ret = PyString_FromFormat("event(wd=%d, mask=%s, cookie=0x%x)", | |
382 wd, maskstr, cookie); | |
383 } | |
384 } | |
385 | |
386 goto done; | |
387 bail: | |
388 Py_CLEAR(ret); | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
389 |
6239 | 390 done: |
391 Py_XDECREF(pymask); | |
392 Py_XDECREF(pymasks); | |
393 Py_XDECREF(join); | |
394 | |
395 return ret; | |
396 } | |
397 | |
398 static PyTypeObject event_type = { | |
399 PyObject_HEAD_INIT(NULL) | |
400 0, /*ob_size*/ | |
401 "_inotify.event", /*tp_name*/ | |
402 sizeof(struct event), /*tp_basicsize*/ | |
403 0, /*tp_itemsize*/ | |
404 (destructor)event_dealloc, /*tp_dealloc*/ | |
405 0, /*tp_print*/ | |
406 0, /*tp_getattr*/ | |
407 0, /*tp_setattr*/ | |
408 0, /*tp_compare*/ | |
409 (reprfunc)event_repr, /*tp_repr*/ | |
410 0, /*tp_as_number*/ | |
411 0, /*tp_as_sequence*/ | |
412 0, /*tp_as_mapping*/ | |
413 0, /*tp_hash */ | |
414 0, /*tp_call*/ | |
415 0, /*tp_str*/ | |
416 0, /*tp_getattro*/ | |
417 0, /*tp_setattro*/ | |
418 0, /*tp_as_buffer*/ | |
419 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
420 event_doc, /* tp_doc */ | |
421 0, /* tp_traverse */ | |
422 0, /* tp_clear */ | |
423 0, /* tp_richcompare */ | |
424 0, /* tp_weaklistoffset */ | |
425 0, /* tp_iter */ | |
426 0, /* tp_iternext */ | |
427 0, /* tp_methods */ | |
428 0, /* tp_members */ | |
429 event_getsets, /* tp_getset */ | |
430 0, /* tp_base */ | |
431 0, /* tp_dict */ | |
432 0, /* tp_descr_get */ | |
433 0, /* tp_descr_set */ | |
434 0, /* tp_dictoffset */ | |
435 0, /* tp_init */ | |
436 0, /* tp_alloc */ | |
437 event_new, /* tp_new */ | |
438 }; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
439 |
6239 | 440 PyObject *read_events(PyObject *self, PyObject *args) |
441 { | |
442 PyObject *ctor_args = NULL; | |
443 PyObject *pybufsize = NULL; | |
444 PyObject *ret = NULL; | |
445 int bufsize = 65536; | |
446 char *buf = NULL; | |
447 int nread, pos; | |
448 int fd; | |
449 | |
450 if (!PyArg_ParseTuple(args, "i|O:read", &fd, &pybufsize)) | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
451 goto bail; |
6239 | 452 |
453 if (pybufsize && pybufsize != Py_None) | |
454 bufsize = PyInt_AsLong(pybufsize); | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
455 |
6239 | 456 ret = PyList_New(0); |
457 if (ret == NULL) | |
458 goto bail; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
459 |
6239 | 460 if (bufsize <= 0) { |
461 int r; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
462 |
6239 | 463 Py_BEGIN_ALLOW_THREADS |
464 r = ioctl(fd, FIONREAD, &bufsize); | |
465 Py_END_ALLOW_THREADS | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
466 |
6239 | 467 if (r == -1) { |
468 PyErr_SetFromErrno(PyExc_OSError); | |
469 goto bail; | |
470 } | |
471 if (bufsize == 0) | |
472 goto done; | |
473 } | |
474 else { | |
475 static long name_max; | |
476 static long name_fd = -1; | |
477 long min; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
478 |
6239 | 479 if (name_fd != fd) { |
480 name_fd = fd; | |
481 Py_BEGIN_ALLOW_THREADS | |
482 name_max = fpathconf(fd, _PC_NAME_MAX); | |
483 Py_END_ALLOW_THREADS | |
484 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
485 |
6239 | 486 min = sizeof(struct inotify_event) + name_max + 1; |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
487 |
6239 | 488 if (bufsize < min) { |
489 PyErr_Format(PyExc_ValueError, "bufsize must be at least %d", | |
490 (int) min); | |
491 goto bail; | |
492 } | |
493 } | |
494 | |
495 buf = alloca(bufsize); | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
496 |
6239 | 497 Py_BEGIN_ALLOW_THREADS |
498 nread = read(fd, buf, bufsize); | |
499 Py_END_ALLOW_THREADS | |
500 | |
501 if (nread == -1) { | |
502 PyErr_SetFromErrno(PyExc_OSError); | |
503 goto bail; | |
504 } | |
505 | |
506 ctor_args = PyTuple_New(0); | |
507 | |
508 if (ctor_args == NULL) | |
509 goto bail; | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
510 |
6239 | 511 pos = 0; |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
512 |
6239 | 513 while (pos < nread) { |
514 struct inotify_event *in = (struct inotify_event *) (buf + pos); | |
515 struct event *evt; | |
516 PyObject *obj; | |
517 | |
518 obj = PyObject_CallObject((PyObject *) &event_type, ctor_args); | |
519 | |
520 if (obj == NULL) | |
521 goto bail; | |
522 | |
523 evt = (struct event *) obj; | |
524 | |
525 evt->wd = PyInt_FromLong(in->wd); | |
526 evt->mask = PyInt_FromLong(in->mask); | |
527 if (in->mask & IN_MOVE) | |
528 evt->cookie = PyInt_FromLong(in->cookie); | |
529 else { | |
530 Py_INCREF(Py_None); | |
531 evt->cookie = Py_None; | |
532 } | |
533 if (in->len) | |
534 evt->name = PyString_FromString(in->name); | |
535 else { | |
536 Py_INCREF(Py_None); | |
537 evt->name = Py_None; | |
538 } | |
539 | |
540 if (!evt->wd || !evt->mask || !evt->cookie || !evt->name) | |
541 goto mybail; | |
542 | |
543 if (PyList_Append(ret, obj) == -1) | |
544 goto mybail; | |
545 | |
546 pos += sizeof(struct inotify_event) + in->len; | |
547 continue; | |
548 | |
549 mybail: | |
550 Py_CLEAR(evt->wd); | |
551 Py_CLEAR(evt->mask); | |
552 Py_CLEAR(evt->cookie); | |
553 Py_CLEAR(evt->name); | |
554 Py_DECREF(obj); | |
555 | |
556 goto bail; | |
557 } | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
558 |
6239 | 559 goto done; |
560 | |
561 bail: | |
562 Py_CLEAR(ret); | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
563 |
6239 | 564 done: |
565 Py_XDECREF(ctor_args); | |
566 | |
567 return ret; | |
568 } | |
569 | |
570 PyDoc_STRVAR( | |
571 read_doc, | |
572 "read(fd, bufsize[=65536]) -> list_of_events\n" | |
573 "\n" | |
574 "\nRead inotify events from a file descriptor.\n" | |
575 "\n" | |
576 " fd: file descriptor returned by init()\n" | |
577 " bufsize: size of buffer to read into, in bytes\n" | |
578 "\n" | |
579 "Return a list of event objects.\n" | |
580 "\n" | |
581 "If bufsize is > 0, block until events are available to be read.\n" | |
582 "Otherwise, immediately return all events that can be read without\n" | |
583 "blocking."); | |
584 | |
585 | |
586 static PyMethodDef methods[] = { | |
587 {"init", init, METH_VARARGS, init_doc}, | |
588 {"add_watch", add_watch, METH_VARARGS, add_watch_doc}, | |
589 {"remove_watch", remove_watch, METH_VARARGS, remove_watch_doc}, | |
590 {"read", read_events, METH_VARARGS, read_doc}, | |
591 {"decode_mask", pydecode_mask, METH_VARARGS, decode_mask_doc}, | |
592 {NULL}, | |
593 }; | |
594 | |
595 void init_inotify(void) | |
596 { | |
597 PyObject *mod, *dict; | |
598 | |
599 if (PyType_Ready(&event_type) == -1) | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
600 return; |
6239 | 601 |
602 mod = Py_InitModule3("_inotify", methods, doc); | |
603 | |
604 dict = PyModule_GetDict(mod); | |
6334
7016f7fb8fe3
tab/space cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6239
diff
changeset
|
605 |
6239 | 606 if (dict) |
607 define_consts(dict); | |
608 } |