読者です 読者をやめる 読者になる 読者になる

py-kqueue

Python

py-kqueue
http://pypi.python.org/pypi/py-kqueue/

kqueueバインディング。同じものにPyKQueueがあるが、py-kqueueの方がPython2.2以降に対応ということでC拡張としての作りがモダンで、よりオブジェクト指向PythonらしいAPIを提供している。

インストールは、

$ sudo easy_install py-kqueue

でもできるのかもしれないが、ソースを見てみたかったのでzipを解凍してsetup.pyを自分でたたいた。

$ curl -O http://pypi.python.org/packages/source/p/py-kqueue/py-kqueue-2.0.zip
$ unzip py-kqueue-2.0
$ cd py-kqueue-2.0
$ sudo python setup.py install
$ 

使い方は、結局のところ、man kqueue, man keventを読めってことになるが、py-kqueueのkeventの使い方だけはよく分からなかったので、ソースを読んで解決した。

events = kq.kevent(changelist, nchanges, timeout)

のように、第一引数にkeventオブジェクトのリスト(もしくはkeventオブジェクト)、第二引数にchangelistの長さ、第三引数にタイムアウトを指定する。タイムアウトは、(sec, nsec)のタプルか、nsecのInt/Long型。

練習のために、このページで紹介されているCプログラムとまったく同じことをするPythonプログラムを書いてみた。

An example of kqueue
http://julipedia.blogspot.com/2004/10/example-of-kqueue.html

/tmp/fooというファイルを監視するプログラム。/tmp/fooが削除されたら実行を終了する。

from __future__ import with_statement
import os/
from kqueue import *

with open("/tmp/foo", "r") as f:
    kq = kqueue()

    change = EV_SET(f.fileno(), EVFILT_VNODE,
                    EV_ADD|EV_ENABLE|EV_ONESHOT,
                    NOTE_DELETE|NOTE_EXTEND|NOTE_WRITE|NOTE_ATTRIB,
                    0, 0
                    )
    changes = [change]

    while 1:
        events = kq.kevent(changes, len(changes))
        if events:
            for ev in events:
                if ev.fflags & NOTE_DELETE:
                    print "File deleted"
                    sys.exit(0)
                
                if ev.fflags & NOTE_EXTEND or ev.fflags & NOTE_WRITE:
                    print "File modified"
                
                if ev.fflags & NOTE_ATTRIB:
                    print "File attributes modified"