add -fPIC option to the C compiler, required in f31
[vsys.git] / ocaml_inotify-0.4 / inotify_stubs.c
1 /*
2  *      Copyright (C) 2006 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 only.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * Inotify Ocaml binding - C glue
14  */
15
16 #include <string.h>
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <sys/ioctl.h>
20 #include <caml/mlvalues.h>
21 #include <caml/memory.h>
22 #include <caml/alloc.h>
23 #include <caml/custom.h>
24 #include <caml/fail.h>
25 #include <caml/signals.h>
26
27 #include <features.h>
28
29 #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 4
30 #define GLIBC_SUPPORT_INOTIFY 1
31 #else
32 #define GLIBC_SUPPORT_INOTIFY 0
33 #endif
34
35 #if GLIBC_SUPPORT_INOTIFY
36 #include <inotifytools/inotify.h>
37 #else
38 #include "inotify_compat.h"
39 #endif
40
41 static int inotify_flag_table[] = {
42         IN_ACCESS, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE,
43         IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MODIFY,
44         IN_MOVE_SELF, IN_MOVED_FROM, IN_MOVED_TO, IN_OPEN,
45         IN_DONT_FOLLOW, IN_MASK_ADD, IN_ONESHOT, IN_ONLYDIR,
46         IN_MOVE, IN_CLOSE, IN_ALL_EVENTS, 0
47 };
48
49 static int inotify_return_table[] = {
50         IN_ACCESS, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE,
51         IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MODIFY,
52         IN_MOVE_SELF, IN_MOVED_FROM, IN_MOVED_TO, IN_OPEN,
53         IN_IGNORED, IN_ISDIR, IN_Q_OVERFLOW, IN_UNMOUNT, 0
54 };
55
56 value stub_inotify_init(value unit)
57 {
58         CAMLparam1(unit);
59         int fd;
60
61         fd = inotify_init();
62         CAMLreturn(Val_int(fd));
63 }
64
65 value stub_inotify_ioctl_fionread(value fd)
66 {
67         CAMLparam1(fd);
68         int rc, bytes;
69
70         rc = ioctl(Int_val(fd), FIONREAD, &bytes);
71         if (rc == -1)
72                 caml_failwith("ioctl fionread");
73
74         CAMLreturn(Val_int(bytes));
75 }
76
77 value stub_inotify_add_watch(value fd, value path, value mask)
78 {
79         CAMLparam3(fd, path, mask);
80         int cv_mask, wd;
81
82         cv_mask = caml_convert_flag_list(mask, inotify_flag_table);
83         wd = inotify_add_watch(Int_val(fd), String_val(path), cv_mask);
84         if (wd < 0)
85                 caml_failwith("inotify_add_watch");
86         CAMLreturn(Val_int(wd));
87 }
88
89 value stub_inotify_rm_watch(value fd, value wd)
90 {
91         CAMLparam2(fd, wd);
92         int ret;
93
94         ret = inotify_rm_watch(Int_val(fd), Int_val(wd));
95         if (ret == -1)
96                 caml_failwith("inotify_rm_watch");
97         CAMLreturn(Val_unit);
98 }
99
100 value stub_inotify_struct_size(void)
101 {
102         CAMLparam0();
103         CAMLreturn(Val_int(sizeof(struct inotify_event)));
104 }
105
106 value stub_inotify_convert(value buf)
107 {
108         CAMLparam1(buf);
109         CAMLlocal3(event, l, tmpl);
110         struct inotify_event ev;
111         int i;
112
113         l = Val_emptylist;
114         tmpl = Val_emptylist;
115
116         memcpy(&ev, String_val(buf), sizeof(struct inotify_event));
117
118         for (i = 0; inotify_return_table[i]; i++) {
119                 if (!(ev.mask & inotify_return_table[i]))
120                         continue;
121                 tmpl = caml_alloc_small(2, Tag_cons);
122                 Field(tmpl, 0) = Val_int(i);
123                 Field(tmpl, 1) = l;
124                 l = tmpl;
125         }
126
127         event = caml_alloc_tuple(4);
128         Store_field(event, 0, Val_int(ev.wd));
129         Store_field(event, 1, l);
130         Store_field(event, 2, caml_copy_int32(ev.cookie));
131         Store_field(event, 3, Val_int(ev.len));
132
133         CAMLreturn(event);
134 }