X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=dirwatcher.ml;h=e96c4e9ee6fc2bbeb9559f15727fdb14bbb7526a;hb=refs%2Fheads%2Ftrellis;hp=5bd4d6cb6f95dee02ec7fb3ec53557a7b63ed92b;hpb=2955cde23cac50c0ad569745974746993b171524;p=vsys.git diff --git a/dirwatcher.ml b/dirwatcher.ml index 5bd4d6c..e96c4e9 100644 --- a/dirwatcher.ml +++ b/dirwatcher.ml @@ -1,3 +1,5 @@ +(** Watches directories for events. Agnostic to vsys semantics of backends and + frontends *) open Inotify open Fdwatcher open Printf @@ -6,51 +8,75 @@ open Globals (* I don't know if a wd corresponding to a deleted directory is evicted or just * leaks - fix implementation of rmdir accordingly *) - let wdmap = Hashtbl.create 1024 +let masks = Hashtbl.create 1024 let fd = Inotify.init () +let rec list_check lst elt = + match lst with + | [] -> false + | car::cdr -> if (car==elt) then true else list_check cdr elt + let handle_dir_event dirname evlist str = - let fname = String.concat "/" [dirname;str] in - printf "File: %s. " fname;List.iter - (fun e -> - printf "Event: %s\n" (string_of_event e)) - evlist; - flush Pervasives.stdout + let fname = String.concat "/" [dirname;str] in + fprintf logfd "File: %s. " fname;List.iter + (fun e -> + fprintf logfd "Event: %s\n" (string_of_event e)) + evlist; + flush logfd let add_watch dir events handler = - printf "Adding watch for %s\n" dir; + let evcheck = list_check events in let wd = Inotify.add_watch fd dir events in - Hashtbl.add wdmap wd (dir,handler) + Hashtbl.add masks dir (wd,handler); + Hashtbl.add wdmap wd (dir,Some(handler)) + + (* Ignore the possibility that the whole directory can disappear and come + * back while it is masked *) + +let mask_watch dir = + try + let wd,_ = Hashtbl.find masks dir in + Inotify.rm_watch fd wd; + Hashtbl.remove wdmap wd + with _ -> + () + +let unmask_watch dir events = + let _,handler = try Hashtbl.find masks dir with Not_found->fprintf logfd "unmask called without mask: %s\n" dir;flush logfd;raise Not_found in + try + Hashtbl.remove masks dir; + add_watch dir events handler + with Not_found -> () let asciiz s = let rec findfirstnul str idx len = if ((idx==len) || - (str.[idx]==(char_of_int 0))) then idx - else - findfirstnul str (idx+1) len + (str.[idx]==(char_of_int 0))) then idx + else + findfirstnul str (idx+1) len in let nulterm = findfirstnul s 0 (String.length s) in String.sub s 0 nulterm -let receive_event (eventdescriptor:fd_and_fname) (bla:fd_and_fname) = +let receive_event (eventdescriptor:fname_and_fd) (bla:fname_and_fd) = let (_,fd) = eventdescriptor in - let evs = Inotify.read fd in - List.iter (fun x-> - match x with - | (wd,evlist,_,Some(str)) -> - let purestr = asciiz(str) in - let (dirname,handler) = - try Hashtbl.find wdmap wd with Not_found->printf "Unknown watch descriptor\n";raise Not_found - in - ( - match handler with - | None->handle_dir_event dirname evlist purestr - | Some(handler)->handler dirname evlist purestr - ) - | _ -> ()) - evs + let evs = Inotify.read fd in + List.iter (fun x-> + match x with + | (wd,evlist,_,Some(str)) -> + begin + let purestr = asciiz(str) in + let (dirname,handler) = + try Hashtbl.find wdmap wd with Not_found->("",None) + in + match handler with + | None->fprintf logfd "Unhandled watch descriptor\n";flush logfd + | Some(handler)->handler wd dirname evlist purestr + end + | _ -> ()) + evs let initialize () = Fdwatcher.add_fd (None,fd) (None,fd) receive_event