Merge from mainline
[official-gcc.git] / libjava / classpath / native / jni / java-net / gnu_java_net_VMPlainDatagramSocketImpl.c
blob1b3cb97e0d0639fb820e50d8873d9fea15457ea6
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)
9 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; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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 /* do not move; needed here because of some macro definitions */
39 #include <config.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
45 #include <jni.h>
46 #include <jcl.h>
48 #include "javanet.h"
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__))
72 , jobject obj)
75 #ifndef WITHOUT_NETWORK
76 _javanet_create(env, obj, 0);
77 #else /* not WITHOUT_NETWORK */
78 #endif /* not WITHOUT_NETWORK */
81 /*************************************************************************/
84 * Close the socket.
86 JNIEXPORT void JNICALL
87 Java_gnu_java_net_VMPlainDatagramSocketImpl_close(JNIEnv *env,
88 jclass klass __attribute__ ((__unused__)),
89 jobject obj)
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__)),
106 jobject obj,
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
121 * variables.
123 JNIEXPORT void JNICALL
124 Java_gnu_java_net_VMPlainDatagramSocketImpl_bind(JNIEnv *env,
125 jclass klass __attribute__ ((__unused__)),
126 jobject obj,
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__)),
144 jobject obj,
145 jint option_id,
146 jobject val)
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__)),
163 jobject obj,
164 jint option_id)
167 #ifndef WITHOUT_NETWORK
168 return(_javanet_get_option(env, obj, option_id));
169 #else /* not WITHOUT_NETWORK */
170 return NULL;
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__)),
182 jobject obj,
183 jbyteArray arr,
184 jint offset,
185 jint length,
186 jbyteArray receivedFromAddress,
187 jintArray receivedFromPort,
188 jintArray receivedLength)
190 #ifndef WITHOUT_NETWORK
191 int addr, *port, *bytes_read;
192 char *addressBytes;
194 addr = 0;
196 port = (int*)(*env)->GetIntArrayElements(env, receivedFromPort, NULL);
197 if (port == NULL)
199 JCL_ThrowException(env, IO_EXCEPTION, "Internal error: could not access receivedFromPort array");
200 return;
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");
208 return;
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
216 bytes. */
217 if (length == 0 && (*bytes_read) == -1)
218 *bytes_read = 0;
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");
225 return;
228 (*env)->ReleaseIntArrayElements(env, receivedFromPort, (jint*)port, 0);
229 (*env)->ReleaseIntArrayElements(env, receivedLength, (jint*)bytes_read, 0);
231 if ((*env)->ExceptionOccurred(env))
233 return;
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,
242 addressBytes[0],
243 addressBytes[1],
244 addressBytes[2],
245 addressBytes[3]
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__)),
261 jobject obj,
262 jobject addr,
263 jint port,
264 jarray buf,
265 jint offset,
266 jint len)
268 #ifndef WITHOUT_NETWORK
269 jint netAddress;
271 /* check if address given, tr 7.3.2005 */
272 if (addr != NULL)
274 netAddress = _javanet_get_netaddr(env, addr);
275 if ((*env)->ExceptionOccurred(env))
277 return;
280 else
282 netAddress = 0;
285 DBG("PlainDatagramSocketImpl.sendto(): have addr\n");
287 _javanet_sendto(env, obj, buf, offset, len, netAddress, port);
288 if ((*env)->ExceptionOccurred(env))
290 return;
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__)),
306 jobject obj,
307 jobject addr)
309 #ifndef WITHOUT_NETWORK
310 jint netAddress;
311 int fd;
312 int result;
314 /* check if address given, tr 7.3.2005 */
315 if (addr != NULL)
317 netAddress = _javanet_get_netaddr(env, addr);
318 if ((*env)->ExceptionOccurred(env))
320 JCL_ThrowException(env, IO_EXCEPTION, "Internal error");
321 return;
324 else
326 netAddress = 0;
329 fd = _javanet_get_int_field(env, obj, "native_fd");
330 if ((*env)->ExceptionOccurred(env))
332 JCL_ThrowException(env, IO_EXCEPTION, "Internal error");
333 return;
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());
343 return;
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__)),
359 jobject obj,
360 jobject addr)
362 #ifndef WITHOUT_NETWORK
363 jint netAddress;
364 int fd;
365 int result;
367 /* check if address given, tr 7.3.2005 */
368 if (addr != NULL)
370 netAddress = _javanet_get_netaddr(env, addr);
371 if ((*env)->ExceptionOccurred(env))
373 JCL_ThrowException(env, IO_EXCEPTION, "Internal error");
374 return;
377 else
379 netAddress = 0;
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());
392 return;
395 DBG("PlainDatagramSocketImpl.leave(): finished\n");
396 #else /* not WITHOUT_NETWORK */
397 #endif /* not WITHOUT_NETWORK */