unison

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

inotify_stubs.c (3869B)


      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 - C glue
     15  */
     16 
     17 #include <errno.h>
     18 #include <string.h>
     19 #include <stdio.h>
     20 #include <unistd.h>
     21 #include <sys/ioctl.h>
     22 #include <sys/inotify.h>
     23 #include <caml/mlvalues.h>
     24 #include <caml/memory.h>
     25 #include <caml/alloc.h>
     26 #include <caml/unixsupport.h>
     27 #include <caml/version.h>
     28 
     29 #if OCAML_VERSION_MAJOR < 5
     30 #define caml_unix_error unix_error
     31 #define caml_uerror uerror
     32 #endif
     33 
     34 #ifndef IN_EXCL_UNLINK
     35 #define IN_EXCL_UNLINK 0  /* If not supported, just ignore */
     36 #endif
     37 
     38 static int inotify_flag_table[] = {
     39         IN_ACCESS, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE,
     40         IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MODIFY,
     41         IN_MOVE_SELF, IN_MOVED_FROM, IN_MOVED_TO, IN_OPEN,
     42         IN_DONT_FOLLOW, IN_MASK_ADD, IN_ONESHOT, IN_ONLYDIR,
     43         IN_EXCL_UNLINK, IN_MOVE, IN_CLOSE, IN_ALL_EVENTS, 0
     44 };
     45 
     46 static int inotify_return_table[] = {
     47         IN_ACCESS, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE,
     48         IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MODIFY,
     49         IN_MOVE_SELF, IN_MOVED_FROM, IN_MOVED_TO, IN_OPEN,
     50         IN_IGNORED, IN_ISDIR, IN_Q_OVERFLOW, IN_UNMOUNT, 0
     51 };
     52 
     53 CAMLprim value stub_inotify_init(value unit)
     54 {
     55         CAMLparam1(unit);
     56         int fd;
     57 
     58         fd = inotify_init();
     59         if (fd == -1)
     60                 caml_uerror("inotify_init", Nothing);
     61         CAMLreturn(Val_int(fd));
     62 }
     63 
     64 CAMLprim value stub_inotify_ioctl_fionread(value fd)
     65 {
     66         CAMLparam1(fd);
     67         int rc, bytes;
     68 
     69         rc = ioctl(Int_val(fd), FIONREAD, &bytes);
     70         if (rc == -1)
     71                 caml_uerror("ioctl fionread", Nothing);
     72 
     73         CAMLreturn(Val_int(bytes));
     74 }
     75 
     76 CAMLprim value stub_inotify_add_watch(value fd, value path, value mask)
     77 {
     78         CAMLparam3(fd, path, mask);
     79         int cv_mask, wd;
     80 
     81         cv_mask = caml_convert_flag_list(mask, inotify_flag_table);
     82         wd = inotify_add_watch(Int_val(fd), String_val(path), cv_mask);
     83         if (wd < 0)
     84                 caml_uerror("inotify_add_watch", Nothing);
     85         CAMLreturn(Val_int(wd));
     86 }
     87 
     88 CAMLprim value stub_inotify_rm_watch(value fd, value wd)
     89 {
     90         CAMLparam2(fd, wd);
     91         int ret;
     92 
     93         ret = inotify_rm_watch(Int_val(fd), Int_val(wd));
     94         if (ret == -1)
     95                 caml_uerror("inotify_rm_watch", Nothing);
     96         CAMLreturn(Val_unit);
     97 }
     98 
     99 CAMLprim value stub_inotify_struct_size(void)
    100 {
    101         CAMLparam0();
    102         CAMLreturn(Val_int(sizeof(struct inotify_event)));
    103 }
    104 
    105 CAMLprim value stub_inotify_convert(value buf)
    106 {
    107         CAMLparam1(buf);
    108         CAMLlocal3(event, l, tmpl);
    109         struct inotify_event ev;
    110         int i;
    111 
    112         l = Val_emptylist;
    113         tmpl = Val_emptylist;
    114 
    115         memcpy(&ev, String_val(buf), sizeof(struct inotify_event));
    116 
    117         for (i = 0; inotify_return_table[i]; i++) {
    118                 if (!(ev.mask & inotify_return_table[i]))
    119                         continue;
    120                 tmpl = caml_alloc_small(2, Tag_cons);
    121                 Field(tmpl, 0) = Val_int(i);
    122                 Field(tmpl, 1) = l;
    123                 l = tmpl;
    124         }
    125 
    126         event = caml_alloc_tuple(4);
    127         Store_field(event, 0, Val_int(ev.wd));
    128         Store_field(event, 1, l);
    129         Store_field(event, 2, caml_copy_int32(ev.cookie));
    130         Store_field(event, 3, Val_int(ev.len));
    131 
    132         CAMLreturn(event);
    133 }