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 }