##// END OF EJS Templates
run-tests: support running tests in parallel on windows...
run-tests: support running tests in parallel on windows Previously, we used os.spawnvp, which doesn't exist on Windows, and isn't needed anyway (the command line begins with an absolute path). We also need a slightly more convoluted way to wait for processes without specifying an order on Windows, as it lacks os.wait.

File last commit:

r17531:c133b1fb default
r18057:6b88ded2 default
Show More
_inotify.c
649 lines | 13.8 KiB | text/x-c | CLexer
Bryan O'Sullivan
Add inotify extension
r6239 /*
* _inotify.c - Python extension interfacing to the Linux inotify subsystem
*
* Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2.1 of the GNU Lesser General
Matt Mackall
Update license to GPLv2+
r10263 * Public License or any later version.
Bryan O'Sullivan
Add inotify extension
r6239 */
#include <Python.h>
#include <alloca.h>
#include <sys/inotify.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <unistd.h>
Renato Cunha
inotify: Port of the C module to py3k....
r11549 #include <util.h>
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 /* Variables used in the event string representation */
static PyObject *join;
static PyObject *er_wm;
static PyObject *er_wmc;
static PyObject *er_wmn;
static PyObject *er_wmcn;
Bryan O'Sullivan
Add inotify extension
r6239 static PyObject *init(PyObject *self, PyObject *args)
{
Matt Mackall
many, many trivial check-code fixups
r10282 PyObject *ret = NULL;
int fd = -1;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 if (!PyArg_ParseTuple(args, ":init"))
goto bail;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 Py_BEGIN_ALLOW_THREADS;
fd = inotify_init();
Py_END_ALLOW_THREADS;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (fd == -1) {
PyErr_SetFromErrno(PyExc_OSError);
goto bail;
}
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 ret = PyInt_FromLong(fd);
if (ret == NULL)
goto bail;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 goto done;
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 bail:
Matt Mackall
many, many trivial check-code fixups
r10282 if (fd != -1)
close(fd);
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 Py_CLEAR(ret);
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 done:
Matt Mackall
many, many trivial check-code fixups
r10282 return ret;
Bryan O'Sullivan
Add inotify extension
r6239 }
PyDoc_STRVAR(
Matt Mackall
many, many trivial check-code fixups
r10282 init_doc,
"init() -> fd\n"
"\n"
timeless@mozdev.org
en-us: Initialize
r17531 "Initialize an inotify instance.\n"
Matt Mackall
many, many trivial check-code fixups
r10282 "Return a file descriptor associated with a new inotify event queue.");
Bryan O'Sullivan
Add inotify extension
r6239
static PyObject *add_watch(PyObject *self, PyObject *args)
{
Matt Mackall
many, many trivial check-code fixups
r10282 PyObject *ret = NULL;
uint32_t mask;
int wd = -1;
char *path;
int fd;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (!PyArg_ParseTuple(args, "isI:add_watch", &fd, &path, &mask))
goto bail;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 Py_BEGIN_ALLOW_THREADS;
wd = inotify_add_watch(fd, path, mask);
Py_END_ALLOW_THREADS;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (wd == -1) {
PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
goto bail;
}
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 ret = PyInt_FromLong(wd);
if (ret == NULL)
goto bail;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 goto done;
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 bail:
Matt Mackall
many, many trivial check-code fixups
r10282 if (wd != -1)
inotify_rm_watch(fd, wd);
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 Py_CLEAR(ret);
Bryan O'Sullivan
Add inotify extension
r6239
done:
Matt Mackall
many, many trivial check-code fixups
r10282 return ret;
Bryan O'Sullivan
Add inotify extension
r6239 }
PyDoc_STRVAR(
Matt Mackall
many, many trivial check-code fixups
r10282 add_watch_doc,
"add_watch(fd, path, mask) -> wd\n"
"\n"
"Add a watch to an inotify instance, or modify an existing watch.\n"
"\n"
" fd: file descriptor returned by init()\n"
" path: path to watch\n"
" mask: mask of events to watch for\n"
"\n"
"Return a unique numeric watch descriptor for the inotify instance\n"
"mapped by the file descriptor.");
Bryan O'Sullivan
Add inotify extension
r6239
static PyObject *remove_watch(PyObject *self, PyObject *args)
{
Matt Mackall
many, many trivial check-code fixups
r10282 uint32_t wd;
int fd;
int r;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 if (!PyArg_ParseTuple(args, "iI:remove_watch", &fd, &wd))
return NULL;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 Py_BEGIN_ALLOW_THREADS;
r = inotify_rm_watch(fd, wd);
Py_END_ALLOW_THREADS;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (r == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 Py_INCREF(Py_None);
return Py_None;
Bryan O'Sullivan
Add inotify extension
r6239 }
PyDoc_STRVAR(
Matt Mackall
many, many trivial check-code fixups
r10282 remove_watch_doc,
"remove_watch(fd, wd)\n"
"\n"
" fd: file descriptor returned by init()\n"
" wd: watch descriptor returned by add_watch()\n"
"\n"
"Remove a watch associated with the watch descriptor wd from the\n"
"inotify instance associated with the file descriptor fd.\n"
"\n"
"Removing a watch causes an IN_IGNORED event to be generated for this\n"
"watch descriptor.");
Bryan O'Sullivan
Add inotify extension
r6239
#define bit_name(x) {x, #x}
static struct {
Matt Mackall
many, many trivial check-code fixups
r10282 int bit;
const char *name;
PyObject *pyname;
Bryan O'Sullivan
Add inotify extension
r6239 } bit_names[] = {
Matt Mackall
many, many trivial check-code fixups
r10282 bit_name(IN_ACCESS),
bit_name(IN_MODIFY),
bit_name(IN_ATTRIB),
bit_name(IN_CLOSE_WRITE),
bit_name(IN_CLOSE_NOWRITE),
bit_name(IN_OPEN),
bit_name(IN_MOVED_FROM),
bit_name(IN_MOVED_TO),
bit_name(IN_CREATE),
bit_name(IN_DELETE),
bit_name(IN_DELETE_SELF),
bit_name(IN_MOVE_SELF),
bit_name(IN_UNMOUNT),
bit_name(IN_Q_OVERFLOW),
bit_name(IN_IGNORED),
bit_name(IN_ONLYDIR),
bit_name(IN_DONT_FOLLOW),
bit_name(IN_MASK_ADD),
bit_name(IN_ISDIR),
bit_name(IN_ONESHOT),
{0}
Bryan O'Sullivan
Add inotify extension
r6239 };
static PyObject *decode_mask(int mask)
{
Matt Mackall
many, many trivial check-code fixups
r10282 PyObject *ret = PyList_New(0);
int i;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (ret == NULL)
goto bail;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 for (i = 0; bit_names[i].bit; i++) {
if (mask & bit_names[i].bit) {
if (bit_names[i].pyname == NULL) {
bit_names[i].pyname = PyString_FromString(bit_names[i].name);
if (bit_names[i].pyname == NULL)
goto bail;
}
Py_INCREF(bit_names[i].pyname);
if (PyList_Append(ret, bit_names[i].pyname) == -1)
goto bail;
}
Bryan O'Sullivan
Add inotify extension
r6239 }
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 goto done;
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 bail:
Matt Mackall
many, many trivial check-code fixups
r10282 Py_CLEAR(ret);
Bryan O'Sullivan
Add inotify extension
r6239
done:
Matt Mackall
many, many trivial check-code fixups
r10282 return ret;
Bryan O'Sullivan
Add inotify extension
r6239 }
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 static PyObject *pydecode_mask(PyObject *self, PyObject *args)
{
Matt Mackall
many, many trivial check-code fixups
r10282 int mask;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 if (!PyArg_ParseTuple(args, "i:decode_mask", &mask))
return NULL;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 return decode_mask(mask);
Bryan O'Sullivan
Add inotify extension
r6239 }
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 PyDoc_STRVAR(
Matt Mackall
many, many trivial check-code fixups
r10282 decode_mask_doc,
"decode_mask(mask) -> list_of_strings\n"
"\n"
"Decode an inotify mask value into a list of strings that give the\n"
"name of each bit set in the mask.");
Bryan O'Sullivan
Add inotify extension
r6239
static char doc[] = "Low-level inotify interface wrappers.";
static void define_const(PyObject *dict, const char *name, uint32_t val)
{
Matt Mackall
many, many trivial check-code fixups
r10282 PyObject *pyval = PyInt_FromLong(val);
PyObject *pyname = PyString_FromString(name);
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (!pyname || !pyval)
goto bail;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 PyDict_SetItem(dict, pyname, pyval);
Bryan O'Sullivan
Add inotify extension
r6239
bail:
Matt Mackall
many, many trivial check-code fixups
r10282 Py_XDECREF(pyname);
Py_XDECREF(pyval);
Bryan O'Sullivan
Add inotify extension
r6239 }
static void define_consts(PyObject *dict)
{
Matt Mackall
many, many trivial check-code fixups
r10282 define_const(dict, "IN_ACCESS", IN_ACCESS);
define_const(dict, "IN_MODIFY", IN_MODIFY);
define_const(dict, "IN_ATTRIB", IN_ATTRIB);
define_const(dict, "IN_CLOSE_WRITE", IN_CLOSE_WRITE);
define_const(dict, "IN_CLOSE_NOWRITE", IN_CLOSE_NOWRITE);
define_const(dict, "IN_OPEN", IN_OPEN);
define_const(dict, "IN_MOVED_FROM", IN_MOVED_FROM);
define_const(dict, "IN_MOVED_TO", IN_MOVED_TO);
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 define_const(dict, "IN_CLOSE", IN_CLOSE);
define_const(dict, "IN_MOVE", IN_MOVE);
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 define_const(dict, "IN_CREATE", IN_CREATE);
define_const(dict, "IN_DELETE", IN_DELETE);
define_const(dict, "IN_DELETE_SELF", IN_DELETE_SELF);
define_const(dict, "IN_MOVE_SELF", IN_MOVE_SELF);
define_const(dict, "IN_UNMOUNT", IN_UNMOUNT);
define_const(dict, "IN_Q_OVERFLOW", IN_Q_OVERFLOW);
define_const(dict, "IN_IGNORED", IN_IGNORED);
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 define_const(dict, "IN_ONLYDIR", IN_ONLYDIR);
define_const(dict, "IN_DONT_FOLLOW", IN_DONT_FOLLOW);
define_const(dict, "IN_MASK_ADD", IN_MASK_ADD);
define_const(dict, "IN_ISDIR", IN_ISDIR);
define_const(dict, "IN_ONESHOT", IN_ONESHOT);
define_const(dict, "IN_ALL_EVENTS", IN_ALL_EVENTS);
Bryan O'Sullivan
Add inotify extension
r6239 }
struct event {
Matt Mackall
many, many trivial check-code fixups
r10282 PyObject_HEAD
PyObject *wd;
PyObject *mask;
PyObject *cookie;
PyObject *name;
Bryan O'Sullivan
Add inotify extension
r6239 };
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 static PyObject *event_wd(PyObject *self, void *x)
{
Matt Mackall
many, many trivial check-code fixups
r10282 struct event *evt = (struct event *)self;
Py_INCREF(evt->wd);
return evt->wd;
Bryan O'Sullivan
Add inotify extension
r6239 }
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 static PyObject *event_mask(PyObject *self, void *x)
{
Matt Mackall
many, many trivial check-code fixups
r10282 struct event *evt = (struct event *)self;
Py_INCREF(evt->mask);
return evt->mask;
Bryan O'Sullivan
Add inotify extension
r6239 }
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 static PyObject *event_cookie(PyObject *self, void *x)
{
Matt Mackall
many, many trivial check-code fixups
r10282 struct event *evt = (struct event *)self;
Py_INCREF(evt->cookie);
return evt->cookie;
Bryan O'Sullivan
Add inotify extension
r6239 }
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 static PyObject *event_name(PyObject *self, void *x)
{
Matt Mackall
many, many trivial check-code fixups
r10282 struct event *evt = (struct event *)self;
Py_INCREF(evt->name);
return evt->name;
Bryan O'Sullivan
Add inotify extension
r6239 }
static struct PyGetSetDef event_getsets[] = {
Matt Mackall
many, many trivial check-code fixups
r10282 {"wd", event_wd, NULL,
"watch descriptor"},
{"mask", event_mask, NULL,
"event mask"},
{"cookie", event_cookie, NULL,
"rename cookie, if rename-related event"},
{"name", event_name, NULL,
"file name"},
{NULL}
Bryan O'Sullivan
Add inotify extension
r6239 };
PyDoc_STRVAR(
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 event_doc,
"event: Structure describing an inotify event.");
Bryan O'Sullivan
Add inotify extension
r6239
static PyObject *event_new(PyTypeObject *t, PyObject *a, PyObject *k)
{
Matt Mackall
many, many trivial check-code fixups
r10282 return (*t->tp_alloc)(t, 0);
Bryan O'Sullivan
Add inotify extension
r6239 }
static void event_dealloc(struct event *evt)
{
Matt Mackall
many, many trivial check-code fixups
r10282 Py_XDECREF(evt->wd);
Py_XDECREF(evt->mask);
Py_XDECREF(evt->cookie);
Py_XDECREF(evt->name);
Thomas Arendsen Hein
tab/space cleanup
r6334
Renato Cunha
inotify: make proper use of Python API to get object size....
r11547 Py_TYPE(evt)->tp_free(evt);
Bryan O'Sullivan
Add inotify extension
r6239 }
static PyObject *event_repr(struct event *evt)
{
Matt Mackall
many, many trivial check-code fixups
r10282 int cookie = evt->cookie == Py_None ? -1 : PyInt_AsLong(evt->cookie);
PyObject *ret = NULL, *pymasks = NULL, *pymask = NULL;
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 PyObject *tuple = NULL, *formatstr = NULL;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 pymasks = decode_mask(PyInt_AsLong(evt->mask));
if (pymasks == NULL)
goto bail;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 pymask = _PyString_Join(join, pymasks);
if (pymask == NULL)
goto bail;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 if (evt->name != Py_None) {
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 if (cookie == -1) {
formatstr = er_wmn;
tuple = PyTuple_Pack(3, evt->wd, pymask, evt->name);
}
else {
formatstr = er_wmcn;
tuple = PyTuple_Pack(4, evt->wd, pymask,
evt->cookie, evt->name);
}
Matt Mackall
many, many trivial check-code fixups
r10282 } else {
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 if (cookie == -1) {
formatstr = er_wm;
tuple = PyTuple_Pack(2, evt->wd, pymask);
}
Matt Mackall
many, many trivial check-code fixups
r10282 else {
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 formatstr = er_wmc;
tuple = PyTuple_Pack(3, evt->wd, pymask, evt->cookie);
Matt Mackall
many, many trivial check-code fixups
r10282 }
Bryan O'Sullivan
Add inotify extension
r6239 }
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 if (tuple == NULL)
goto bail;
ret = PyNumber_Remainder(formatstr, tuple);
if (ret == NULL)
goto bail;
Matt Mackall
many, many trivial check-code fixups
r10282 goto done;
Bryan O'Sullivan
Add inotify extension
r6239 bail:
Matt Mackall
many, many trivial check-code fixups
r10282 Py_CLEAR(ret);
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 done:
Matt Mackall
many, many trivial check-code fixups
r10282 Py_XDECREF(pymask);
Py_XDECREF(pymasks);
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 Py_XDECREF(tuple);
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 return ret;
Bryan O'Sullivan
Add inotify extension
r6239 }
static PyTypeObject event_type = {
Renato Cunha
inotify: Port of the C module to py3k....
r11549 PyVarObject_HEAD_INIT(NULL, 0)
Matt Mackall
many, many trivial check-code fixups
r10282 "_inotify.event", /*tp_name*/
sizeof(struct event), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)event_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)event_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
event_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
event_getsets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
event_new, /* tp_new */
Bryan O'Sullivan
Add inotify extension
r6239 };
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 PyObject *read_events(PyObject *self, PyObject *args)
{
Matt Mackall
many, many trivial check-code fixups
r10282 PyObject *ctor_args = NULL;
PyObject *pybufsize = NULL;
PyObject *ret = NULL;
int bufsize = 65536;
char *buf = NULL;
int nread, pos;
int fd;
if (!PyArg_ParseTuple(args, "i|O:read", &fd, &pybufsize))
goto bail;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (pybufsize && pybufsize != Py_None)
bufsize = PyInt_AsLong(pybufsize);
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 ret = PyList_New(0);
if (ret == NULL)
goto bail;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 if (bufsize <= 0) {
int r;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 Py_BEGIN_ALLOW_THREADS;
r = ioctl(fd, FIONREAD, &bufsize);
Py_END_ALLOW_THREADS;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 if (r == -1) {
PyErr_SetFromErrno(PyExc_OSError);
goto bail;
}
if (bufsize == 0)
goto done;
Bryan O'Sullivan
Add inotify extension
r6239 }
Matt Mackall
many, many trivial check-code fixups
r10282 else {
static long name_max;
static long name_fd = -1;
long min;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 if (name_fd != fd) {
name_fd = fd;
Py_BEGIN_ALLOW_THREADS;
name_max = fpathconf(fd, _PC_NAME_MAX);
Py_END_ALLOW_THREADS;
}
min = sizeof(struct inotify_event) + name_max + 1;
if (bufsize < min) {
PyErr_Format(PyExc_ValueError,
"bufsize must be at least %d", (int)min);
goto bail;
}
Bryan O'Sullivan
Add inotify extension
r6239 }
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 buf = alloca(bufsize);
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 Py_BEGIN_ALLOW_THREADS;
nread = read(fd, buf, bufsize);
Py_END_ALLOW_THREADS;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (nread == -1) {
PyErr_SetFromErrno(PyExc_OSError);
goto bail;
Bryan O'Sullivan
Add inotify extension
r6239 }
Matt Mackall
many, many trivial check-code fixups
r10282 ctor_args = PyTuple_New(0);
if (ctor_args == NULL)
goto bail;
pos = 0;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 while (pos < nread) {
struct inotify_event *in = (struct inotify_event *)(buf + pos);
struct event *evt;
PyObject *obj;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 obj = PyObject_CallObject((PyObject *)&event_type, ctor_args);
if (obj == NULL)
goto bail;
evt = (struct event *)obj;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 evt->wd = PyInt_FromLong(in->wd);
evt->mask = PyInt_FromLong(in->mask);
if (in->mask & IN_MOVE)
evt->cookie = PyInt_FromLong(in->cookie);
else {
Py_INCREF(Py_None);
evt->cookie = Py_None;
}
if (in->len)
evt->name = PyString_FromString(in->name);
else {
Py_INCREF(Py_None);
evt->name = Py_None;
}
if (!evt->wd || !evt->mask || !evt->cookie || !evt->name)
goto mybail;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (PyList_Append(ret, obj) == -1)
goto mybail;
pos += sizeof(struct inotify_event) + in->len;
continue;
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 mybail:
Py_CLEAR(evt->wd);
Py_CLEAR(evt->mask);
Py_CLEAR(evt->cookie);
Py_CLEAR(evt->name);
Py_DECREF(obj);
goto bail;
}
goto done;
Bryan O'Sullivan
Add inotify extension
r6239
bail:
Matt Mackall
many, many trivial check-code fixups
r10282 Py_CLEAR(ret);
Thomas Arendsen Hein
tab/space cleanup
r6334
Bryan O'Sullivan
Add inotify extension
r6239 done:
Matt Mackall
many, many trivial check-code fixups
r10282 Py_XDECREF(ctor_args);
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 return ret;
Bryan O'Sullivan
Add inotify extension
r6239 }
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 static int init_globals(void)
{
join = PyString_FromString("|");
er_wm = PyString_FromString("event(wd=%d, mask=%s)");
er_wmn = PyString_FromString("event(wd=%d, mask=%s, name=%s)");
er_wmc = PyString_FromString("event(wd=%d, mask=%s, cookie=0x%x)");
er_wmcn = PyString_FromString("event(wd=%d, mask=%s, cookie=0x%x, name=%s)");
return join && er_wm && er_wmn && er_wmc && er_wmcn;
}
Bryan O'Sullivan
Add inotify extension
r6239 PyDoc_STRVAR(
Matt Mackall
many, many trivial check-code fixups
r10282 read_doc,
"read(fd, bufsize[=65536]) -> list_of_events\n"
"\n"
"\nRead inotify events from a file descriptor.\n"
"\n"
" fd: file descriptor returned by init()\n"
" bufsize: size of buffer to read into, in bytes\n"
"\n"
"Return a list of event objects.\n"
"\n"
"If bufsize is > 0, block until events are available to be read.\n"
"Otherwise, immediately return all events that can be read without\n"
"blocking.");
Bryan O'Sullivan
Add inotify extension
r6239
static PyMethodDef methods[] = {
Matt Mackall
many, many trivial check-code fixups
r10282 {"init", init, METH_VARARGS, init_doc},
{"add_watch", add_watch, METH_VARARGS, add_watch_doc},
{"remove_watch", remove_watch, METH_VARARGS, remove_watch_doc},
{"read", read_events, METH_VARARGS, read_doc},
{"decode_mask", pydecode_mask, METH_VARARGS, decode_mask_doc},
{NULL},
Bryan O'Sullivan
Add inotify extension
r6239 };
Renato Cunha
inotify: Port of the C module to py3k....
r11549 #ifdef IS_PY3K
static struct PyModuleDef _inotify_module = {
PyModuleDef_HEAD_INIT,
"_inotify",
doc,
-1,
methods
};
PyMODINIT_FUNC PyInit__inotify(void)
{
PyObject *mod, *dict;
mod = PyModule_Create(&_inotify_module);
if (mod == NULL)
return NULL;
if (!init_globals())
return;
dict = PyModule_GetDict(mod);
if (dict)
define_consts(dict);
return mod;
}
#else
Bryan O'Sullivan
Add inotify extension
r6239 void init_inotify(void)
{
Matt Mackall
many, many trivial check-code fixups
r10282 PyObject *mod, *dict;
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 if (PyType_Ready(&event_type) == -1)
return;
Bryan O'Sullivan
Add inotify extension
r6239
Renato Cunha
inotify: Better implementation of the event string representation....
r11548 if (!init_globals())
return;
Matt Mackall
many, many trivial check-code fixups
r10282 mod = Py_InitModule3("_inotify", methods, doc);
Bryan O'Sullivan
Add inotify extension
r6239
Matt Mackall
many, many trivial check-code fixups
r10282 dict = PyModule_GetDict(mod);
Thomas Arendsen Hein
tab/space cleanup
r6334
Matt Mackall
many, many trivial check-code fixups
r10282 if (dict)
define_consts(dict);
Bryan O'Sullivan
Add inotify extension
r6239 }
Renato Cunha
inotify: Port of the C module to py3k....
r11549 #endif