Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 248 lines (218 sloc) 5.871 kb
5456c90 @omry initial commit
omry authored
1 /*******************************************************************************
f9b8182 @omry renamed library in LGPL comments
omry authored
2 * JNotify - Allow java applications to register to File system events.
5456c90 @omry initial commit
omry authored
3 *
4 * Copyright (C) 2005 - Content Objects
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 ******************************************************************************
21 *
22 * Content Objects, Inc., hereby disclaims all copyright interest in the
f9b8182 @omry renamed library in LGPL comments
omry authored
23 * library `JNotify' (a Java library for file system events).
5456c90 @omry initial commit
omry authored
24 *
25 * Yahali Sherman, 21 November 2005
26 * Content Objects, VP R&D.
27 *
28 ******************************************************************************
29 * Author : Omry Yadan
30 ******************************************************************************/
31
f9b8182 @omry renamed library in LGPL comments
omry authored
32
33
5456c90 @omry initial commit
omry authored
34
35 #include "net_contentobjects_jnotify_linux_JNotify_linux.h"
36 #include <sys/time.h>
37 #include <sys/select.h>
38 #include <sys/ioctl.h>
39 #include <linux/inotify.h>
40 #include <errno.h>
41 #include <stdio.h>
42 #include <unistd.h>
43 #include "inotify-syscalls.h"
44
45 int runLoop(JNIEnv *env, jclass clazz);
46 void __attribute__ ((destructor)) cleanup(void);
47 void dispatch(JNIEnv *env, jclass clazz, struct inotify_event *event);
48
49 int init();
50 int add_watch(char *path, __u32 mask);
51 int remove_watch(int wd);
52
53 /*
54 * Class: net_contentobjects_jnotify_linux_JNotify_linux
55 * Method: nativeInit
56 * Signature: ()I
57 */
58 JNIEXPORT jint JNICALL Java_net_contentobjects_jnotify_linux_JNotify_1linux_nativeInit
59 (JNIEnv *env, jclass clazz)
60 {
61 return (jint)init();
62 }
63
95c0166 @omry removed some debug prints.
omry authored
64 /*plog
5456c90 @omry initial commit
omry authored
65 * Class: net_contentobjects_jnotify_linux_JNotify_linux
66 * Method: nativeAddWatch
67 * Signature: (Ljava/lang/String;I)I
68 */
69 JNIEXPORT jint JNICALL Java_net_contentobjects_jnotify_linux_JNotify_1linux_nativeAddWatch
70 (JNIEnv *env, jclass clazz, jstring path, jint mask)
71 {
72 const char *str;
73 str = (*env)->GetStringUTFChars(env, path, NULL);
74 if (str == NULL)
75 {
76 return -1; /* OutOfMemoryError already thrown */
77 }
78 // todo : ERROR HADNLING!
79 int wd = add_watch((char*)str, mask);
80 (*env)->ReleaseStringUTFChars(env, path, str);
81
82 return wd;
83 }
84
85 /*
86 * Class: net_contentobjects_fshook_linux_INotify
87 * Method: nativeRemoveWatch
88 * Signature: (I)I
89 */
90 JNIEXPORT jint JNICALL Java_net_contentobjects_jnotify_linux_JNotify_1linux_nativeRemoveWatch
91 (JNIEnv *jni, jclass clazz, jint wd)
92 {
93 return remove_watch(wd);
94 }
95
96 /*
97 * Class: net_contentobjects_fshook_linux_INotify
98 * Method: nativeNotifyLoop
99 * Signature: ()V
100 */
101 JNIEXPORT jint JNICALL Java_net_contentobjects_jnotify_linux_JNotify_1linux_nativeNotifyLoop
102 (JNIEnv *env, jclass clazz)
103 {
104 return runLoop(env, clazz);
105 }
106
107 /**
108 * inotify fd.
109 */
110 int fd = -1;
111
112
113 /**
114 * initialize the inotify hook.
115 * returns:
116 * 0 if all ok.
117 * errno if initialization failed. (see inotify_init() documentation).
118 */
119 int init()
120 {
121 if (fd != -1)
122 {
123 return 0;
124 }
125
126 fd = inotify_init ();
127 if (fd < 0)
128 {
129 perror ("inotify_init");
130 return errno;
131 }
132 else
133 {
134 return 0;
135 }
136 }
137
138 /**
139 * Adds a watch with the specified mask.
140 * see inotify_add_watch for ddocumentation.
141 * returns -1 on error, or the watch descriptor otherwise.
142 */
143 int add_watch(char *path, __u32 mask)
144 {
145 int wd = inotify_add_watch (fd, path, mask);
95c0166 @omry removed some debug prints.
omry authored
146 int lastErr = errno;
5456c90 @omry initial commit
omry authored
147 if (wd == -1)
148 {
149 perror("inotify_add_watch");
95c0166 @omry removed some debug prints.
omry authored
150 return -lastErr;
5456c90 @omry initial commit
omry authored
151 }
152 return wd;
153 }
154
155 /**
156 * removes a watch descriptor.
157 */
158 int remove_watch(int wd)
159 {
160 int ret = inotify_rm_watch (fd, wd);
161 if (ret < 0)
162 perror ("inotify_rm_watch");
163 return ret;
164 }
165
166 void cleanup()
167 {
168 if (fd != -1)
169 {
170 if (close(fd) < 0)
171 perror ("close");
172 }
173 }
174
175 int runLoop(JNIEnv *env, jclass clazz)
176 {
177 if (fd == -1)
178 {
179 return 1;
180 }
181
182 static int BUF_LEN = 4096;
183 char buf[BUF_LEN];
184 int len, i = 0;
185
186 while (fd != -1)
187 {
188 len = read (fd, buf, BUF_LEN);
189
190 while (i < len)
191 {
192 struct inotify_event *event = (struct inotify_event *) &buf[i];
193 dispatch(env, clazz, event);
194 i += sizeof (struct inotify_event) + event->len;
195 }
196 i=0;
197 }
198
199
200 return 0;
201 }
202
203 void dispatch(JNIEnv *env, jclass clazz, struct inotify_event *event)
204 {
205 jstring name;
206 if (event->len)
207 {
208 name = (*env)->NewStringUTF(env, event->name);
209 }
210 else
211 {
212 char nostr[] = {0};
213 name = (*env)->NewStringUTF(env, nostr);
214 }
215
216 jmethodID mid = (*env)->GetStaticMethodID(env, clazz, "callbackProcessEvent", "(Ljava/lang/String;III)V");
217 if (mid == NULL)
218 {
95c0166 @omry removed some debug prints.
omry authored
219 printf("callbackProcessEvent not found! \n");
220 fflush(stdout);
5456c90 @omry initial commit
omry authored
221 return; /* method not found */
222 }
223
224 (*env)->CallStaticVoidMethod(env, clazz, mid, name, event->wd, event->mask, event->cookie);
225 //callbackProcessEvent(String name, int wd, int mask, int cookie)
226 }
227
95c0166 @omry removed some debug prints.
omry authored
228
229 /*
230 * Class: net_contentobjects_jnotify_linux_JNotify_linux
231 * Method: getErrorDesc
232 * Signature: (J)Ljava/lang/String;
233 */
234 JNIEXPORT jstring JNICALL Java_net_contentobjects_jnotify_linux_JNotify_1linux_getErrorDesc
235 (JNIEnv *env, jclass clazz, jlong errorCode)
236 {
237 const char* err;
238 if (errorCode < sys_nerr)
239 {
240 err = sys_errlist[errorCode];
241 }
242 else
243 {
244 err = "Unknown error\0";
245 }
246 return (*env)->NewStringUTF(env, err);
247 }
Something went wrong with that request. Please try again.