1 /* VMPlainDatagramSocketImpl.c - Native methods for PlainDatagramSocketImpl
2 Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4 This file is 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, or (at your option)
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; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
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. */
38 /* do not move; needed here because of some macro definitions */
50 #include "target_native.h"
51 #ifndef WITHOUT_NETWORK
52 #include "target_native_network.h"
53 #endif /* WITHOUT_NETWORK */
56 #include "gnu_java_net_VMPlainDatagramSocketImpl.h"
59 * Note that most of the functions in this module simply redirect to another
60 * internal function. Why? Because many of these functions are shared
61 * with PlainSocketImpl.
64 /*************************************************************************/
67 * Creates a new datagram socket
69 JNIEXPORT
void JNICALL
70 Java_gnu_java_net_VMPlainDatagramSocketImpl_create(JNIEnv
*env
,
71 jclass klass
__attribute__ ((__unused__
))
75 #ifndef WITHOUT_NETWORK
76 _javanet_create(env
, obj
, 0);
77 #else /* not WITHOUT_NETWORK */
78 #endif /* not WITHOUT_NETWORK */
81 /*************************************************************************/
86 JNIEXPORT
void JNICALL
87 Java_gnu_java_net_VMPlainDatagramSocketImpl_close(JNIEnv
*env
,
88 jclass klass
__attribute__ ((__unused__
)),
92 #ifndef WITHOUT_NETWORK
93 _javanet_close(env
, obj
, 0);
94 #else /* not WITHOUT_NETWORK */
95 #endif /* not WITHOUT_NETWORK */
98 /*************************************************************************/
101 * Connects to the specified destination.
103 JNIEXPORT
void JNICALL
104 Java_gnu_java_net_VMPlainDatagramSocketImpl_connect(JNIEnv
*env
,
105 jclass klass
__attribute__ ((__unused__
)),
107 jobject addr
, jint port
)
109 #ifndef WITHOUT_NETWORK
111 _javanet_connect(env
, obj
, addr
, port
, 0);
112 #else /* not WITHOUT_NETWORK */
113 #endif /* not WITHOUT_NETWORK */
116 /*************************************************************************/
119 * This method binds the specified address to the specified local port.
120 * Note that we have to set the local address and local port public instance
123 JNIEXPORT
void JNICALL
124 Java_gnu_java_net_VMPlainDatagramSocketImpl_bind(JNIEnv
*env
,
125 jclass klass
__attribute__ ((__unused__
)),
127 jint port
, jobject addr
)
130 #ifndef WITHOUT_NETWORK
131 _javanet_bind(env
, obj
, addr
, port
, 0);
132 #else /* not WITHOUT_NETWORK */
133 #endif /* not WITHOUT_NETWORK */
136 /*************************************************************************/
139 * This method sets the specified option for a socket
141 JNIEXPORT
void JNICALL
142 Java_gnu_java_net_VMPlainDatagramSocketImpl_setOption(JNIEnv
*env
,
143 jclass klass
__attribute__ ((__unused__
)),
149 #ifndef WITHOUT_NETWORK
150 _javanet_set_option(env
, obj
, option_id
, val
);
151 #else /* not WITHOUT_NETWORK */
152 #endif /* not WITHOUT_NETWORK */
155 /*************************************************************************/
158 * This method sets the specified option for a socket
160 JNIEXPORT jobject JNICALL
161 Java_gnu_java_net_VMPlainDatagramSocketImpl_getOption(JNIEnv
*env
,
162 jclass klass
__attribute__ ((__unused__
)),
167 #ifndef WITHOUT_NETWORK
168 return(_javanet_get_option(env
, obj
, option_id
));
169 #else /* not WITHOUT_NETWORK */
171 #endif /* not WITHOUT_NETWORK */
174 /*************************************************************************/
177 * Reads a buffer from a remote host
179 JNIEXPORT
void JNICALL
180 Java_gnu_java_net_VMPlainDatagramSocketImpl_nativeReceive(JNIEnv
*env
,
181 jclass klass
__attribute__ ((__unused__
)),
186 jbyteArray receivedFromAddress
,
187 jintArray receivedFromPort
,
188 jintArray receivedLength
)
190 #ifndef WITHOUT_NETWORK
191 int addr
, *port
, *bytes_read
;
196 port
= (int*)(*env
)->GetIntArrayElements(env
, receivedFromPort
, NULL
);
199 JCL_ThrowException(env
, IO_EXCEPTION
, "Internal error: could not access receivedFromPort array");
203 bytes_read
= (int*)(*env
)->GetIntArrayElements(env
, receivedLength
, NULL
);
204 if (bytes_read
== NULL
)
206 (*env
)->ReleaseIntArrayElements(env
, receivedFromPort
, (jint
*)port
, 0);
207 JCL_ThrowException(env
, IO_EXCEPTION
, "Internal error: could not access receivedLength array");
211 /* Receive the packet */
212 /* should we try some sort of validation on the length? */
213 (*bytes_read
) = _javanet_recvfrom(env
, obj
, arr
, offset
, length
, &addr
, port
);
215 /* Special case the strange situation where the receiver didn't want any
217 if (length
== 0 && (*bytes_read
) == -1)
220 if ((*bytes_read
) == -1)
222 (*env
)->ReleaseIntArrayElements(env
, receivedFromPort
, (jint
*)port
, 0);
223 (*env
)->ReleaseIntArrayElements(env
, receivedLength
, (jint
*)bytes_read
, 0);
224 JCL_ThrowException(env
, IO_EXCEPTION
, "Internal error: receive");
228 (*env
)->ReleaseIntArrayElements(env
, receivedFromPort
, (jint
*)port
, 0);
229 (*env
)->ReleaseIntArrayElements(env
, receivedLength
, (jint
*)bytes_read
, 0);
231 if ((*env
)->ExceptionOccurred(env
))
236 DBG("PlainDatagramSocketImpl.receive(): Received packet\n");
239 /* Store the address */
240 addressBytes
= (char*)(*env
)->GetPrimitiveArrayCritical(env
, receivedFromAddress
, NULL
);
241 TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES(addr
,
247 (*env
)->ReleasePrimitiveArrayCritical(env
, receivedFromAddress
, addressBytes
, 0);
249 #else /* not WITHOUT_NETWORK */
250 #endif /* not WITHOUT_NETWORK */
253 /*************************************************************************/
256 * Writes a buffer to the remote host
258 JNIEXPORT
void JNICALL
259 Java_gnu_java_net_VMPlainDatagramSocketImpl_nativeSendTo(JNIEnv
*env
,
260 jclass klass
__attribute__ ((__unused__
)),
268 #ifndef WITHOUT_NETWORK
271 /* check if address given, tr 7.3.2005 */
274 netAddress
= _javanet_get_netaddr(env
, addr
);
275 if ((*env
)->ExceptionOccurred(env
))
285 DBG("PlainDatagramSocketImpl.sendto(): have addr\n");
287 _javanet_sendto(env
, obj
, buf
, offset
, len
, netAddress
, port
);
288 if ((*env
)->ExceptionOccurred(env
))
293 DBG("PlainDatagramSocketImpl.sendto(): finished\n");
294 #else /* not WITHOUT_NETWORK */
295 #endif /* not WITHOUT_NETWORK */
298 /*************************************************************************/
301 * Joins a multicast group
303 JNIEXPORT
void JNICALL
304 Java_gnu_java_net_VMPlainDatagramSocketImpl_join(JNIEnv
*env
,
305 jclass klass
__attribute__ ((__unused__
)),
309 #ifndef WITHOUT_NETWORK
314 /* check if address given, tr 7.3.2005 */
317 netAddress
= _javanet_get_netaddr(env
, addr
);
318 if ((*env
)->ExceptionOccurred(env
))
320 JCL_ThrowException(env
, IO_EXCEPTION
, "Internal error");
329 fd
= _javanet_get_int_field(env
, obj
, "native_fd");
330 if ((*env
)->ExceptionOccurred(env
))
332 JCL_ThrowException(env
, IO_EXCEPTION
, "Internal error");
336 DBG("PlainDatagramSocketImpl.join(): have native fd\n");
338 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_ADD_MEMBERSHIP(fd
,netAddress
,result
);
340 if (result
!= TARGET_NATIVE_OK
)
342 JCL_ThrowException(env
, IO_EXCEPTION
, TARGET_NATIVE_LAST_ERROR_STRING());
346 DBG("PlainDatagramSocketImpl.join(): finished\n");
347 #else /* not WITHOUT_NETWORK */
348 #endif /* not WITHOUT_NETWORK */
351 /*************************************************************************/
354 * Leaves a multicast group
356 JNIEXPORT
void JNICALL
357 Java_gnu_java_net_VMPlainDatagramSocketImpl_leave(JNIEnv
*env
,
358 jclass klass
__attribute__ ((__unused__
)),
362 #ifndef WITHOUT_NETWORK
367 /* check if address given, tr 7.3.2005 */
370 netAddress
= _javanet_get_netaddr(env
, addr
);
371 if ((*env
)->ExceptionOccurred(env
))
373 JCL_ThrowException(env
, IO_EXCEPTION
, "Internal error");
382 fd
= _javanet_get_int_field(env
, obj
, "native_fd");
383 if ((*env
)->ExceptionOccurred(env
))
384 { JCL_ThrowException(env
, IO_EXCEPTION
, "Internal error"); return; }
386 DBG("PlainDatagramSocketImpl.leave(): have native fd\n");
388 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_DROP_MEMBERSHIP(fd
,netAddress
,result
);
389 if (result
!=TARGET_NATIVE_OK
)
391 JCL_ThrowException(env
, IO_EXCEPTION
, TARGET_NATIVE_LAST_ERROR_STRING());
395 DBG("PlainDatagramSocketImpl.leave(): finished\n");
396 #else /* not WITHOUT_NETWORK */
397 #endif /* not WITHOUT_NETWORK */