X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=dirwatcher.ml;fp=dirwatcher.ml;h=41310238ae7a07250e9b4710a039114964f15d2d;hb=16c8bb31dd971b7fab00dbb17a75bb08cee463c6;hp=643830e4ec8b82a6bd3251cfb3434a654db315c3;hpb=47e86c6701f0bfe11a8a8784cd06db3283a57775;p=vsys.git diff --git a/dirwatcher.ml b/dirwatcher.ml index 643830e..4131023 100644 --- a/dirwatcher.ml +++ b/dirwatcher.ml @@ -1,5 +1,5 @@ (** Watches directories for events. Agnostic to vsys semantics of backends and -frontends *) + frontends *) open Inotify open Fdwatcher open Printf @@ -8,79 +8,78 @@ open Globals (* I don't know if a wd corresponding to a deleted directory is evicted or just * leaks - fix implementation of rmdir accordingly *) - -type 'a handlertype = Nohandler | Activehandler of 'a | Maskedhandler of 'a - 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 - fprintf logfd "File: %s. " fname;List.iter - (fun e -> - fprintf logfd "Event: %s\n" (string_of_event e)) - evlist; - flush logfd + 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 = - let wd = Inotify.add_watch fd dir events in - Hashtbl.add wdmap wd (dir,Activehandler(handler)) - -let mask_events wd = - let (dirname,handler) = try Hashtbl.find wdmap wd with Not_found->("",Nohandler) - in - match handler with - | Activehandler(func)-> - Hashtbl.replace wdmap wd (dirname,Maskedhandler(func)) - | _ -> - () - -let unmask_events wd = - let (dirname,handler) = try Hashtbl.find wdmap wd with Not_found->("",Nohandler) + let evcheck = list_check events in + let oneshot = if (evcheck S_Oneshot) then true else false in - match handler with - | Maskedhandler(func)-> - Hashtbl.replace wdmap wd (dirname,Activehandler(func)) - | _ -> - () + let wd = Inotify.add_watch fd dir events in + Hashtbl.add masks dir (wd,handler); + Hashtbl.add wdmap wd (dir,Some(handler),oneshot) +let mask_watch dir = + try + let wd,_ = Hashtbl.find masks dir in + Inotify.rm_watch fd wd; + Hashtbl.remove wdmap wd + with _ -> + () - (* XXX -let del_watch dir = - fprintf logfd "Removing watch for %s\n" dir;flush logfd; - let wd = Inotify.rm_watch fd dir in - Hashtbl.remove wdmap wd - *) +let unmask_watch dir events = + let _,handler = Hashtbl.find masks dir 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: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->("",Nohandler) - in - ( - match handler with - | Nohandler->fprintf logfd "Unhandled watch descriptor\n";flush logfd - | Activehandler(handler)->handler wd dirname evlist purestr - | Maskedhandler(_)->() - ) - | _ -> ()) - evs + 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,oneshot) = + try Hashtbl.find wdmap wd with Not_found->("",None,false) + in + printf "Received event: %s " dirname; + List.iter (fun l->printf "%s " (string_of_event l)) evlist; + printf "\n";flush Pervasives.stdout; + if (oneshot) then Hashtbl.remove wdmap wd; + ( + match handler with + | None->fprintf logfd "Unhandled watch descriptor\n";flush logfd + | Some(handler)->handler wd dirname evlist purestr + ) + | _ -> ()) + evs let initialize () = Fdwatcher.add_fd (None,fd) (None,fd) receive_event