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

kqueueを試してみた

kqueueを試してみました。

hoge.txtに何らかの書き込みがあるまで待ち続けるサンプルコードを書いて見ました。
環境はMac、/path/to/hoge.txtのパスを変更して、gccでコンパイルすれば動くと思います。エラー処理は適当。
このコードだけでは、旨みは見えないw
とりあえず動かすだけ。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/event.h>
#include <sys/time.h>
#include <fcntl.h>

int main(void)
{
  int fd;
  int kq;
  struct kevent kev;
  int ret;
  struct timespec tspec;

  /* 初期化 */
  fd = 0;
  kq = 0;
  (void)memset(&kev, 0, sizeof(kev));
  ret = 0;
  (void)memset(&tspec, 0, sizeof(tspec));

  /* hoge.txtを監視するよう登録 */
  fd = open("/path/to/hoge.txt", O_RDONLY);
  if (fd == -1) {
    perror("open");
    exit(1);
  }
  kq = kqueue();
  if (kq == -1) {
    perror("kqueue");
    exit(1);
  }
  EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD, NOTE_WRITE, 0, NULL);
  ret = kevent(kq, &kev, 1, NULL, 0, NULL);
  if (ret == -1) {
    perror("kevent");
    exit(1);
  }

  /* hoge.txtを監視 */
  while (1) {
    ret = kevent(kq, NULL, 0, &kev, 1, NULL);

    if (ret == -1) {
      perror("kevent");
      exit(1);
    }
    else if (ret > 0) {
      if (kev.ident == fd &&
          (kev.fflags & NOTE_WRITE) == NOTE_WRITE) {
        printf("hoge.txt is written\n");
        break;
      }
    }
  }

  /* 終了処理 */
  close(kq);
  close(fd);

  return 0;
}

全然関係ないけど、vimでhoge.txtを書きこもうと思ったら検知してくれず、なんでだろう?と思ったら、vimでファイル書きこむ際はファイル削除しているようだ。そうか、多分裏でswapしてるんだな。と納得。
なので、試す際は echo hoge > hoge.txtとかやるといいと思います。