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. */
43 #endif /* HAVE_CONFIG_H */
45 #include <gnu_java_net_local_LocalSocketImpl.h>
51 #define TRACE(msg) fprintf (stderr, "%s(%s:%d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg)
57 _throw (JNIEnv
*env
, const char *exception
, const char *msg
)
59 jclass _theclass
= (*env
)->FindClass (env
, exception
);
63 (*env
)->FatalError (env
, "exception class not found");
65 (*env
)->ThrowNew (env
, _theclass
, msg
);
70 Java_gnu_java_net_local_LocalSocketImpl_create (JNIEnv
*env
, jobject
this, jboolean stream
)
72 #ifdef ENABLE_LOCAL_SOCKETS
73 jfieldID socket_fd
, created
;
75 jint fd
= (jint
) local_create ((int) stream
);
81 _throw (env
, "java/io/IOException", local_error ());
84 clazz
= (*env
)->GetObjectClass (env
, this);
85 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
90 created
= (*env
)->GetFieldID (env
, clazz
, "created", "Z");
95 (*env
)->SetIntField (env
, this, socket_fd
, fd
);
96 (*env
)->SetBooleanField (env
, this, created
, JNI_TRUE
);
102 _throw (env
, "java/lang/Error", "support for local sockets not available");
103 #endif /* ENABLE_LOCAL_SOCKETS */
108 Java_gnu_java_net_local_LocalSocketImpl_listen (JNIEnv
*env
, jobject
this, jint backlog
)
110 #ifdef ENABLE_LOCAL_SOCKETS
117 clazz
= (*env
)->GetObjectClass (env
, this);
118 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
123 fd
= (int) (*env
)->GetIntField (env
, this, socket_fd
);
124 if (local_listen (fd
, (int) backlog
))
126 _throw (env
, "java/io/IOException", local_error ());
134 _throw (env
, "java/lang/Error", "support for local sockets not available");
135 #endif /* ENABLE_LOCAL_SOCKETS */
140 Java_gnu_java_net_local_LocalSocketImpl_accept (JNIEnv
*env
, jobject
this, jobject socket
)
142 #ifdef ENABLE_LOCAL_SOCKETS
144 jfieldID socket_fd
, remote_addr
, local_addr
;
145 jclass clazz1
, clazz2
;
146 jobject remote
, local
;
152 clazz1
= (*env
)->GetObjectClass (env
, this);
153 socket_fd
= (*env
)->GetFieldID (env
, clazz1
, "socket_fd", "I");
158 fd
= (*env
)->GetIntField (env
, this, socket_fd
);
159 fd
= (jint
) local_accept ((int) fd
, path
);
162 _throw (env
, "java/io/IOException", local_error ());
166 clazz2
= (*env
)->FindClass (env
, "gnu/java/net/local/LocalSocketAddress");
171 addr_init
= (*env
)->GetMethodID (env
, clazz2
, "<init>", "(Ljava/lang/String;)V");
176 remote
= (*env
)->NewObject (env
, clazz2
, addr_init
, (*env
)->NewStringUTF (env
, path
));
178 remote_addr
= (*env
)->GetFieldID (env
, clazz1
, "remote", "Lgnu/java/net/local/LocalSocketAddress;");
183 local_addr
= (*env
)->GetFieldID (env
, clazz1
, "local", "Lgnu/java/net/local/LocalSocketAddress;");
188 local
= (*env
)->GetObjectField (env
, this, local_addr
);
189 (*env
)->SetIntField (env
, socket
, socket_fd
, fd
);
190 (*env
)->SetObjectField (env
, socket
, remote_addr
, remote
);
191 (*env
)->SetObjectField (env
, socket
, local_addr
, local
);
197 _throw (env
, "java/lang/Error", "support for local sockets not available");
198 #endif /* ENABLE_LOCAL_SOCKETS */
203 Java_gnu_java_net_local_LocalSocketImpl_available (JNIEnv
*env
, jobject
this)
205 #ifdef ENABLE_LOCAL_SOCKETS
212 clazz
= (*env
)->GetObjectClass (env
, this);
213 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
218 avail
= (jint
) local_available ((int) (*env
)->GetIntField (env
, this, socket_fd
));
221 _throw (env
, "java/io/IOException", local_error ());
230 _throw (env
, "java/lang/Error", "support for local sockets not available");
232 #endif /* ENABLE_LOCAL_SOCKETS */
237 Java_gnu_java_net_local_LocalSocketImpl_close (JNIEnv
*env
, jobject
this)
239 #ifdef ENABLE_LOCAL_SOCKETS
246 clazz
= (*env
)->GetObjectClass (env
, this);
247 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
252 fd
= (int) (*env
)->GetIntField (env
, this, socket_fd
);
253 if (local_close (fd
))
255 _throw (env
, "java/io/IOException", local_error ());
261 _throw (env
, "java/lang/Error", "support for local sockets not available");
262 #endif /* ENABLE_LOCAL_SOCKETS */
267 Java_gnu_java_net_local_LocalSocketImpl_unlink (JNIEnv
*env
, jobject
this)
269 #ifdef ENABLE_LOCAL_SOCKETS
272 jclass clazz1
, clazz2
;
273 jobject local_ref
, path
;
278 clazz1
= (*env
)->GetObjectClass (env
, this);
279 local
= (*env
)->GetFieldID (env
, clazz1
, "local", "Lgnu/java/net/local/LocalSocketAddress;");
284 local_ref
= (*env
)->GetObjectField (env
, this, local
);
285 clazz2
= (*env
)->GetObjectClass (env
, local_ref
);
286 get_path
= (*env
)->GetMethodID (env
, clazz2
, "getPath", "()Ljava/lang/String;");
291 path
= (*env
)->CallObjectMethod (env
, local_ref
, get_path
);
292 addr_path
= (char *) (*env
)->GetStringUTFChars (env
, (jstring
) path
, NULL
);
293 if (local_unlink (addr_path
))
295 _throw (env
, "java/io/IOException", local_error ());
297 (*env
)->ReleaseStringUTFChars (env
, (jstring
) path
, addr_path
);
302 _throw (env
, "java/lang/Error", "support for local sockets not available");
303 #endif /* ENABLE_LOCAL_SOCKETS */
308 Java_gnu_java_net_local_LocalSocketImpl_sendUrgentData (JNIEnv
*env
, jobject
this __attribute__((unused
)), jint data
__attribute__((unused
)))
310 /* XXX I don't remember why I have this. Probably should just
312 (*env
)->FatalError (env
, "Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject) not implemented");
317 Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv
*env
, jobject
this)
319 #ifdef ENABLE_LOCAL_SOCKETS
326 clazz
= (*env
)->GetObjectClass (env
, this);
327 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
332 fd
= (*env
)->GetIntField (env
, this, socket_fd
);
333 if (local_shutdown_input (fd
))
335 _throw (env
, "java/io/IOException", local_error ());
341 _throw (env
, "java/lang/Error", "support for local sockets not available");
342 #endif /* ENABLE_LOCAL_SOCKETS */
347 Java_gnu_java_net_local_LocalSocketImpl_shutdownOutput (JNIEnv
*env
, jobject
this)
349 #ifdef ENABLE_LOCAL_SOCKETS
356 clazz
= (*env
)->GetObjectClass (env
, this);
357 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
362 fd
= (*env
)->GetIntField (env
, this, socket_fd
);
363 if (local_shutdown_output (fd
))
365 _throw (env
, "java/io/IOException", local_error ());
371 _throw (env
, "java/lang/Error", "support for local sockets not available");
372 #endif /* ENABLE_LOCAL_SOCKETS */
377 Java_gnu_java_net_local_LocalSocketImpl_localBind (JNIEnv
*env
, jobject
this, jobject address
)
379 #ifdef ENABLE_LOCAL_SOCKETS
383 jclass clazz1
, clazz2
;
384 const char *addr_path
;
389 clazz1
= (*env
)->GetObjectClass (env
, this);
390 socket_fd
= (*env
)->GetFieldID (env
, clazz1
, "socket_fd", "I");
395 fd
= (int) (*env
)->GetIntField (env
, this, socket_fd
);
396 clazz2
= (*env
)->GetObjectClass (env
, address
);
397 get_path
= (*env
)->GetMethodID (env
, clazz2
, "getPath", "()Ljava/lang/String;");
398 path
= (*env
)->CallObjectMethod (env
, address
, get_path
);
399 addr_path
= (*env
)->GetStringUTFChars (env
, (jstring
) path
, NULL
);
400 if (local_bind (fd
, addr_path
))
402 _throw (env
, "java/io/IOException", local_error ());
404 (*env
)->ReleaseStringUTFChars (env
, (jstring
) path
, addr_path
);
410 _throw (env
, "java/lang/Error", "support for local sockets not available");
411 #endif /* ENABLE_LOCAL_SOCKETS */
416 Java_gnu_java_net_local_LocalSocketImpl_localConnect (JNIEnv
*env
, jobject
this, jobject address
)
418 #ifdef ENABLE_LOCAL_SOCKETS
422 jclass clazz1
, clazz2
;
428 clazz1
= (*env
)->GetObjectClass (env
, this);
429 socket_fd
= (*env
)->GetFieldID (env
, clazz1
, "socket_fd", "I");
434 fd
= (int) (*env
)->GetIntField (env
, this, socket_fd
);
435 clazz2
= (*env
)->GetObjectClass (env
, address
);
436 get_path
= (*env
)->GetMethodID (env
, clazz2
, "getPath", "()Ljava/lang/String;");
437 path
= (*env
)->CallObjectMethod (env
, address
, get_path
);
438 addr_path
= (char *) (*env
)->GetStringUTFChars (env
, (jstring
) path
, NULL
);
439 if (local_connect (fd
, addr_path
))
441 _throw (env
, "java/io/IOException", local_error ());
443 (*env
)->ReleaseStringUTFChars (env
, (jstring
) path
, addr_path
);
449 _throw (env
, "java/lang/Error", "support for local sockets not available");
450 #endif /* ENABLE_LOCAL_SOCKETS */
455 Java_gnu_java_net_local_LocalSocketImpl_read (JNIEnv
*env
, jobject
this, jbyteArray buf
, jint off
, jint len
)
457 #ifdef ENABLE_LOCAL_SOCKETS
466 if (off
< 0 || len
< 0 || off
+ len
> (*env
)->GetArrayLength (env
, buf
))
468 _throw (env
, "java/lang/ArrayIndexOutOfBoundsException", "");
471 clazz
= (*env
)->GetObjectClass (env
, this);
472 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
477 fd
= (int) (*env
)->GetIntField (env
, this, socket_fd
);
478 buffer
= (*env
)->GetByteArrayElements (env
, buf
, NULL
);
479 count
= (jint
) local_read (fd
, (void *) (buffer
+ off
), (int) len
);
482 _throw (env
, "java/io/IOException", local_error ());
484 (*env
)->ReleaseByteArrayElements (env
, buf
, buffer
, 0);
494 _throw (env
, "java/lang/Error", "support for local sockets not available");
496 #endif /* ENABLE_LOCAL_SOCKETS */
501 Java_gnu_java_net_local_LocalSocketImpl_write (JNIEnv
*env
, jobject
this, jbyteArray buf
, jint off
, jint len
)
503 #ifdef ENABLE_LOCAL_SOCKETS
511 if (off
< 0 || len
< 0 || off
+ len
> (*env
)->GetArrayLength (env
, buf
))
513 _throw (env
, "java/lang/ArrayIndexOutOfBoundsException", "");
516 clazz
= (*env
)->GetObjectClass (env
, this);
517 socket_fd
= (*env
)->GetFieldID (env
, clazz
, "socket_fd", "I");
522 fd
= (int) (*env
)->GetIntField (env
, this, socket_fd
);
523 buffer
= (*env
)->GetByteArrayElements (env
, buf
, NULL
);
524 if (local_write (fd
, (void *) (buffer
+ off
), (int) len
) < 0)
526 _throw (env
, "java/io/IOException", local_error ());
528 (*env
)->ReleaseByteArrayElements (env
, buf
, buffer
, JNI_ABORT
);
536 _throw (env
, "java/lang/Error", "support for local sockets not available");
537 #endif /* ENABLE_LOCAL_SOCKETS */