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
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
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. */
44 #include <gnu_java_net_local_LocalSocketImpl.h>
50 #define TRACE(msg) fprintf (stderr, "%s(%s:%d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg)
56 _throw (JNIEnv
*env
, const char *exception
, const char *msg
)
58 jclass _theclass
= (*env
)->FindClass (env
, exception
);
62 (*env
)->FatalError (env
, "exception class not found");
64 (*env
)->ThrowNew (env
, _theclass
, msg
);
69 Java_gnu_java_net_local_LocalSocketImpl_create (JNIEnv
*env
, jobject
this, jboolean stream
)
71 #ifdef ENABLE_LOCAL_SOCKETS
72 jfieldID socket_fd
, created
;
74 jint fd
= (jint
) local_create ((int) stream
);
80 _throw (env
, "java/io/IOException", local_error ());
83 clazz
= (*env
)->GetObjectClass (env
, this);
84 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
89 created
= (*env
)->GetFieldID (env
, clazz
, "created", "Z");
94 (*env
)->SetIntField (env
, this, socket_fd
, fd
);
95 (*env
)->SetBooleanField (env
, this, created
, JNI_TRUE
);
101 _throw (env
, "java/lang/Error", "support for local sockets not available");
102 #endif /* ENABLE_LOCAL_SOCKETS */
107 Java_gnu_java_net_local_LocalSocketImpl_listen (JNIEnv
*env
, jobject
this, jint backlog
)
109 #ifdef ENABLE_LOCAL_SOCKETS
116 clazz
= (*env
)->GetObjectClass (env
, this);
117 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
122 fd
= (int) (*env
)->GetIntField (env
, this, socket_fd
);
123 if (local_listen (fd
, (int) backlog
))
125 _throw (env
, "java/io/IOException", local_error ());
133 _throw (env
, "java/lang/Error", "support for local sockets not available");
134 #endif /* ENABLE_LOCAL_SOCKETS */
139 Java_gnu_java_net_local_LocalSocketImpl_accept (JNIEnv
*env
, jobject
this, jobject socket
)
141 #ifdef ENABLE_LOCAL_SOCKETS
143 jfieldID socket_fd
, remote_addr
, local_addr
;
144 jclass clazz1
, clazz2
;
145 jobject remote
, local
;
151 clazz1
= (*env
)->GetObjectClass (env
, this);
152 socket_fd
= (*env
)->GetFieldID (env
, clazz1
, "socket_fd", "I");
157 fd
= (*env
)->GetIntField (env
, this, socket_fd
);
158 fd
= (jint
) local_accept ((int) fd
, path
);
161 _throw (env
, "java/io/IOException", local_error ());
165 clazz2
= (*env
)->FindClass (env
, "gnu/java/net/local/LocalSocketAddress");
170 addr_init
= (*env
)->GetMethodID (env
, clazz2
, "<init>", "(Ljava/lang/String;)V");
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;");
182 local_addr
= (*env
)->GetFieldID (env
, clazz1
, "local", "Lgnu/java/net/local/LocalSocketAddress;");
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
);
196 _throw (env
, "java/lang/Error", "support for local sockets not available");
197 #endif /* ENABLE_LOCAL_SOCKETS */
202 Java_gnu_java_net_local_LocalSocketImpl_available
203 (JNIEnv
*env
, jobject
this __attribute__((unused
)), jint fd
)
205 #ifdef ENABLE_LOCAL_SOCKETS
210 avail
= (jint
) local_available (fd
);
213 _throw (env
, "java/io/IOException", local_error ());
223 _throw (env
, "java/lang/Error", "support for local sockets not available");
225 #endif /* ENABLE_LOCAL_SOCKETS */
230 Java_gnu_java_net_local_LocalSocketImpl_close (JNIEnv
*env
, jobject
this)
232 #ifdef ENABLE_LOCAL_SOCKETS
239 clazz
= (*env
)->GetObjectClass (env
, this);
240 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
245 fd
= (int) (*env
)->GetIntField (env
, this, socket_fd
);
246 if (local_close (fd
))
248 _throw (env
, "java/io/IOException", local_error ());
254 _throw (env
, "java/lang/Error", "support for local sockets not available");
255 #endif /* ENABLE_LOCAL_SOCKETS */
260 Java_gnu_java_net_local_LocalSocketImpl_unlink (JNIEnv
*env
, jobject
this)
262 #ifdef ENABLE_LOCAL_SOCKETS
265 jclass clazz1
, clazz2
;
266 jobject local_ref
, path
;
271 clazz1
= (*env
)->GetObjectClass (env
, this);
272 local
= (*env
)->GetFieldID (env
, clazz1
, "local", "Lgnu/java/net/local/LocalSocketAddress;");
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;");
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
);
295 _throw (env
, "java/lang/Error", "support for local sockets not available");
296 #endif /* ENABLE_LOCAL_SOCKETS */
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
305 (*env
)->FatalError (env
, "Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject) not implemented");
310 Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv
*env
, jobject
this)
312 #ifdef ENABLE_LOCAL_SOCKETS
319 clazz
= (*env
)->GetObjectClass (env
, this);
320 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
325 fd
= (*env
)->GetIntField (env
, this, socket_fd
);
326 if (local_shutdown_input (fd
))
328 _throw (env
, "java/io/IOException", local_error ());
334 _throw (env
, "java/lang/Error", "support for local sockets not available");
335 #endif /* ENABLE_LOCAL_SOCKETS */
340 Java_gnu_java_net_local_LocalSocketImpl_shutdownOutput (JNIEnv
*env
, jobject
this)
342 #ifdef ENABLE_LOCAL_SOCKETS
349 clazz
= (*env
)->GetObjectClass (env
, this);
350 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
355 fd
= (*env
)->GetIntField (env
, this, socket_fd
);
356 if (local_shutdown_output (fd
))
358 _throw (env
, "java/io/IOException", local_error ());
364 _throw (env
, "java/lang/Error", "support for local sockets not available");
365 #endif /* ENABLE_LOCAL_SOCKETS */
370 Java_gnu_java_net_local_LocalSocketImpl_localBind (JNIEnv
*env
, jobject
this, jobject address
)
372 #ifdef ENABLE_LOCAL_SOCKETS
376 jclass clazz1
, clazz2
;
377 const char *addr_path
;
382 clazz1
= (*env
)->GetObjectClass (env
, this);
383 socket_fd
= (*env
)->GetFieldID (env
, clazz1
, "socket_fd", "I");
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
);
403 _throw (env
, "java/lang/Error", "support for local sockets not available");
404 #endif /* ENABLE_LOCAL_SOCKETS */
409 Java_gnu_java_net_local_LocalSocketImpl_localConnect (JNIEnv
*env
, jobject
this, jobject address
)
411 #ifdef ENABLE_LOCAL_SOCKETS
415 jclass clazz1
, clazz2
;
421 clazz1
= (*env
)->GetObjectClass (env
, this);
422 socket_fd
= (*env
)->GetFieldID (env
, clazz1
, "socket_fd", "I");
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
);
442 _throw (env
, "java/lang/Error", "support for local sockets not available");
443 #endif /* ENABLE_LOCAL_SOCKETS */
448 Java_gnu_java_net_local_LocalSocketImpl_read
449 (JNIEnv
*env
, jobject
this __attribute__((unused
)), jint fd
, jbyteArray buf
,
452 #ifdef ENABLE_LOCAL_SOCKETS
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
);
467 _throw (env
, "java/io/IOException", local_error ());
469 (*env
)->ReleaseByteArrayElements (env
, buf
, buffer
, 0);
480 _throw (env
, "java/lang/Error", "support for local sockets not available");
482 #endif /* ENABLE_LOCAL_SOCKETS */
487 Java_gnu_java_net_local_LocalSocketImpl_write
488 (JNIEnv
*env
, jobject
this __attribute__((unused
)), jint fd
, jbyteArray buf
,
491 #ifdef ENABLE_LOCAL_SOCKETS
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
);
515 _throw (env
, "java/lang/Error", "support for local sockets not available");
516 #endif /* ENABLE_LOCAL_SOCKETS */