kqueueインタフェースを呼び出すサンプルコード
5473 ワード
詳細
インタフェースを理解するには、サンプルコードを直接テストすることが最善です.
コードはkqueue-NetBSD System Calls Manualから
このコードの主な機能は、指定されたファイルを監視し、受信したイベントメッセージを印刷することです.(ファイルはプログラムの最初の実行パラメータで指定されます)
monitor.h
コンパイルし、テスト用の監視対象ファイルを生成し、プログラムを実行します.
ファイルに対して様々な操作を行い、出力を観察します.
監視効果がよく、強いです.コードを見てみましょう.
この例では、構造体keventは、モニタリング対象ファイル(例えば、対応するfile descriptor、モニタリングが必要なイベント)を記述するために使用される.
構造体の初期化操作は?ここにいたのか:
EV_SETはkevent構造体の初期化コードを簡略化するマクロ定義である.
はいhにEVが見えるSETの定義、このファイルは(システム:Mac OS X 10.6.8)にあります.
構造体keventの各メンバーの意味(カッコ内はサンプルコードに入力された実際のパラメータ):
ident (fd)
イベントの識別は、通常file descriptorを使用して識別されます.
他にもEVFILT_AIO, EVFILT_SIGNALなど.
filter (EVFILT_VNODE)
イベントを処理するkernel filterを指定します.通常はシステムの事前定義kernel filterである.
EVFILT_VNODEは、fflagsで指定されたイベントタイプを監視するファイルを説明します.
flags (EV_ADD | EV_ENABLE | EV_CLEAR)
Actions to perform on the event.
例:EV_ADDは、このイベントをkqueueに加えるものである.
EV_ENABLEは、kevent()関数がトリガーされるとイベントを返すことを許可します.
fflags (NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE)
Filter-specific flags.
data (0)
Filter-specific data value.
udata (0)
Opaque user-defined value passed through the kernel unchanged.
詳細はman kqueueを表示すればいいです.
参照ドキュメント:
1.kqueue - NetBSD System Calls Manual
インタフェースを理解するには、サンプルコードを直接テストすることが最善です.
コードはkqueue-NetBSD System Calls Manualから
このコードの主な機能は、指定されたファイルを監視し、受信したイベントメッセージを印刷することです.(ファイルはプログラムの最初の実行パラメータで指定されます)
monitor.h
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
int fd, kq, nev;
struct kevent ev;
static const struct timespec tout = { 1, 0 };
if ((fd = open(argv[1], O_RDONLY)) == -1)
err(1, "Cannot open `%s'", argv[1]);
if ((kq = kqueue()) == -1)
err(1, "Cannot create kqueue");
EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
NOTE_RENAME|NOTE_REVOKE, 0, 0);
if (kevent(kq, &ev, 1, NULL, 0, &tout) == -1)
err(1, "kevent");
for (;;) {
nev = kevent(kq, NULL, 0, &ev, 1, &tout);
if (nev == -1)
err(1, "kevent");
if (nev == 0)
continue;
if (ev.fflags & NOTE_DELETE) {
printf("deleted ");
ev.fflags &= ~NOTE_DELETE;
}
if (ev.fflags & NOTE_WRITE) {
printf("written ");
ev.fflags &= ~NOTE_WRITE;
}
if (ev.fflags & NOTE_EXTEND) {
printf("extended ");
ev.fflags &= ~NOTE_EXTEND;
}
if (ev.fflags & NOTE_ATTRIB) {
printf("chmod/chown/utimes ");
ev.fflags &= ~NOTE_ATTRIB;
}
if (ev.fflags & NOTE_LINK) {
printf("hardlinked ");
ev.fflags &= ~NOTE_LINK;
}
if (ev.fflags & NOTE_RENAME) {
printf("renamed ");
ev.fflags &= ~NOTE_RENAME;
}
if (ev.fflags & NOTE_REVOKE) {
printf("revoked ");
ev.fflags &= ~NOTE_REVOKE;
}
printf("
");
if (ev.fflags)
warnx("unknown event 0x%x
", ev.fflags);
}
}
コンパイルし、テスト用の監視対象ファイルを生成し、プログラムを実行します.
cc monitor.c -o monitor
touch zhongwei.log
./monitor zhongwei.log
ファイルに対して様々な操作を行い、出力を観察します.
echo "Hello kqueue" >> zhongwei.log
# :
# extended
# written
touch zhongwei.log
# :
# chmod/chown/utimes
mv zhongwei.log zhongwei2.log
# :
# renamed
rm zhongwei2.log
# :
# deleted hardlinked
監視効果がよく、強いです.コードを見てみましょう.
struct kevent ev;
この例では、構造体keventは、モニタリング対象ファイル(例えば、対応するfile descriptor、モニタリングが必要なイベント)を記述するために使用される.
struct kevent {
uintptr_t ident; /* identifier for this event */
uint32_t filter; /* filter for event */
uint32_t flags; /* action flags for kqueue */
uint32_t fflags; /* filter flag value */
int64_t data; /* filter data value */
intptr_t udata; /* opaque user data identifier */
};
構造体の初期化操作は?ここにいたのか:
EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
NOTE_RENAME|NOTE_REVOKE, 0, 0);
EV_SETはkevent構造体の初期化コードを簡略化するマクロ定義である.
はいhにEVが見えるSETの定義、このファイルは(システム:Mac OS X 10.6.8)にあります.
$ find /System/ -name event.h
/System//Library/Frameworks/Kernel.framework/Versions/A/Headers/sys/event.h
#define EV_SET(kevp, a, b, c, d, e, f) do { \
struct kevent *__kevp__ = (kevp); \
__kevp__->ident = (a); \
__kevp__->filter = (b); \
__kevp__->flags = (c); \
__kevp__->fflags = (d); \
__kevp__->data = (e); \
__kevp__->udata = (f); \
} while(0)
構造体keventの各メンバーの意味(カッコ内はサンプルコードに入力された実際のパラメータ):
ident (fd)
イベントの識別は、通常file descriptorを使用して識別されます.
他にもEVFILT_AIO, EVFILT_SIGNALなど.
filter (EVFILT_VNODE)
イベントを処理するkernel filterを指定します.通常はシステムの事前定義kernel filterである.
EVFILT_VNODEは、fflagsで指定されたイベントタイプを監視するファイルを説明します.
flags (EV_ADD | EV_ENABLE | EV_CLEAR)
Actions to perform on the event.
例:EV_ADDは、このイベントをkqueueに加えるものである.
EV_ENABLEは、kevent()関数がトリガーされるとイベントを返すことを許可します.
fflags (NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE)
Filter-specific flags.
data (0)
Filter-specific data value.
udata (0)
Opaque user-defined value passed through the kernel unchanged.
詳細はman kqueueを表示すればいいです.
参照ドキュメント:
1.kqueue - NetBSD System Calls Manual