unison

Fork of Unison, a bi-directional file synchronization tool
git clone git://git.laack.co/unison.git
Log | Files | Refs | README | LICENSE

inotify.ml (3378B)


      1 (*
      2  * Copyright (C) 2006-2008 Vincent Hanquez <vincent@snarc.org>
      3  *
      4  * This program is free software; you can redistribute it and/or modify
      5  * it under the terms of the GNU Lesser General Public License as published
      6  * by the Free Software Foundation; version 2.1 only. with the special
      7  * exception on linking described in file LICENSE.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU Lesser General Public License for more details.
     13  *
     14  * Inotify OCaml binding
     15  *)
     16 
     17 type select_event =
     18         | S_Access
     19         | S_Attrib
     20         | S_Close_write
     21         | S_Close_nowrite
     22         | S_Create
     23         | S_Delete
     24         | S_Delete_self
     25         | S_Modify
     26         | S_Move_self
     27         | S_Moved_from
     28         | S_Moved_to
     29         | S_Open
     30         | S_Dont_follow
     31         | S_Mask_add
     32         | S_Oneshot
     33         | S_Onlydir
     34         | S_Excl_unlink
     35         (* convenience *)
     36         | S_Move
     37         | S_Close
     38         | S_All
     39 
     40 type type_event =
     41         | Access
     42         | Attrib
     43         | Close_write
     44         | Close_nowrite
     45         | Create
     46         | Delete
     47         | Delete_self
     48         | Modify
     49         | Move_self
     50         | Moved_from
     51         | Moved_to
     52         | Open
     53         | Ignored
     54         | Isdir
     55         | Q_overflow
     56         | Unmount
     57 
     58 let string_of_event = function
     59         | Access -> "ACCESS"
     60         | Attrib -> "ATTRIB"
     61         | Close_write -> "CLOSE_WRITE"
     62         | Close_nowrite -> "CLOSE_NOWRITE"
     63         | Create -> "CREATE"
     64         | Delete -> "DELETE"
     65         | Delete_self -> "DELETE_SELF"
     66         | Modify -> "MODIFY"
     67         | Move_self -> "MOVE_SELF"
     68         | Moved_from -> "MOVED_FROM"
     69         | Moved_to -> "MOVED_TO"
     70         | Open -> "OPEN"
     71         | Ignored -> "IGNORED"
     72         | Isdir -> "ISDIR"
     73         | Q_overflow -> "Q_OVERFLOW"
     74         | Unmount -> "UNMOUNT"
     75 
     76 let int_of_wd wd = wd
     77 
     78 type wd = int
     79 type event = wd * type_event list * int32 * string option
     80 
     81 external init : unit -> Unix.file_descr = "stub_inotify_init"
     82 external add_watch : Unix.file_descr -> string -> select_event list -> wd
     83                    = "stub_inotify_add_watch"
     84 external rm_watch : Unix.file_descr -> wd -> unit = "stub_inotify_rm_watch"
     85 external convert : string -> (wd * type_event list * int32 * int)
     86                  = "stub_inotify_convert"
     87 external struct_size : unit -> int = "stub_inotify_struct_size"
     88 
     89 external to_read : Unix.file_descr -> int = "stub_inotify_ioctl_fionread"
     90 
     91 let read fd =
     92         let ss = struct_size () in
     93         let toread = to_read fd in
     94 
     95         let ret = ref [] in
     96         let buf = Bytes.make toread '\000' in
     97         let toread = Unix.read fd buf 0 toread in
     98 
     99         let read_c_string offset len =
    100                 let index = ref 0 in
    101                 while !index < len && Bytes.get buf (offset + !index) <> '\000' do incr index done;
    102                 Bytes.sub_string buf offset !index
    103                 in
    104 
    105         let i = ref 0 in
    106 
    107         while !i < toread
    108         do
    109                 let wd, l, cookie, len = convert (Bytes.sub_string buf !i ss) in
    110                 let s = if len > 0 then Some (read_c_string (!i + ss) len) else None in
    111                 ret := (wd, l, cookie, s) :: !ret;
    112                 i := !i + (ss + len);
    113         done;
    114 
    115         List.rev !ret