libjava/
[official-gcc.git] / libjava / classpath / native / jni / java-net / gnu_java_net_local_LocalSocketImpl.c
blob288653d51f05eb0dbfaa267ef0326f4b43379d25
1 /* gnu_java_net_local_LocalSocketImpl.c -- native local socket implementation.
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is a part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at
9 your option) any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 USA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 #ifndef _GNU_SOURCE
39 #define _GNU_SOURCE
40 #endif
42 #include "config.h"
44 #include <gnu_java_net_local_LocalSocketImpl.h>
46 #include <stddef.h>
47 #include "local.h"
49 #ifdef DEBUG
50 #define TRACE(msg) fprintf (stderr, "%s(%s:%d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg)
51 #else
52 #define TRACE(msg)
53 #endif
55 static void
56 _throw (JNIEnv *env, const char *exception, const char *msg)
58 jclass _theclass = (*env)->FindClass (env, exception);
59 TRACE("begin");
60 if (!_theclass)
62 (*env)->FatalError (env, "exception class not found");
64 (*env)->ThrowNew (env, _theclass, msg);
65 TRACE("end");
68 void
69 Java_gnu_java_net_local_LocalSocketImpl_create (JNIEnv *env, jobject this, jboolean stream)
71 #ifdef ENABLE_LOCAL_SOCKETS
72 jfieldID socket_fd, created;
73 jclass clazz;
74 jint fd = (jint) local_create ((int) stream);
76 TRACE("begin");
78 if (fd < 0)
80 _throw (env, "java/io/IOException", local_error ());
81 return;
83 clazz = (*env)->GetObjectClass (env, this);
84 socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
85 if (!socket_fd)
87 return;
89 created = (*env)->GetFieldID (env, clazz, "created", "Z");
90 if (!created)
92 return;
94 (*env)->SetIntField (env, this, socket_fd, fd);
95 (*env)->SetBooleanField (env, this, created, JNI_TRUE);
97 TRACE("end");
98 #else
99 (void) this;
100 (void) stream;
101 _throw (env, "java/lang/Error", "support for local sockets not available");
102 #endif /* ENABLE_LOCAL_SOCKETS */
106 void
107 Java_gnu_java_net_local_LocalSocketImpl_listen (JNIEnv *env, jobject this, jint backlog)
109 #ifdef ENABLE_LOCAL_SOCKETS
110 jfieldID socket_fd;
111 jclass clazz;
112 int fd;
114 TRACE("begin");
116 clazz = (*env)->GetObjectClass (env, this);
117 socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
118 if (!socket_fd)
120 return;
122 fd = (int) (*env)->GetIntField (env, this, socket_fd);
123 if (local_listen (fd, (int) backlog))
125 _throw (env, "java/io/IOException", local_error ());
126 return;
129 TRACE("end");
130 #else
131 (void) this;
132 (void) backlog;
133 _throw (env, "java/lang/Error", "support for local sockets not available");
134 #endif /* ENABLE_LOCAL_SOCKETS */
138 void
139 Java_gnu_java_net_local_LocalSocketImpl_accept (JNIEnv *env, jobject this, jobject socket)
141 #ifdef ENABLE_LOCAL_SOCKETS
142 jmethodID addr_init;
143 jfieldID socket_fd, remote_addr, local_addr;
144 jclass clazz1, clazz2;
145 jobject remote, local;
146 jint fd;
147 char path[108];
149 TRACE("begin");
151 clazz1 = (*env)->GetObjectClass (env, this);
152 socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I");
153 if (!socket_fd)
155 return;
157 fd = (*env)->GetIntField (env, this, socket_fd);
158 fd = (jint) local_accept ((int) fd, path);
159 if (fd < 0)
161 _throw (env, "java/io/IOException", local_error ());
162 return;
165 clazz2 = (*env)->FindClass (env, "gnu/java/net/local/LocalSocketAddress");
166 if (!clazz2)
168 return;
170 addr_init = (*env)->GetMethodID (env, clazz2, "<init>", "(Ljava/lang/String;)V");
171 if (!addr_init)
173 return;
175 remote = (*env)->NewObject (env, clazz2, addr_init, (*env)->NewStringUTF (env, path));
177 remote_addr = (*env)->GetFieldID (env, clazz1, "remote", "Lgnu/java/net/local/LocalSocketAddress;");
178 if (!remote_addr)
180 return;
182 local_addr = (*env)->GetFieldID (env, clazz1, "local", "Lgnu/java/net/local/LocalSocketAddress;");
183 if (!local_addr)
185 return;
187 local = (*env)->GetObjectField (env, this, local_addr);
188 (*env)->SetIntField (env, socket, socket_fd, fd);
189 (*env)->SetObjectField (env, socket, remote_addr, remote);
190 (*env)->SetObjectField (env, socket, local_addr, local);
192 TRACE("end");
193 #else
194 (void) this;
195 (void) socket;
196 _throw (env, "java/lang/Error", "support for local sockets not available");
197 #endif /* ENABLE_LOCAL_SOCKETS */
201 jint
202 Java_gnu_java_net_local_LocalSocketImpl_available
203 (JNIEnv *env, jobject this __attribute__((unused)), jint fd)
205 #ifdef ENABLE_LOCAL_SOCKETS
206 jint avail;
208 TRACE("begin");
210 avail = (jint) local_available (fd);
211 if (avail < 0)
213 _throw (env, "java/io/IOException", local_error ());
214 return 0;
217 TRACE("end");
219 return avail;
220 #else
221 (void) this;
222 (void) fd;
223 _throw (env, "java/lang/Error", "support for local sockets not available");
224 return -1;
225 #endif /* ENABLE_LOCAL_SOCKETS */
229 void
230 Java_gnu_java_net_local_LocalSocketImpl_close (JNIEnv *env, jobject this)
232 #ifdef ENABLE_LOCAL_SOCKETS
233 jfieldID socket_fd;
234 jclass clazz;
235 int fd;
237 TRACE("begin");
239 clazz = (*env)->GetObjectClass (env, this);
240 socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
241 if (!socket_fd)
243 return;
245 fd = (int) (*env)->GetIntField (env, this, socket_fd);
246 if (local_close (fd))
248 _throw (env, "java/io/IOException", local_error ());
251 TRACE("end");
252 #else
253 (void) this;
254 _throw (env, "java/lang/Error", "support for local sockets not available");
255 #endif /* ENABLE_LOCAL_SOCKETS */
259 void
260 Java_gnu_java_net_local_LocalSocketImpl_unlink (JNIEnv *env, jobject this)
262 #ifdef ENABLE_LOCAL_SOCKETS
263 jfieldID local;
264 jmethodID get_path;
265 jclass clazz1, clazz2;
266 jobject local_ref, path;
267 char *addr_path;
269 TRACE("begin");
271 clazz1 = (*env)->GetObjectClass (env, this);
272 local = (*env)->GetFieldID (env, clazz1, "local", "Lgnu/java/net/local/LocalSocketAddress;");
273 if (!local)
275 return;
277 local_ref = (*env)->GetObjectField (env, this, local);
278 clazz2 = (*env)->GetObjectClass (env, local_ref);
279 get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;");
280 if (!get_path)
282 return;
284 path = (*env)->CallObjectMethod (env, local_ref, get_path);
285 addr_path = (char *) (*env)->GetStringUTFChars (env, (jstring) path, NULL);
286 if (local_unlink (addr_path))
288 _throw (env, "java/io/IOException", local_error ());
290 (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path);
292 TRACE("end");
293 #else
294 (void) this;
295 _throw (env, "java/lang/Error", "support for local sockets not available");
296 #endif /* ENABLE_LOCAL_SOCKETS */
300 void
301 Java_gnu_java_net_local_LocalSocketImpl_sendUrgentData (JNIEnv *env, jobject this __attribute__((unused)), jint data __attribute__((unused)))
303 /* XXX I don't remember why I have this. Probably should just
304 remove. */
305 (*env)->FatalError (env, "Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject) not implemented");
309 void
310 Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject this)
312 #ifdef ENABLE_LOCAL_SOCKETS
313 jfieldID socket_fd;
314 jclass clazz;
315 int fd;
317 TRACE("begin");
319 clazz = (*env)->GetObjectClass (env, this);
320 socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
321 if (!socket_fd)
323 return;
325 fd = (*env)->GetIntField (env, this, socket_fd);
326 if (local_shutdown_input (fd))
328 _throw (env, "java/io/IOException", local_error ());
331 TRACE("end");
332 #else
333 (void) this;
334 _throw (env, "java/lang/Error", "support for local sockets not available");
335 #endif /* ENABLE_LOCAL_SOCKETS */
339 void
340 Java_gnu_java_net_local_LocalSocketImpl_shutdownOutput (JNIEnv *env, jobject this)
342 #ifdef ENABLE_LOCAL_SOCKETS
343 jfieldID socket_fd;
344 jclass clazz;
345 int fd;
347 TRACE("begin");
349 clazz = (*env)->GetObjectClass (env, this);
350 socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
351 if (!socket_fd)
353 return;
355 fd = (*env)->GetIntField (env, this, socket_fd);
356 if (local_shutdown_output (fd))
358 _throw (env, "java/io/IOException", local_error ());
361 TRACE("end");
362 #else
363 (void) this;
364 _throw (env, "java/lang/Error", "support for local sockets not available");
365 #endif /* ENABLE_LOCAL_SOCKETS */
369 void
370 Java_gnu_java_net_local_LocalSocketImpl_localBind (JNIEnv *env, jobject this, jobject address)
372 #ifdef ENABLE_LOCAL_SOCKETS
373 jfieldID socket_fd;
374 jmethodID get_path;
375 jobject path;
376 jclass clazz1, clazz2;
377 const char *addr_path;
378 int fd;
380 TRACE("begin");
382 clazz1 = (*env)->GetObjectClass (env, this);
383 socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I");
384 if (!socket_fd)
386 return;
388 fd = (int) (*env)->GetIntField (env, this, socket_fd);
389 clazz2 = (*env)->GetObjectClass (env, address);
390 get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;");
391 path = (*env)->CallObjectMethod (env, address, get_path);
392 addr_path = (*env)->GetStringUTFChars (env, (jstring) path, NULL);
393 if (local_bind (fd, addr_path))
395 _throw (env, "java/io/IOException", local_error ());
397 (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path);
399 TRACE("end");
400 #else
401 (void) this;
402 (void) address;
403 _throw (env, "java/lang/Error", "support for local sockets not available");
404 #endif /* ENABLE_LOCAL_SOCKETS */
408 void
409 Java_gnu_java_net_local_LocalSocketImpl_localConnect (JNIEnv *env, jobject this, jobject address)
411 #ifdef ENABLE_LOCAL_SOCKETS
412 jfieldID socket_fd;
413 jmethodID get_path;
414 jobject path;
415 jclass clazz1, clazz2;
416 char *addr_path;
417 int fd;
419 TRACE("begin");
421 clazz1 = (*env)->GetObjectClass (env, this);
422 socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I");
423 if (!socket_fd)
425 return;
427 fd = (int) (*env)->GetIntField (env, this, socket_fd);
428 clazz2 = (*env)->GetObjectClass (env, address);
429 get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;");
430 path = (*env)->CallObjectMethod (env, address, get_path);
431 addr_path = (char *) (*env)->GetStringUTFChars (env, (jstring) path, NULL);
432 if (local_connect (fd, addr_path))
434 _throw (env, "java/io/IOException", local_error ());
436 (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path);
438 TRACE("end");
439 #else
440 (void) this;
441 (void) address;
442 _throw (env, "java/lang/Error", "support for local sockets not available");
443 #endif /* ENABLE_LOCAL_SOCKETS */
447 jint
448 Java_gnu_java_net_local_LocalSocketImpl_read
449 (JNIEnv *env, jobject this __attribute__((unused)), jint fd, jbyteArray buf,
450 jint off, jint len)
452 #ifdef ENABLE_LOCAL_SOCKETS
453 jbyte *buffer;
454 jint count;
456 TRACE("begin");
458 if (off < 0 || len < 0 || off + len > (*env)->GetArrayLength (env, buf))
460 _throw (env, "java/lang/ArrayIndexOutOfBoundsException", "");
463 buffer = (*env)->GetByteArrayElements (env, buf, NULL);
464 count = (jint) local_read (fd, (void *) (buffer + off), (int) len);
465 if (count < 0)
467 _throw (env, "java/io/IOException", local_error ());
469 (*env)->ReleaseByteArrayElements (env, buf, buffer, 0);
471 TRACE("end");
473 return count;
474 #else
475 (void) this;
476 (void) fd;
477 (void) buf;
478 (void) off;
479 (void) len;
480 _throw (env, "java/lang/Error", "support for local sockets not available");
481 return -1;
482 #endif /* ENABLE_LOCAL_SOCKETS */
486 void
487 Java_gnu_java_net_local_LocalSocketImpl_write
488 (JNIEnv *env, jobject this __attribute__((unused)), jint fd, jbyteArray buf,
489 jint off, jint len)
491 #ifdef ENABLE_LOCAL_SOCKETS
492 jbyte *buffer;
494 TRACE("begin");
496 if (off < 0 || len < 0 || off + len > (*env)->GetArrayLength (env, buf))
498 _throw (env, "java/lang/ArrayIndexOutOfBoundsException", "");
501 buffer = (*env)->GetByteArrayElements (env, buf, NULL);
502 if (local_write (fd, (void *) (buffer + off), (int) len) < 0)
504 _throw (env, "java/io/IOException", local_error ());
506 (*env)->ReleaseByteArrayElements (env, buf, buffer, JNI_ABORT);
508 TRACE("end");
509 #else
510 (void) this;
511 (void) fd;
512 (void) buf;
513 (void) off;
514 (void) len;
515 _throw (env, "java/lang/Error", "support for local sockets not available");
516 #endif /* ENABLE_LOCAL_SOCKETS */