add -fPIC option to the C compiler, required in f31
[vsys.git] / dirwatcher.ml
1 (** Watches directories for events. Agnostic to vsys semantics of backends and
2   frontends *)
3 open Inotify
4 open Fdwatcher
5 open Printf
6 open Globals
7
8 (* I don't know if a wd corresponding to a deleted directory is evicted or just
9  * leaks - fix implementation of rmdir accordingly
10  *)
11 let wdmap = Hashtbl.create 1024
12
13 let fd = Inotify.init ()
14
15 let rec list_check lst elt =
16   match lst with
17     | [] -> false
18     | car::cdr -> if (car==elt) then true else list_check cdr elt
19
20 let pevlist evlist =
21     List.iter 
22       (fun e -> 
23          logprint "Event: %s\n" (string_of_event e)) 
24       evlist
25
26 let handle_dir_event dirname evlist str = 
27   let fname = String.concat "/" [dirname;str] in
28     logprint "File: %s. " fname;
29     pevlist evlist
30
31 let add_watch dir events handler =
32   let wd = Inotify.add_watch fd dir events in
33     Hashtbl.add wdmap wd (dir,Some(handler))
34       (* Ignore the possibility that the whole directory can disappear and come
35        * back while it is masked *)
36
37 let asciiz s =
38   let rec findfirstnul str idx len =
39     if ((idx==len) || 
40         (str.[idx]==(char_of_int 0))) then idx
41     else
42       findfirstnul str (idx+1) len
43   in
44   let nulterm = findfirstnul s 0 (String.length s) in
45     String.sub s 0 nulterm
46
47 let receive_event (eventdescriptor:fname_and_fd) (bla:fname_and_fd) =
48   let (_,fd) = eventdescriptor in
49   let evs = Inotify.read fd in
50     List.iter (fun x->
51                  match x with
52                    | (wd,evlist,_,Some(str)) ->
53                        begin
54                                let purestr = asciiz(str) in
55                                let (dirname,handler) = 
56                                  try Hashtbl.find wdmap wd with Not_found->("",None)
57                                in
58                                  match handler with
59                                    | None->
60                                        logprint "Unhandled watch descriptor\n"
61                                    | Some(handler)->
62                                        let fqp = String.concat "/" [dirname;purestr] in
63                                          begin
64                                          handler wd dirname evlist
65                                            purestr
66                                          end
67                        end
68                    | _ -> ()) 
69       evs
70
71 let initialize () =
72   Fdwatcher.add_fd (None,fd) (None,fd) receive_event