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