Author: tack
Date: Sun Mar 26 23:53:53 2006
New Revision: 1357
Added:
trunk/beacon/src/inotify/
trunk/beacon/src/inotify/__init__.py
trunk/beacon/src/inotify/fallback-inotify-syscalls.h
trunk/beacon/src/inotify/fallback-inotify.h
trunk/beacon/src/inotify/inotify.c
trunk/beacon/test/
trunk/beacon/test/inotify.py
Removed:
trunk/beacon/src/inotify.py
Modified:
trunk/beacon/setup.py
Log:
Add INotify API.
Modified: trunk/beacon/setup.py
==============================================================================
--- trunk/beacon/setup.py (original)
+++ trunk/beacon/setup.py Sun Mar 26 23:53:53 2006
@@ -40,28 +40,47 @@
print 'kaa.base not installed'
sys.exit(1)
-ext = Extension("kaa.beacon.thumbnail.libthumb",
- ["src/thumbnail/thumbnail.c", "src/thumbnail/png.c" ],
- config='src/thumbnail/config.h')
+thumb_ext = Extension("kaa.beacon.thumbnail.libthumb",
+ ["src/thumbnail/thumbnail.c", "src/thumbnail/png.c" ],
+ config='src/thumbnail/config.h')
-if not ext.check_library('imlib2', '1.1.1'):
+if not thumb_ext.check_library('imlib2', '1.1.1'):
print 'Imlib2 >= 1.1.1 not found'
print 'Download from http://enlightenment.freedesktop.org/'
sys.exit(1)
-if not ext.check_library('libpng', '1.2.0'):
+if not thumb_ext.check_library('libpng', '1.2.0'):
print 'libpng >= 1.2.0 not found'
sys.exit(1)
-if ext.check_library('epeg', '0.9'):
+if thumb_ext.check_library('epeg', '0.9'):
print 'epeg extention enabled'
- ext.config('#define USE_EPEG')
+ thumb_ext.config('#define USE_EPEG')
else:
print 'epeg extention disabled'
+
+inotify_ext = Extension("kaa.beacon.inotify._inotify",
+ ["src/inotify/inotify.c"],
+ config='src/inotify/config.h')
+
+ext_modules = [ thumb_ext, inotify_ext ]
+
+if not inotify_ext.check_cc(["<sys/inotify.h>"], "inotify_init();"):
+ if not inotify_ext.check_cc(["<sys/syscall.h>"], "syscall(0);"):
+ print "inotify not enabled: doesn't look like a Linux system."
+ ext_modules.remove(inotify_ext)
+ else:
+ print "inotify not supported in glibc; using fallback."
+ inotify_ext.config("#define USE_FALLBACK")
+
+else:
+ print "inotify supported by glibc; good."
+
+
setup (module = 'beacon',
version = '0.1',
description = "Media-oriented virtual filesystem",
scripts = [ 'bin/kaa-thumb', 'bin/beacon' ],
- ext_modules = [ ext ]
+ ext_modules = ext_modules
)
Added: trunk/beacon/src/inotify/__init__.py
==============================================================================
--- (empty file)
+++ trunk/beacon/src/inotify/__init__.py Sun Mar 26 23:53:53 2006
@@ -0,0 +1,115 @@
+try:
+ from kaa.beacon.inotify import _inotify
+except ImportError:
+ _inotify = None
+
+import kaa
+import os
+import struct
+
+
+class INotify:
+
+ def __init__(self):
+ if not _inotify:
+ self._fd = -1
+ raise SystemError, "INotify support not compiled."
+
+ self.signals = {
+ # Master signal: this signal gets emitted on all events.
+ "event": kaa.notifier.Signal()
+ }
+
+ self._watches = {}
+ self._read_buffer = ""
+
+ self._fd = _inotify.init()
+ if self._fd < 0:
+ raise SystemError, "INotify support not detected on this system."
+
+ self._mon = kaa.notifier.WeakSocketDispatcher(self._handle_data)
+ self._mon.register(self._fd)
+
+
+ def __del__(self):
+ if self._fd >= 0:
+ os.close(self._fd)
+ self._mon.unregister()
+
+
+ def watch(self, path, mask = None):
+ """
+ Adds a watch to the given path. The default mask is anything that
+ causes a change (new file, deleted file, modified file, or attribute
+ change on the file). This function returns a Signal that the caller
+ can then connect to. Any time there is a notification, the signal
+ will get emitted. Callbacks connected to the signal must accept 2
+ arguments: notify mask and filename.
+ """
+ if mask == None:
+ mask = INotify.WATCH_MASK
+
+ wd = _inotify.add_watch(self._fd, path, mask)
+ if wd < 0:
+ raise IOError, "Failed to add watch on '%s'" % path
+
+ signal = kaa.notifier.Signal()
+ self._watches[wd] = [signal, os.path.realpath(path)]
+ return signal
+
+
+ def ignore(self, path):
+ """
+ Removes a watch on the given path.
+ """
+ path = os.path.realpath(path)
+ for wd in self._watches:
+ if path == self._watches[wd][1]:
+ _inotify.rm_watch(self._fd, wd)
+ del self._watches[wd]
+ return True
+
+ return False
+
+ def _handle_data(self):
+ data = os.read(self._fd, 32768)
+ self._read_buffer += data
+
+ while True:
+ if len(self._read_buffer) < 16:
+ break
+
+ wd, mask, cookie, size = struct.unpack("LLLL",
self._read_buffer[0:16])
+ if size:
+ name = self._read_buffer[16:16+size]
+ else:
+ name = None
+
+ self._read_buffer = self._read_buffer[16+size:]
+ if wd not in self._watches:
+ continue
+
+ path = self._watches[wd][1]
+ if name:
+ path = os.path.join(path, name)
+
+ self._watches[wd][0].emit(mask, path)
+ self.signals["event"].emit(mask, path)
+
+ if mask & INotify.DELETE_SELF:
+ # Self got deleted, so remove the watch data.
+ del self._watches[wd]
+
+
+if _inotify:
+ # Copy constants from _inotify to INotify
+ for attr in dir(_inotify):
+ if attr[0].isupper():
+ setattr(INotify, attr, getattr(_inotify, attr))
+
+ INotify.WATCH_MASK = INotify.MODIFY | INotify.ATTRIB | INotify.DELETE | \
+ INotify.CREATE | INotify.DELETE_SELF |
INotify.UNMOUNT | \
+ INotify.MOVE
+
+ INotify.CHANGE = INotify.MODIFY | INotify.ATTRIB
+
Added: trunk/beacon/src/inotify/fallback-inotify-syscalls.h
==============================================================================
--- (empty file)
+++ trunk/beacon/src/inotify/fallback-inotify-syscalls.h Sun Mar 26
23:53:53 2006
@@ -0,0 +1,61 @@
+#ifndef _LINUX_INOTIFY_SYSCALLS_H
+#define _LINUX_INOTIFY_SYSCALLS_H
+
+#include <sys/syscall.h>
+
+#if defined(__i386__)
+# define __NR_inotify_init 291
+# define __NR_inotify_add_watch 292
+# define __NR_inotify_rm_watch 293
+#elif defined(__x86_64__)
+# define __NR_inotify_init 253
+# define __NR_inotify_add_watch 254
+# define __NR_inotify_rm_watch 255
+#elif defined(__powerpc__) || defined(__powerpc64__)
+# define __NR_inotify_init 275
+# define __NR_inotify_add_watch 276
+# define __NR_inotify_rm_watch 277
+#elif defined (__ia64__)
+# define __NR_inotify_init 1277
+# define __NR_inotify_add_watch 1278
+# define __NR_inotify_rm_watch 1279
+#elif defined (__s390__)
+# define __NR_inotify_init 284
+# define __NR_inotify_add_watch 285
+# define __NR_inotify_rm_watch 286
+#elif defined (__alpha__)
+# define __NR_inotify_init 444
+# define __NR_inotify_add_watch 445
+# define __NR_inotify_rm_watch 446
+#elif defined (__sparc__) || defined (__sparc64__)
+# define __NR_inotify_init 151
+# define __NR_inotify_add_watch 152
+# define __NR_inotify_rm_watch 156
+#elif defined (__arm__)
+# define __NR_inotify_init 316
+# define __NR_inotify_add_watch 317
+# define __NR_inotify_rm_watch 318
+#elif defined (__sh__)
+# define __NR_inotify_init 290
+# define __NR_inotify_add_watch 291
+# define __NR_inotify_rm_watch 292
+#else
+# error "Unsupported architecture!"
+#endif
+
+static inline int inotify_init (void)
+{
+ return syscall (__NR_inotify_init);
+}
+
+static inline int inotify_add_watch (int fd, const char *name, __u32 mask)
+{
+ return syscall (__NR_inotify_add_watch, fd, name, mask);
+}
+
+static inline int inotify_rm_watch (int fd, __u32 wd)
+{
+ return syscall (__NR_inotify_rm_watch, fd, wd);
+}
+
+#endif /* _LINUX_INOTIFY_SYSCALLS_H */
Added: trunk/beacon/src/inotify/fallback-inotify.h
==============================================================================
--- (empty file)
+++ trunk/beacon/src/inotify/fallback-inotify.h Sun Mar 26 23:53:53 2006
@@ -0,0 +1,109 @@
+/*
+ * Inode based directory notification for Linux
+ *
+ * Copyright (C) 2005 John McCutchan
+ */
+
+#ifndef _LINUX_INOTIFY_H
+#define _LINUX_INOTIFY_H
+
+#include <linux/types.h>
+
+/*
+ * struct inotify_event - structure read from the inotify device for each event
+ *
+ * When you are watching a directory, you will receive the filename for events
+ * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
+ */
+struct inotify_event {
+ __s32 wd; /* watch descriptor */
+ __u32 mask; /* watch mask */
+ __u32 cookie; /* cookie to synchronize two events */
+ __u32 len; /* length (including nulls) of name */
+ char name[0]; /* stub for possible name */
+};
+
+/* the following are legal, implemented events that user-space can watch for */
+#define IN_ACCESS 0x00000001 /* File was accessed */
+#define IN_MODIFY 0x00000002 /* File was modified */
+#define IN_ATTRIB 0x00000004 /* Metadata changed */
+#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */
+#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
+#define IN_OPEN 0x00000020 /* File was opened */
+#define IN_MOVED_FROM 0x00000040 /* File was moved from X */
+#define IN_MOVED_TO 0x00000080 /* File was moved to Y */
+#define IN_CREATE 0x00000100 /* Subfile was created */
+#define IN_DELETE 0x00000200 /* Subfile was deleted */
+#define IN_DELETE_SELF 0x00000400 /* Self was deleted */
+#define IN_MOVE_SELF 0x00000800 /* Self was moved. */
+
+/* the following are legal events. they are sent as needed to any watch */
+#define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */
+#define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
+#define IN_IGNORED 0x00008000 /* File was ignored */
+
+/* helper events */
+#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */
+#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves
*/
+
+/* special flags */
+#define IN_ISDIR 0x40000000 /* event occurred against dir */
+#define IN_ONESHOT 0x80000000 /* only send event once */
+
+/*
+ * All of the events - we build the list by hand so that we can add flags in
+ * the future and not break backward compatibility. Apps will get only the
+ * events that they originally wanted. Be sure to add new events here!
+ */
+#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
+ IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \
+ IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF)
+
+#ifdef __KERNEL__
+
+#include <linux/dcache.h>
+#include <linux/fs.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_INOTIFY
+
+extern void inotify_inode_queue_event(struct inode *, __u32, __u32,
+ const char *);
+extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32,
+ const char *);
+extern void inotify_unmount_inodes(struct list_head *);
+extern void inotify_inode_is_dead(struct inode *);
+extern u32 inotify_get_cookie(void);
+
+#else
+
+static inline void inotify_inode_queue_event(struct inode *inode,
+ __u32 mask, __u32 cookie,
+ const char *filename)
+{
+}
+
+static inline void inotify_dentry_parent_queue_event(struct dentry *dentry,
+ __u32 mask, __u32 cookie,
+ const char *filename)
+{
+}
+
+static inline void inotify_unmount_inodes(struct list_head *list)
+{
+}
+
+static inline void inotify_inode_is_dead(struct inode *inode)
+{
+}
+
+static inline u32 inotify_get_cookie(void)
+{
+ return 0;
+}
+
+#endif /* CONFIG_INOTIFY */
+
+#endif /* __KERNEL __ */
+
+#endif /* _LINUX_INOTIFY_H */
Added: trunk/beacon/src/inotify/inotify.c
==============================================================================
--- (empty file)
+++ trunk/beacon/src/inotify/inotify.c Sun Mar 26 23:53:53 2006
@@ -0,0 +1,104 @@
+/*
+ * ----------------------------------------------------------------------------
+ * Inotify module for Python
+ * ----------------------------------------------------------------------------
+ * $Id: inotify.c 1247 2006-03-04 19:35:51Z tack $
+ *
+ * ----------------------------------------------------------------------------
+ * Copyright (C) 2006 Jason Tackaberry <[EMAIL PROTECTED]>
+ *
+ * First Edition: Jason Tackaberry <[EMAIL PROTECTED]>
+ * Maintainer: Jason Tackaberry <[EMAIL PROTECTED]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+ * CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * ----------------------------------------------------------------------------
+ */
+
+#include <Python.h>
+#include "config.h"
+
+#include <inttypes.h>
+
+#ifdef USE_FALLBACK
+# include "fallback-inotify.h"
+# include "fallback-inotify-syscalls.h"
+#else
+# include <sys/inotify.h>
+#endif
+
+PyObject *init(PyObject *self, PyObject *args)
+{
+ int fd = inotify_init();
+ return Py_BuildValue("l", fd);
+}
+
+PyObject *add_watch(PyObject *self, PyObject *args)
+{
+ int fd;
+ uint32_t mask;
+ char *name;
+
+ if (!PyArg_ParseTuple(args, "isi", &fd, &name, &mask))
+ return NULL;
+
+ return Py_BuildValue("l", inotify_add_watch(fd, name, mask));
+}
+
+PyObject *rm_watch(PyObject *self, PyObject *args)
+{
+ int fd;
+ uint32_t wd;
+
+ if (!PyArg_ParseTuple(args, "ii", &fd, &wd))
+ return NULL;
+
+ return Py_BuildValue("l", inotify_rm_watch(fd, wd));
+}
+
+
+PyMethodDef inotify_methods[] = {
+ { "init", init, METH_VARARGS },
+ { "add_watch", add_watch, METH_VARARGS },
+ { "rm_watch", rm_watch, METH_VARARGS },
+ { NULL }
+};
+
+
+void init_inotify()
+{
+ PyObject *m = Py_InitModule("_inotify", inotify_methods);
+ #define add_const(x) PyModule_AddObject(m, #x, PyLong_FromLong(IN_ ## x));
+ add_const(ACCESS);
+ add_const(MODIFY);
+ add_const(ATTRIB);
+ add_const(CLOSE_WRITE);
+ add_const(CLOSE_NOWRITE);
+ add_const(CLOSE);
+ add_const(OPEN);
+ add_const(MOVED_FROM);
+ add_const(MOVED_TO);
+ add_const(MOVE);
+ add_const(CREATE);
+ add_const(DELETE);
+ add_const(DELETE_SELF);
+ add_const(MOVE_SELF);
+ add_const(UNMOUNT);
+ add_const(Q_OVERFLOW);
+ add_const(IGNORED);
+ add_const(ISDIR);
+ add_const(ONESHOT);
+ add_const(ALL_EVENTS);
+}
Added: trunk/beacon/test/inotify.py
==============================================================================
--- (empty file)
+++ trunk/beacon/test/inotify.py Sun Mar 26 23:53:53 2006
@@ -0,0 +1,16 @@
+from kaa.beacon.inotify import INotify
+import kaa, os
+
+def cb(mask, name):
+ if mask & INotify.CREATE:
+ print name, "created."
+ elif mask & INotify.CHANGE:
+ print name, "changed."
+ elif mask & INotify.DELETE:
+ print name, "deleted"
+
+i = INotify()
+dir = os.path.expanduser("~")
+i.watch(dir).connect(cb)
+print "Now monitoring", dir
+kaa.main()
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog