1 /* PlainSocketImpl.c - Native methods for PlainSocketImpl class
2 Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc.
3
4 Modifications are copyright (C) 2004 by Etienne M. Gagnon
5 <gagnon.etienne_m@uqam.ca>. All rights reserved.
6
7 This file is part of GNU Classpath.
8
9 GNU Classpath is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GNU Classpath is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU Classpath; see the file COPYING. If not, write to the
21 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301 USA.
23
24 Linking this library statically or dynamically with other modules is
25 making a combined work based on this library. Thus, the terms and
26 conditions of the GNU General Public License cover the whole
27 combination.
28
29 As a special exception, the copyright holders of this library give you
30 permission to link this library with independent modules to produce an
31 executable, regardless of the license terms of these independent
32 modules, and to copy and distribute the resulting executable under
33 terms of your choice, provided that you also meet, for each linked
34 independent module, the terms and conditions of the license of that
35 module. An independent module is a module which is not derived from
36 or based on this library. If you modify this library, you may extend
37 this exception to your version of the library, but you are not
38 obligated to do so. If you do not wish to do so, delete this
39 exception statement from your version. */
40
41 /* do not move; needed here because of some macro definitions */
42 #include <config.h>
43
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <assert.h>
48
49 #include <jni.h>
50 #include <jcl.h>
51
52 #include "javanet.h"
53
54 #include "target_native.h"
55 #ifndef WITHOUT_NETWORK
56 #include "target_native_file.h" /* Get FIONREAD on Solaris. */
57 #include "target_native_network.h"
58 #endif /* WITHOUT_NETWORK */
59
60 #include "gnu_java_net_PlainSocketImpl.h"
61
62 /*
63 * Note that the functions in this module simply redirect to another
64 * internal function. Why? Because many of these functions are shared
65 * with PlainDatagramSocketImpl. The unshared ones were done the same
66 * way for consistency.
67 */
68
69 /*************************************************************************/
70
71 /*
72 * Creates a new stream or datagram socket
73 */
74 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_create(JNIEnv * env,jobject this,jboolean stream)75 Java_gnu_java_net_PlainSocketImpl_create (JNIEnv * env, jobject this,
76 jboolean stream)
77 {
78 #ifndef WITHOUT_NETWORK
79 assert (env != NULL);
80 assert ((*env) != NULL);
81
82 _javanet_create (env, this, stream);
83 #else /* not WITHOUT_NETWORK */
84 #endif /* not WITHOUT_NETWORK */
85 }
86
87 /*************************************************************************/
88
89 /*
90 * Close the socket. Any underlying streams will be closed by this
91 * action as well.
92 */
93 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_close(JNIEnv * env,jobject this)94 Java_gnu_java_net_PlainSocketImpl_close (JNIEnv * env, jobject this)
95 {
96 #ifndef WITHOUT_NETWORK
97 assert (env != NULL);
98 assert ((*env) != NULL);
99
100 _javanet_close (env, this, 1);
101 #else /* not WITHOUT_NETWORK */
102 #endif /* not WITHOUT_NETWORK */
103 }
104
105 /*************************************************************************/
106
107 /*
108 * Connects to the specified destination.
109 */
110 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_connect(JNIEnv * env,jobject this,jobject addr,jint port)111 Java_gnu_java_net_PlainSocketImpl_connect (JNIEnv * env, jobject this,
112 jobject addr, jint port)
113 {
114 #ifndef WITHOUT_NETWORK
115 assert (env != NULL);
116 assert ((*env) != NULL);
117
118 _javanet_connect (env, this, addr, port);
119 #else /* not WITHOUT_NETWORK */
120 #endif /* not WITHOUT_NETWORK */
121 }
122
123 /*************************************************************************/
124
125 /*
126 * This method binds the specified address to the specified local port.
127 * Note that we have to set the local address and local port public instance
128 * variables.
129 */
130 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_bind(JNIEnv * env,jobject this,jobject addr,jint port)131 Java_gnu_java_net_PlainSocketImpl_bind (JNIEnv * env, jobject this,
132 jobject addr, jint port)
133 {
134 #ifndef WITHOUT_NETWORK
135 assert (env != NULL);
136 assert ((*env) != NULL);
137
138 _javanet_bind (env, this, addr, port, 1);
139 #else /* not WITHOUT_NETWORK */
140 #endif /* not WITHOUT_NETWORK */
141 }
142
143 /*************************************************************************/
144
145 /*
146 * Starts listening on a socket with the specified number of pending
147 * connections allowed.
148 */
149 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_listen(JNIEnv * env,jobject this,jint queuelen)150 Java_gnu_java_net_PlainSocketImpl_listen (JNIEnv * env, jobject this,
151 jint queuelen)
152 {
153 #ifndef WITHOUT_NETWORK
154 assert (env != NULL);
155 assert ((*env) != NULL);
156
157 _javanet_listen (env, this, queuelen);
158 #else /* not WITHOUT_NETWORK */
159 #endif /* not WITHOUT_NETWORK */
160 }
161
162 /*************************************************************************/
163
164 /*
165 * Accepts a new connection and assigns it to the passed in SocketImpl
166 * object. Note that we assume this is a PlainSocketImpl just like us.
167 */
168 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_accept(JNIEnv * env,jobject this,jobject impl)169 Java_gnu_java_net_PlainSocketImpl_accept (JNIEnv * env, jobject this,
170 jobject impl)
171 {
172 #ifndef WITHOUT_NETWORK
173 assert (env != NULL);
174 assert ((*env) != NULL);
175
176 _javanet_accept (env, this, impl);
177 #else /* not WITHOUT_NETWORK */
178 #endif /* not WITHOUT_NETWORK */
179 }
180
181 /*************************************************************************/
182
183 JNIEXPORT jint JNICALL
Java_gnu_java_net_PlainSocketImpl_available(JNIEnv * env,jobject this)184 Java_gnu_java_net_PlainSocketImpl_available (JNIEnv * env, jobject this)
185 {
186 #ifndef WITHOUT_NETWORK
187 jclass cls;
188 jfieldID fid;
189 int fd;
190 int bytesAvailable;
191 int result;
192
193 assert (env != NULL);
194 assert ((*env) != NULL);
195
196 cls = (*env)->GetObjectClass (env, this);
197 if (cls == 0)
198 {
199 JCL_ThrowException (env, IO_EXCEPTION, "internal error");
200 return 0;
201 }
202
203 fid = (*env)->GetFieldID (env, cls, "native_fd", "I");
204 if (fid == 0)
205 {
206 JCL_ThrowException (env, IO_EXCEPTION, "internal error");
207 return 0;
208 }
209
210 fd = (*env)->GetIntField (env, this, fid);
211
212 TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_AVAILABLE (fd, bytesAvailable, result);
213 if (result != TARGET_NATIVE_OK)
214 {
215 JCL_ThrowException (env, IO_EXCEPTION,
216 TARGET_NATIVE_LAST_ERROR_STRING ());
217 return 0;
218 }
219
220 return bytesAvailable;
221 #else /* not WITHOUT_NETWORK */
222 return 0;
223 #endif /* not WITHOUT_NETWORK */
224 }
225
226 /*************************************************************************/
227
228 /*
229 * This method sets the specified option for a socket
230 */
231 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_setOption(JNIEnv * env,jobject this,jint option_id,jobject val)232 Java_gnu_java_net_PlainSocketImpl_setOption (JNIEnv * env, jobject this,
233 jint option_id, jobject val)
234 {
235 #ifndef WITHOUT_NETWORK
236 assert (env != NULL);
237 assert ((*env) != NULL);
238
239 _javanet_set_option (env, this, option_id, val);
240 #else /* not WITHOUT_NETWORK */
241 #endif /* not WITHOUT_NETWORK */
242 }
243
244 /*************************************************************************/
245
246 /*
247 * This method sets the specified option for a socket
248 */
249 JNIEXPORT jobject JNICALL
Java_gnu_java_net_PlainSocketImpl_getOption(JNIEnv * env,jobject this,jint option_id)250 Java_gnu_java_net_PlainSocketImpl_getOption (JNIEnv * env, jobject this,
251 jint option_id)
252 {
253 #ifndef WITHOUT_NETWORK
254 assert (env != NULL);
255 assert ((*env) != NULL);
256
257 return (_javanet_get_option (env, this, option_id));
258 #else /* not WITHOUT_NETWORK */
259 return NULL;
260 #endif /* not WITHOUT_NETWORK */
261 }
262
263 /*************************************************************************/
264
265 /*
266 * Reads a buffer from a remote host
267 */
268 JNIEXPORT jint JNICALL
Java_gnu_java_net_PlainSocketImpl_read(JNIEnv * env,jobject this,jarray buf,jint offset,jint len)269 Java_gnu_java_net_PlainSocketImpl_read (JNIEnv * env, jobject this,
270 jarray buf, jint offset, jint len)
271 {
272 #ifndef WITHOUT_NETWORK
273 assert (env != NULL);
274 assert ((*env) != NULL);
275
276 return (_javanet_recvfrom (env, this, buf, offset, len, 0, 0));
277 #else /* not WITHOUT_NETWORK */
278 return 0;
279 #endif /* not WITHOUT_NETWORK */
280 }
281
282 /*************************************************************************/
283
284 /*
285 * Reads a char from a remote host
286 */
287 JNIEXPORT jint JNICALL
Java_gnu_java_net_PlainSocketImpl_nativeRead(JNIEnv * env,jclass class,jint fd)288 Java_gnu_java_net_PlainSocketImpl_nativeRead (JNIEnv *env, jclass class, jint fd)
289 {
290 #ifndef WITHOUT_NETWORK
291
292 jbyte b;
293 size_t recv_count;
294
295 /* receive one char */
296 recv_count = recv (fd, &b, 1, 0);
297
298 /* error, throw IOException */
299 if (recv_count == -1)
300 {
301 JCL_ThrowException(env, IO_EXCEPTION, strerror(errno));
302 return -1;
303 }
304
305 /* EOF: it's a blocking call, so it shouldn't return 0 unless EOF is
306 reached */
307 if (recv_count == 0)
308 {
309 return -1;
310 }
311
312 assert (recv_count == 1);
313
314 return ((jint) b) & 0x000000FF;
315
316 #else /* not WITHOUT_NETWORK */
317 #endif /* not WITHOUT_NETWORK */
318 }
319
320 /*************************************************************************/
321
322 /*
323 * Writes a buffer to the remote host
324 */
325 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_write(JNIEnv * env,jobject this,jarray buf,jint offset,jint len)326 Java_gnu_java_net_PlainSocketImpl_write (JNIEnv * env, jobject this,
327 jarray buf, jint offset, jint len)
328 {
329 #ifndef WITHOUT_NETWORK
330 assert (env != NULL);
331 assert ((*env) != NULL);
332
333 _javanet_sendto (env, this, buf, offset, len, 0, 0);
334 #else /* not WITHOUT_NETWORK */
335 #endif /* not WITHOUT_NETWORK */
336 }
337
338 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_shutdownInput(JNIEnv * env,jobject this)339 Java_gnu_java_net_PlainSocketImpl_shutdownInput (JNIEnv * env, jobject this)
340 {
341 #ifndef WITHOUT_NETWORK
342 assert (env != NULL);
343 assert ((*env) != NULL);
344
345 _javanet_shutdownInput (env, this);
346 #else /* not WITHOUT_NETWORK */
347 #endif /* not WITHOUT_NETWORK */
348 }
349
350 JNIEXPORT void JNICALL
Java_gnu_java_net_PlainSocketImpl_shutdownOutput(JNIEnv * env,jobject this)351 Java_gnu_java_net_PlainSocketImpl_shutdownOutput (JNIEnv * env, jobject this)
352 {
353 #ifndef WITHOUT_NETWORK
354 assert (env != NULL);
355 assert ((*env) != NULL);
356
357 _javanet_shutdownOutput (env, this);
358 #else /* not WITHOUT_NETWORK */
359 #endif /* not WITHOUT_NETWORK */
360 }
361
362 /* end of file */
363