Commit 5f41a20c authored by Sylvain Le Gall's avatar Sylvain Le Gall

Imported Upstream version 0.5

parents
version="0.5"
archive(byte)="inotify.cma"
archive(native)="inotify.cmxa"
CC = gcc
CFLAGS = -Wall -fPIC -O2
OCAMLC = ocamlc
OCAMLOPT = ocamlopt
OCAMLOPTFLAGS =
OCAMLABI := $(shell ocamlc -version)
OCAMLLIBDIR := $(shell ocamlc -where)
OCAMLDESTDIR ?= $(OCAMLLIBDIR)
OCAML_TEST_INC = -I `ocamlfind query oUnit`
OCAML_TEST_LIB = `ocamlfind query oUnit`/oUnit.cmxa
LIBS = inotify.cmi inotify.cmxa inotify.cma
PROGRAMS = test.inotify
all: $(LIBS)
bins: $(PROGRAMS)
libs: $(LIBS)
inotify.cmxa: libinotify_stubs.a inotify_stubs.a inotify.cmx
$(OCAMLOPT) $(OCAMLOPTFLAGS) -a -cclib -linotify_stubs -o $@ inotify.cmx
inotify.cma: libinotify_stubs.a inotify.cmi inotify.cmo
$(OCAMLC) -a -dllib dllinotify_stubs.so -cclib -linotify_stubs -o $@ inotify.cmo
inotify_stubs.a: inotify_stubs.o
ocamlmklib -o inotify_stubs $+
libinotify_stubs.a: inotify_stubs.o
ar rcs $@ $+
ocamlmklib -o inotify_stubs $+
%.cmo: %.ml
$(OCAMLC) -c -o $@ $<
%.cmi: %.mli
$(OCAMLC) -c -o $@ $<
%.cmx: %.ml
$(OCAMLOPT) $(OCAMLOPTFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
.PHONY: install
install: $(LIBS)
ocamlfind install -destdir $(OCAMLDESTDIR) -ldconf ignore inotify META inotify.cmi inotify.mli inotify.cma inotify.cmxa *.a *.so *.cmx
uninstall:
ocamlfind remove -destdir $(OCAMLDESTDIR) sqlite3
test.inotify: inotify.cmxa test.inotify.ml
$(OCAMLOPT) -o $@ unix.cmxa $+
clean:
-rm -f *.o *.so *.a *.cmo *.cmi *.cma *.cmx *.cmxa $(LIBS) $(PROGRAMS)
(*
* Copyright (C) 2006 Vincent Hanquez <vincent@snarc.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2 only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Inotify OCaml binding
*)
type select_event =
| S_Access
| S_Attrib
| S_Close_write
| S_Close_nowrite
| S_Create
| S_Delete
| S_Delete_self
| S_Modify
| S_Move_self
| S_Moved_from
| S_Moved_to
| S_Open
| S_Dont_follow
| S_Mask_add
| S_Oneshot
| S_Onlydir
(* convenience *)
| S_Move
| S_Close
| S_All
type type_event =
| Access
| Attrib
| Close_write
| Close_nowrite
| Create
| Delete
| Delete_self
| Modify
| Move_self
| Moved_from
| Moved_to
| Open
| Ignored
| Isdir
| Q_overflow
| Unmount
let string_of_event = function
| Access -> "ACCESS"
| Attrib -> "ATTRIB"
| Close_write -> "CLOSE_WRITE"
| Close_nowrite -> "CLOSE_NOWRITE"
| Create -> "CREATE"
| Delete -> "DELETE"
| Delete_self -> "DELETE_SELF"
| Modify -> "MODIFY"
| Move_self -> "MOVE_SELF"
| Moved_from -> "MOVED_FROM"
| Moved_to -> "MOVED_TO"
| Open -> "OPEN"
| Ignored -> "IGNORED"
| Isdir -> "ISDIR"
| Q_overflow -> "Q_OVERFLOW"
| Unmount -> "UNMOUNT"
let int_of_wd wd = wd
type wd = int
type event = wd * type_event list * int32 * string option
external init : unit -> Unix.file_descr = "stub_inotify_init"
external add_watch : Unix.file_descr -> string -> select_event list -> wd
= "stub_inotify_add_watch"
external rm_watch : Unix.file_descr -> wd -> unit = "stub_inotify_rm_watch"
external convert : string -> (wd * type_event list * int32 * int)
= "stub_inotify_convert"
external struct_size : unit -> int = "stub_inotify_struct_size"
external to_read : Unix.file_descr -> int = "stub_inotify_ioctl_fionread"
let read fd =
let ss = struct_size () in
let toread = to_read fd in
let ret = ref [] in
let buf = String.make toread '\000' in
let toread = Unix.read fd buf 0 toread in
let i = ref 0 in
while !i < toread
do
let wd, l, cookie, len = convert (String.sub buf !i ss) in
let s = if len > 0 then Some (String.sub buf (!i + ss) len) else None in
ret := (wd, l, cookie, s) :: !ret;
i := !i + (ss + len);
done;
List.rev !ret
(*
* Copyright (C) 2006 Vincent Hanquez <vincent@snarc.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2 only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Inotify OCaml binding
*)
type select_event =
| S_Access
| S_Attrib
| S_Close_write
| S_Close_nowrite
| S_Create
| S_Delete
| S_Delete_self
| S_Modify
| S_Move_self
| S_Moved_from
| S_Moved_to
| S_Open
| S_Dont_follow
| S_Mask_add
| S_Oneshot
| S_Onlydir
| S_Move
| S_Close
| S_All
type type_event =
| Access
| Attrib
| Close_write
| Close_nowrite
| Create
| Delete
| Delete_self
| Modify
| Move_self
| Moved_from
| Moved_to
| Open
| Ignored
| Isdir
| Q_overflow
| Unmount
type wd
type event = wd * type_event list * int32 * string option
val int_of_wd : wd -> int
val string_of_event : type_event -> string
val init : unit -> Unix.file_descr
val add_watch : Unix.file_descr -> string -> select_event list -> wd
val rm_watch : Unix.file_descr -> wd -> unit
val read : Unix.file_descr -> event list
#ifndef _SYS_INOTIFY_H
#define _SYS_INOTIFY_H 1
/* no other solution unfortunately ATM. */
#define __KERNEL__
#include <stdint.h>
#include <sys/syscall.h>
#include <asm/unistd.h>
/* Structure describing an inotify event. */
struct inotify_event
{
int wd;
unsigned int mask;
unsigned int cookie;
unsigned int len;
char name[0];
};
#define IN_ACCESS 0x00000001
#define IN_MODIFY 0x00000002
#define IN_ATTRIB 0x00000004
#define IN_CLOSE_WRITE 0x00000008
#define IN_CLOSE_NOWRITE 0x00000010
#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
#define IN_OPEN 0x00000020
#define IN_MOVED_FROM 0x00000040
#define IN_MOVED_TO 0x00000080
#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO)
#define IN_CREATE 0x00000100
#define IN_DELETE 0x00000200
#define IN_DELETE_SELF 0x00000400
#define IN_MOVE_SELF 0x00000800
#define IN_UNMOUNT 0x00002000
#define IN_Q_OVERFLOW 0x00004000
#define IN_IGNORED 0x00008000
#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO)
#define IN_ONLYDIR 0x01000000
#define IN_DONT_FOLLOW 0x02000000
#define IN_MASK_ADD 0x20000000
#define IN_ISDIR 0x40000000
#define IN_ONESHOT 0x80000000
#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_CREATE | IN_DELETE \
| IN_DELETE_SELF | IN_MOVE_SELF)
#include <errno.h>
_syscall0(long, inotify_init);
_syscall3(int, inotify_add_watch, int, fd, char *, name, int, mask);
_syscall2(int, inotify_rm_watch, int, fd, int, wd);
#undef __KERNEL__
#endif /* ! _SYS_INOTIFY_H */
/*
* Copyright (C) 2006 Vincent Hanquez <vincent@snarc.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2.1 only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Inotify Ocaml binding - C glue
*/
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>
#include <caml/custom.h>
#include <caml/fail.h>
#include <caml/signals.h>
#include <features.h>
#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 4
#define GLIBC_SUPPORT_INOTIFY 1
#else
#define GLIBC_SUPPORT_INOTIFY 0
#endif
#if GLIBC_SUPPORT_INOTIFY
#include <sys/inotify.h>
#else
#include "inotify_compat.h"
#endif
static int inotify_flag_table[] = {
IN_ACCESS, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE,
IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MODIFY,
IN_MOVE_SELF, IN_MOVED_FROM, IN_MOVED_TO, IN_OPEN,
IN_DONT_FOLLOW, IN_MASK_ADD, IN_ONESHOT, IN_ONLYDIR,
IN_MOVE, IN_CLOSE, IN_ALL_EVENTS, 0
};
static int inotify_return_table[] = {
IN_ACCESS, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE,
IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MODIFY,
IN_MOVE_SELF, IN_MOVED_FROM, IN_MOVED_TO, IN_OPEN,
IN_IGNORED, IN_ISDIR, IN_Q_OVERFLOW, IN_UNMOUNT, 0
};
value stub_inotify_init(value unit)
{
CAMLparam1(unit);
int fd;
fd = inotify_init();
CAMLreturn(Val_int(fd));
}
value stub_inotify_ioctl_fionread(value fd)
{
CAMLparam1(fd);
int rc, bytes;
rc = ioctl(Int_val(fd), FIONREAD, &bytes);
if (rc == -1)
caml_failwith("ioctl fionread");
CAMLreturn(Val_int(bytes));
}
value stub_inotify_add_watch(value fd, value path, value mask)
{
CAMLparam3(fd, path, mask);
int cv_mask, wd;
cv_mask = caml_convert_flag_list(mask, inotify_flag_table);
wd = inotify_add_watch(Int_val(fd), String_val(path), cv_mask);
if (wd < 0)
caml_failwith("inotify_add_watch");
CAMLreturn(Val_int(wd));
}
value stub_inotify_rm_watch(value fd, value wd)
{
CAMLparam2(fd, wd);
int ret;
ret = inotify_rm_watch(Int_val(fd), Int_val(wd));
if (ret == -1)
caml_failwith("inotify_rm_watch");
CAMLreturn(Val_unit);
}
value stub_inotify_struct_size(void)
{
CAMLparam0();
CAMLreturn(Val_int(sizeof(struct inotify_event)));
}
value stub_inotify_convert(value buf)
{
CAMLparam1(buf);
CAMLlocal3(event, l, tmpl);
struct inotify_event ev;
int i;
l = Val_emptylist;
tmpl = Val_emptylist;
memcpy(&ev, String_val(buf), sizeof(struct inotify_event));
for (i = 0; inotify_return_table[i]; i++) {
if (!(ev.mask & inotify_return_table[i]))
continue;
tmpl = caml_alloc_small(2, Tag_cons);
Field(tmpl, 0) = Val_int(i);
Field(tmpl, 1) = l;
l = tmpl;
}
event = caml_alloc_tuple(4);
Store_field(event, 0, Val_int(ev.wd));
Store_field(event, 1, l);
Store_field(event, 2, caml_copy_int32(ev.cookie));
Store_field(event, 3, Val_int(ev.len));
CAMLreturn(event);
}
(* unit testing inotify *)
open Printf
let _ =
if Array.length Sys.argv < 2 then (
eprintf "usage: %s <path>\n" Sys.argv.(0);
exit 1
);
let fd = Inotify.init () in
ignore (Inotify.add_watch fd Sys.argv.(1) [ Inotify.S_Create ]);
let string_of_event ev =
let wd,mask,cookie,s = ev in
let mask = String.concat ":" (List.map Inotify.string_of_event mask) in
let s = match s with Some s -> s | None -> "\"\"" in
sprintf "wd [%u] mask[%s] cookie[%ld] %s" (Inotify.int_of_wd wd)
mask cookie s
in
let nb = ref 0 in
while true
do
let _, _, _ = Unix.select [ fd ] [] [] (-1.) in
let evs = Inotify.read fd in
List.iter (fun ev ->
printf "[%d] %s\n%!" !nb (string_of_event ev)) evs;
incr nb
done;
Unix.close fd
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment