Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pdsimpl.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pdsimpl.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pdsimpl.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pdsimpl.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,979 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include "jclglob.h"
+#include "nethelp.h"
+#include "helpers.h"
+#include "jclprots.h"
+
+#if defined(LINUX)
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for struct in_addr */
+#include <sys/ioctl.h>
+#include <net/if.h> /* for struct ifconf */
+#endif
+
+#include "portsock.h"
+
+void setDatagramPacketAddress (JNIEnv * env, jobject datagramPacket,
+ jobject anInetAddress);
+void setDatagramPacketPort (JNIEnv * env, jobject datagramPacket, U_16 hPort);
+void updateAddress (JNIEnv * env, hysockaddr_t sockaddrP,
+ jobject senderAddress);
+void updatePacket (JNIEnv * env, hysockaddr_t sockaddrP,
+ jobject datagramPacket, I_32 bytesRead);
+void setDatagramPacketLength (JNIEnv * env, jobject datagramPacket,
+ I_32 length);
+
+/**
+ * A helper method, to set the remote address into the DatagramPacket.
+ *
+ * @param env pointer to the JNI library
+ * @param datagramPacket pointer to the java DatagramPacket object to update
+ * @param anInetAddress pointer to the java InetAddress to update the packet with
+ *
+ */
+
+void
+setDatagramPacketAddress (JNIEnv * env, jobject datagramPacket,
+ jobject anInetAddress)
+{
+ jfieldID fid = JCL_CACHE_GET (env, FID_java_net_DatagramPacket_address);
+ (*env)->SetObjectField (env, datagramPacket, fid, anInetAddress);
+}
+
+/**
+ * A helper method, to set the remote port into the java DatagramPacket.
+ *
+ * @param env pointer to the JNI library
+ * @param datagramPacket pointer to the java DatagramPacket object to update
+ * @param hPort the port value to update the packet with, in host order
+ */
+
+void
+setDatagramPacketPort (JNIEnv * env, jobject datagramPacket, U_16 hPort)
+{
+ jfieldID fid = JCL_CACHE_GET (env, FID_java_net_DatagramPacket_port);
+ (*env)->SetIntField (env, datagramPacket, fid, hPort);
+}
+
+/**
+ * A helper method, to set the data length into a java DatagramPacket.
+ *
+ * @param env pointer to the JNI library
+ * @param datagramPacket pointer to the java DatagramPacket object to update
+ * @param length the length value to update the packet with
+ */
+
+void
+setDatagramPacketLength (JNIEnv * env, jobject datagramPacket, I_32 length)
+{
+ jfieldID fid = JCL_CACHE_GET (env, FID_java_net_DatagramPacket_length);
+ (*env)->SetIntField (env, datagramPacket, fid, length);
+}
+
+/**
+ * A helper method, to update the java DatagramPacket argument. Used after receiving a datagram packet,
+ * to update the DatagramPacket with the network address and port of the sending machine.
+ *
+ * @param env pointer to the JNI library
+ * @param sockaddrP pointer to the hysockaddr struct with the sending host address & port
+ * @param datagramPacket pointer to the java DatagramPacket object to update
+ * @param bytesRead the bytes read value to update the packet with
+ */
+
+void
+updatePacket (JNIEnv * env, hysockaddr_t sockaddrP, jobject datagramPacket,
+ I_32 bytesRead)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jobject anInetAddress;
+ U_16 nPort;
+ U_32 length;
+ U_32 scope_id = 0;
+ jbyte byte_array[HYSOCK_INADDR6_LEN];
+ hysock_sockaddr_address6 (sockaddrP, (U_8 *) byte_array, &length,
+ &scope_id);
+
+ nPort = hysock_sockaddr_port (sockaddrP);
+ anInetAddress =
+ newJavaNetInetAddressGenericB (env, byte_array, length, scope_id);
+
+ setDatagramPacketAddress (env, datagramPacket, anInetAddress);
+ setDatagramPacketPort (env, datagramPacket, hysock_ntohs (nPort));
+ setDatagramPacketLength (env, datagramPacket, bytesRead);
+}
+
+/**
+ * A helper method, to set address of the java InetAddress argument.
+ *
+ * @param env pointer to the JNI library
+ * @param sockaddrP pointer to the hysockaddr struct containing the network address
+ * @param senderAddress pointer to the java InetAddress object to update
+ */
+
+void
+updateAddress (JNIEnv * env, hysockaddr_t sockaddrP, jobject senderAddress)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte ipv4Addr[16];
+ U_32 length;
+ U_32 scope_id = 0;
+ hysock_sockaddr_address6 (sockaddrP, (U_8 *) ipv4Addr, &length, &scope_id);
+ (*env)->SetObjectField (env, senderAddress,
+ JCL_CACHE_GET (env,
+ FID_java_net_InetAddress_address),
+ newJavaByteArray (env, ipv4Addr, length));
+ if (jcl_supports_ipv6 (env) && (scope_id != 0))
+ {
+ jclass tempClass = JCL_CACHE_GET (env, CLS_java_net_InetAddress);
+ jfieldID fid = NULL;
+
+ fid = (*env)->GetFieldID (env, tempClass, "scope_id", "I");
+ if ((*env)->ExceptionCheck (env))
+ {
+ /* this will occur if we cannot find the scope_id field which means we have an older JCL
+ in this case we just don't set the soce id and we clear th exception */
+ (*env)->ExceptionClear (env);
+ }
+ else
+ {
+ (*env)->SetIntField (env, senderAddress, fid, scope_id);
+ }
+ }
+}
+
+/* HAS_JAVA_NET_CONNECT_EXCEPTION */
+#define HAS_JAVA_NET_CONNECT_EXCEPTION
+/**
+ * Create a new socket, for datagrams. The system socket is created and 'linked' to the
+ * the java PlainDatagramSocketImpl by setting the file descriptor value (which is an integer
+ * reference to socket maintained by the system).
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param thisObjFD pointer to the file descriptor of the java PlainDatagramSocketImpl
+ * @param preferIPv4Stack if application preference is to use only IPv4 sockets (default is false)
+ */
+
+void JNICALL
+Java_java_net_PlainDatagramSocketImpl_createDatagramSocketImpl (JNIEnv * env,
+ jclass
+ thisClz,
+ jobject
+ thisObjFD,
+ jboolean
+ preferIPv4Stack)
+{
+ createSocket (env, thisObjFD, HYSOCK_DGRAM, preferIPv4Stack);
+}
+
+/**
+ * Peek for data available for reading on the socket and answer the sending host address and port.
+ * This call is used to enforce secure reads. The peek function does not remove data from the system
+ * input queue, so that if the originating host address/port is acceptable to the security policy, a subsequent
+ * read operation may be issued to get the data. The peek is implemented as a recvfrom with the peek flag set,
+ * so the call otherwise behaves as a recvfrom call.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the file descriptor of the java PlainDatagramSocketImpl
+ * @param senderAddress pointer to the java InetAddress object to update with the sender address
+ * @param timeout the read timeout, in milliSeconds
+ *
+ * @return the port on the host sending the data
+ * @exception SocketException if an error occurs during the call
+ */
+
+jint JNICALL
+Java_java_net_PlainDatagramSocketImpl_peekDatagramImpl (JNIEnv * env,
+ jclass thisClz,
+ jobject
+ fileDescriptor,
+ jobject senderAddress,
+ jint timeout)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ hysocket_t hysocketP;
+ hysockaddr_struct sockaddrP;
+ char msg[1] = { 0 };
+ I_32 msgLen = 1;
+ I_32 result;
+ I_32 flags = 0;
+ jint hport;
+ jbyte nlocalAddrBytes[HYSOCK_INADDR6_LEN];
+
+ result = pollSelectRead (env, fileDescriptor, timeout, TRUE);
+ if (0 > result)
+ return (jint) 0;
+
+ hysocketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (hysocketP))
+ {
+ throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_BADSOCKET);
+ return (jint) 0;
+ }
+
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nlocalAddrBytes,
+ HYSOCK_INADDR_LEN, HYADDR_FAMILY_AFINET4, 0, 0, 0,
+ hysocketP);
+
+ result = hysock_setflag (HYSOCK_MSG_PEEK, &flags);
+ if (0 > result)
+ {
+ throwJavaNetSocketException (env, result);
+ return (jint) 0;
+ }
+ result =
+ hysock_readfrom (hysocketP, (U_8 *) msg, msgLen, flags, &sockaddrP);
+
+/**
+ * Note, the msgsize error is acceptable as the read buffer was set to a nominal length.
+ * Updating sockaddrP is the purpose of this call.
+ */
+ if (result < 0 && result != HYPORT_ERROR_SOCKET_MSGSIZE)
+ {
+ throwJavaNetSocketException (env, result);
+ return (jint) 0;
+ }
+ else
+ {
+ updateAddress (env, &sockaddrP, senderAddress);
+ hport = (jint) hysock_ntohs (hysock_sockaddr_port (&sockaddrP));
+ return hport;
+ }
+}
+
+void JNICALL
+Java_java_net_PlainDatagramSocketImpl_oneTimeInitialization (JNIEnv * env,
+ jclass clazz,
+ jboolean
+ ipv6support)
+{
+ jclass lookupClass;
+ jfieldID fid;
+
+ netInitializeIDCaches (env, ipv6support);
+
+ lookupClass = (*env)->FindClass (env, "java/net/DatagramPacket");
+ if (!lookupClass)
+ return;
+
+ fid =
+ (*env)->GetFieldID (env, lookupClass, "address",
+ "Ljava/net/InetAddress;");
+ if (!fid)
+ return;
+ JCL_CACHE_SET (env, FID_java_net_DatagramPacket_address, fid);
+
+ fid = (*env)->GetFieldID (env, lookupClass, "length", "I");
+ if (!fid)
+ return;
+ JCL_CACHE_SET (env, FID_java_net_DatagramPacket_length, fid);
+
+ fid = (*env)->GetFieldID (env, lookupClass, "port", "I");
+ if (!fid)
+ return;
+ JCL_CACHE_SET (env, FID_java_net_DatagramPacket_port, fid);
+}
+
+/**
+ * Receive data on this socket and update the DatagramPacket with the data and sender address/port.
+ * If the timeout value is 0, the call may block indefinitely waiting for data otherwise
+ * if no data is received within the timeout, it will return throw an exception. Note, the
+ * data & msgLength arguments are fields within the DatagramPacket, passed explicitly to
+ * save doing accesses within the native code.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the file descriptor of the java PlainDatagramSocketImpl
+ * @param datagramPacket pointer to the java DatagramPacket object to update with data & address/port information
+ * @param data pointer to the java read buffer
+ * @param offset offset into the buffer to start reading data from
+ * @param msgLength the length of the read buffer
+ * @param timeout the read timeout, in milliSeconds
+ * @param peek choice whether to peek or receive the datagram
+ *
+ * @return the number of bytes read
+ * @exception InterruptedIOException, SocketException if an error occurs during the call
+ */
+
+jint JNICALL
+Java_java_net_PlainDatagramSocketImpl_receiveDatagramImpl2 (JNIEnv * env,
+ jclass thisClz,
+ jobject
+ fileDescriptor,
+ jobject
+ datagramPacket,
+ jbyteArray data,
+ jint offset,
+ jint msgLength,
+ jint timeout,
+ jboolean peek)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ hysocket_t hysocketP;
+ hysockaddr_struct sockaddrP;
+ jbyte *message;
+ I_32 result, localCount;
+ I_32 flags = HYSOCK_NOFLAGS;
+ jbyte nlocalAddrBytes[HYSOCK_INADDR6_LEN];
+
+ result = pollSelectRead (env, fileDescriptor, timeout, TRUE);
+ if (0 > result)
+ return (jint) 0;
+
+ hysocketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (hysocketP))
+ {
+ throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_BADSOCKET);
+ return (jint) 0;
+ }
+
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nlocalAddrBytes,
+ HYSOCK_INADDR_LEN, HYADDR_FAMILY_AFINET4, 0, 0, 0,
+ hysocketP);
+
+ localCount = (msgLength < 65536) ? msgLength : 65536;
+ message = jclmem_allocate_memory (env, localCount);
+ if (message == NULL)
+ {
+ throwNewOutOfMemoryError (env, "");
+ return 0;
+ }
+ if (peek)
+ {
+ result = hysock_setflag (HYSOCK_MSG_PEEK, &flags);
+ if (result)
+ {
+ jclmem_free_memory (env, message);
+ throwJavaNetSocketException (env, result);
+ return (jint) 0;
+ }
+ }
+ result =
+ hysock_readfrom (hysocketP, message, localCount, flags, &sockaddrP);
+ if (result > 0)
+ (*env)->SetByteArrayRegion (env, data, offset, result, message);
+ jclmem_free_memory (env, message);
+ if (result < 0)
+ {
+ throwJavaNetSocketException (env, result);
+ return (jint) 0;
+ }
+ else
+ {
+ updatePacket (env, &sockaddrP, datagramPacket, result);
+ return (jint) result;
+ }
+}
+
+/**
+ * Disconnect the Datagram socket. This allows the socket to be used to sendto and or receive from any addres
+* once again
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the socket file descriptor
+ *
+ * @exception SocketException if an error occurs disconneting from the remote host
+ */
+void JNICALL
+Java_java_net_PlainDatagramSocketImpl_disconnectDatagramImpl (JNIEnv * env,
+ jclass thisClz,
+ jobject
+ fileDescriptor)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte nAddrBytes[HYSOCK_INADDR6_LEN];
+ int length;
+ U_16 nPort = 0;
+ I_32 result;
+ hysocket_t socketP;
+ hysockaddr_struct sockaddrP;
+
+ socketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_BADSOCKET);
+ return;
+ }
+
+ /* the address itself should not matter as the protocol family is AF_UNSPEC. This tells connect to
+ disconnect the Datagram */
+ memset (nAddrBytes, 0, HYSOCK_INADDR6_LEN);
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nAddrBytes, HYSOCK_INADDR_LEN,
+ HYADDR_FAMILY_UNSPEC, nPort, 0, 0, socketP);
+
+ /* there is the possiblity of an exception here */
+ result = hysock_connect (socketP, &sockaddrP);
+
+ /* will likely need to eat the correct exception here. Leave as is until we figure out what that exception will be */
+ if (0 != result)
+ {
+ throwJavaNetSocketException (env, result);
+ return;
+ }
+}
+
+/**
+ * Receive data on this socket and update the DatagramPacket with the data and sender address/port.
+ * If the timeout value is 0, the call may block indefinitely waiting for data otherwise
+ * if no data is received within the timeout, it will return throw an exception. Note, the
+ * data & msgLength arguments are fields within the DatagramPacket, passed explicitly to
+ * save doing accesses within the native code.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the file descriptor of the java PlainDatagramSocketImpl
+ * @param datagramPacket pointer to the java DatagramPacket object to update with data & address/port information
+ * @param data pointer to the java read buffer
+ * @param offset offset into the buffer to start reading data from
+ * @param msgLength the length of the read buffer
+ * @param timeout the read timeout, in milliSeconds
+ * @param peek consume the data packet or not
+ *
+ * @return the number of bytes read
+ * @exception InterruptedIOException, SocketException if an error occurs during the call
+ */
+
+jint JNICALL
+Java_java_net_PlainDatagramSocketImpl_recvConnectedDatagramImpl (JNIEnv * env,
+ jclass
+ thisClz,
+ jobject
+ fileDescriptor,
+ jobject
+ datagramPacket,
+ jbyteArray
+ data,
+ jint offset,
+ jint
+ msgLength,
+ jint timeout,
+ jboolean
+ peek)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ hysocket_t hysocketP;
+ jbyte *message;
+ I_32 result;
+ I_32 localCount;
+ I_32 flags = HYSOCK_NOFLAGS;
+
+ /* check if there is any data to be read before we go ahead and do the read */
+ result = pollSelectRead (env, fileDescriptor, timeout, TRUE);
+ if (0 > result)
+ {
+ return (jint) 0;
+ }
+
+ /* get the handle to the socket */
+ hysocketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (hysocketP))
+ {
+ throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_BADSOCKET);
+ return (jint) 0;
+ }
+
+ /* allocate the buffer into which data will be read */
+ localCount = (msgLength < 65536) ? msgLength : 65536;
+ message = jclmem_allocate_memory (env, localCount);
+ if (message == NULL)
+ {
+ throwNewOutOfMemoryError (env, "");
+ return 0;
+ }
+
+ /* check for peek option, if so set the appropriate flag */
+ if (peek)
+ {
+ result = hysock_setflag (HYSOCK_MSG_PEEK, &flags);
+ if (result)
+ {
+ jclmem_free_memory (env, message);
+ throwJavaNetSocketException (env, result);
+ return (jint) 0;
+ }
+ }
+
+ /* read the data and copy it to the return array, then free the buffer as we
+ no longer need it */
+ result = hysock_read (hysocketP, message, localCount, flags);
+ if (result > 0)
+ {
+ (*env)->SetByteArrayRegion (env, data, offset, result, message);
+ }
+ jclmem_free_memory (env, message);
+ if (result < 0)
+ {
+ if ((HYPORT_ERROR_SOCKET_CONNRESET == result)
+ || (HYPORT_ERROR_SOCKET_CONNECTION_REFUSED == result))
+ {
+ throwJavaNetPortUnreachableException (env, result);
+ return (jint) 0;
+ }
+ else
+ {
+ throwJavaNetSocketException (env, result);
+ return (jint) 0;
+ }
+ }
+ else
+ {
+ /* update the packet with the legth of data received.
+ Since we are connected we did not get back an address. This
+ address is cached within the PlainDatagramSocket java object and is filled in at
+ the java level */
+ setDatagramPacketLength (env, datagramPacket, result);
+ return (jint) result;
+ }
+}
+
+/**
+ * Send data on this socket to the nominated host address/port.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the file descriptor of the java PlainDatagramSocketImpl
+ * @param data pointer to the java read buffer
+ * @param offset offset into the buffer
+ * @param msgLength the length of the read buffer
+ * @param bindToDevice
+ *
+ * @return the number of bytes sent
+ * @exception SocketException if an error occurs during the call
+ */
+
+jint JNICALL
+Java_java_net_PlainDatagramSocketImpl_sendConnectedDatagramImpl (JNIEnv * env,
+ jclass
+ thisClz,
+ jobject
+ fileDescriptor,
+ jbyteArray
+ data,
+ jint offset,
+ jint
+ msgLength,
+ jboolean
+ bindToDevice)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte *message;
+ I_32 result = 0;
+ I_32 sent = 0;
+ hysocket_t socketP;
+ int flags = HYSOCK_NOFLAGS;
+
+ /* allocate a local buffer into which we will copy the data to be sent and which we will use
+ for the write call */
+ message = jclmem_allocate_memory (env, msgLength);
+ if (message == NULL)
+ {
+ throwNewOutOfMemoryError (env, "");
+ return 0;
+ }
+ (*env)->GetByteArrayRegion (env, data, offset, msgLength, message);
+
+ do
+ {
+ /* make sure the socket is still valid */
+ socketP =
+ (hysocket_t) getJavaIoFileDescriptorContentsAsPointer (env,
+ fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ throwJavaNetSocketException (env,
+ sent ==
+ 0 ? HYPORT_ERROR_SOCKET_BADSOCKET :
+ HYPORT_ERROR_SOCKET_INTERRUPTED);
+ return (jint) 0;
+ }
+
+ /* try to send the next block of data */
+ result =
+ hysock_write (socketP, message + sent, (I_32) msgLength - sent,
+ flags);
+ if (result < 0)
+ {
+ break;
+ }
+ sent += result;
+ }
+ while (sent < msgLength);
+
+ /* ok free the buffer and return the length sent or an exception as appropriate */
+ jclmem_free_memory (env, message);
+
+ if (result < 0)
+ {
+ if ((HYPORT_ERROR_SOCKET_CONNRESET == result)
+ || (HYPORT_ERROR_SOCKET_CONNECTION_REFUSED == result))
+ {
+ throwJavaNetPortUnreachableException (env, result);
+ return (jint) 0;
+ }
+ else
+ {
+ throwJavaNetSocketException (env, result);
+ return (jint) 0;
+ }
+ }
+ else
+ {
+ return (jint) result;
+ }
+}
+
+/**
+ * Connect the Datagram socket to the nominated remote host address/port. The socket may then be used to send
+ * and receive data from the remote host.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the socket file descriptor
+ * @param remotePort the port on the remote host to connect to
+ * @param trafficClass trafficClass to be used when the datagram socket is connected
+ * @param inetAddress the inetAddress object representing the address to be connected on.
+ *
+ * @exception SocketException if an error occurs connected to the remote host
+ */
+void JNICALL
+Java_java_net_PlainDatagramSocketImpl_connectDatagramImpl2 (JNIEnv * env,
+ jclass thisClz,
+ jobject
+ fileDescriptor,
+ jint remotePort,
+ jint trafficClass,
+ jobject
+ inetAddress)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte nAddrBytes[HYSOCK_INADDR6_LEN];
+ int length;
+ U_16 nPort;
+ I_32 result;
+ hysocket_t socketP;
+ hysockaddr_struct sockaddrP;
+ U_32 scope_id = 0;
+
+ socketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_BADSOCKET);
+ return;
+ }
+
+ netGetJavaNetInetAddressValue (env, inetAddress, nAddrBytes, &length);
+
+ nPort = hysock_htons ((U_16) remotePort);
+ if (length == HYSOCK_INADDR_LEN)
+ {
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nAddrBytes, length,
+ HYADDR_FAMILY_AFINET4, nPort, 0, 0, socketP);
+ }
+ else
+ {
+ netGetJavaNetInetAddressScopeId (env, inetAddress, &scope_id);
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nAddrBytes, length,
+ HYADDR_FAMILY_AFINET6, nPort,
+ (trafficClass & 0xFF) << 20, scope_id, socketP);
+ }
+
+ result = hysock_connect (socketP, &sockaddrP);
+ if (0 != result)
+ {
+ throwJavaNetConnectException (env, result);
+
+ return;
+ }
+}
+
+/**
+ * Send data on this socket to the nominated host address/port.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the file descriptor of the java PlainDatagramSocketImpl
+ * @param data pointer to the java read buffer
+ * @param msgLength the length of the read buffer
+ * @param targetPort target port, in host order
+ * @param trafficClass the traffic class value that should be use when sending the datagram
+ * @param inetAddress object with the address to which the datagram should be sent
+ *
+ * @return the number of bytes sent
+ * @exception SocketException if an error occurs during the call
+ */
+
+jint JNICALL
+Java_java_net_PlainDatagramSocketImpl_sendDatagramImpl2 (JNIEnv * env,
+ jclass thisClz,
+ jobject
+ fileDescriptor,
+ jbyteArray data,
+ jint offset,
+ jint msgLength,
+ jint targetPort,
+ jboolean
+ bindToDevice,
+ jint trafficClass,
+ jobject inetAddress)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte *message;
+ jbyte nhostAddrBytes[HYSOCK_INADDR6_LEN];
+ int length;
+
+ U_32 nhostAddr;
+ U_16 nPort;
+ I_32 result = 0, sent = 0;
+ hysocket_t socketP;
+ hysockaddr_struct sockaddrP;
+ int flags;
+ U_32 scope_id = 0;
+
+ netGetJavaNetInetAddressValue (env, inetAddress, nhostAddrBytes, &length);
+ nPort = hysock_htons ((U_16) targetPort);
+
+ socketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (length == HYSOCK_INADDR6_LEN)
+ {
+ netGetJavaNetInetAddressScopeId (env, inetAddress, &scope_id);
+ hysock_sockaddr_init6 (&sockaddrP, nhostAddrBytes, length,
+ HYADDR_FAMILY_AFINET6, nPort,
+ (trafficClass & 0xFF) << 20, scope_id, socketP);
+ }
+ else
+ {
+ hysock_sockaddr_init6 (&sockaddrP, nhostAddrBytes, length,
+ HYADDR_FAMILY_AFINET4, nPort, 0, scope_id,
+ socketP);
+ }
+
+ flags = HYSOCK_NOFLAGS;
+
+ message = jclmem_allocate_memory (env, msgLength);
+ if (message == NULL)
+ {
+ throwNewOutOfMemoryError (env, "");
+ return 0;
+ }
+ (*env)->GetByteArrayRegion (env, data, offset, msgLength, message);
+
+ /* Zero length datagram packets are not sent */
+ do
+ {
+ socketP =
+ getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ /* Allocated memory blocks are not freed before throwing JavaNetSocketException */
+ jclmem_free_memory (env, message);
+ throwJavaNetSocketException (env,
+ sent ==
+ 0 ? HYPORT_ERROR_SOCKET_BADSOCKET :
+ HYPORT_ERROR_SOCKET_INTERRUPTED);
+ return (jint) 0;
+ }
+ result =
+ hysock_writeto (socketP, message + sent, (I_32) msgLength - sent,
+ flags, &sockaddrP);
+ if (result < 0)
+ break;
+ sent += result;
+ }
+ while (sent < msgLength);
+
+ jclmem_free_memory (env, message);
+ if (result < 0)
+ {
+ throwJavaNetSocketException (env, result);
+ return (jint) 0;
+ }
+ else
+ {
+ return (jint) result;
+ }
+}
+
+/**
+ * Bind the socket to the specified local address/port. This call is made after socket creation
+ * and prior to read/write operations.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the file descriptor of the socket to bind
+ * @param localPort the port, in host order, to bind the socket on
+ * @param inetAddress the inetAddres object containing the address to bind on.
+ *
+ * @exception SocketException if an error occurs during the call
+ */
+
+jboolean JNICALL
+Java_java_net_PlainDatagramSocketImpl_socketBindImpl2 (JNIEnv * env,
+ jclass thisClz,
+ jobject fileDescriptor,
+ jint localPort,
+ jboolean doDevice,
+ jobject inetAddress)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte nlocalAddrBytes[HYSOCK_INADDR6_LEN];
+ int length;
+ U_16 nPort;
+ I_32 result;
+ hysocket_t socketP;
+ hysockaddr_struct sockaddrP;
+ jboolean bindToDevice = FALSE;
+ jboolean equals_address = TRUE;
+ int i;
+ U_32 scope_id = 0;
+
+ /* This method still needs work for IPv6 support */
+
+ socketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_BADSOCKET);
+ return 0;
+ }
+ else
+ {
+
+ netGetJavaNetInetAddressValue (env, inetAddress, nlocalAddrBytes,
+ &length);
+
+ nPort = hysock_htons ((U_16) localPort);
+#if defined(LINUX)
+ for (i = 0; i < length; i++)
+ {
+ if (nlocalAddrBytes[i] != 0)
+ {
+ equals_address = FALSE;
+ break;
+ }
+ }
+ if (doDevice && !equals_address)
+ {
+ struct ifreq *ifr;
+ struct ifconf ifc;
+ char *ptr;
+ int len = 128 * sizeof (struct ifreq);
+ for (;;)
+ {
+ char *data = jclmem_allocate_memory (env, len);
+ if (data == 0)
+ {
+ throwNewOutOfMemoryError (env,
+ "Cannot allocate SIOCGIFCONF buffer");
+ return 0;
+ }
+ ifc.ifc_len = len;
+ ifc.ifc_buf = data;
+ if (ioctl ((int) socketP, SIOCGIFCONF, &ifc) != 0)
+ {
+ jclmem_free_memory (env, ifc.ifc_buf);
+ throwJavaNetSocketException (env, errno);
+ return 0;
+ }
+ if (ifc.ifc_len < len)
+ break;
+ jclmem_free_memory (env, data);
+ len += 128 * sizeof (struct ifreq);
+ }
+ ptr = ifc.ifc_buf;
+ while (ptr < (char *) ifc.ifc_buf + ifc.ifc_len)
+ {
+ struct sockaddr_in *inaddr;
+ ifr = (struct ifreq *) ptr;
+ ptr += sizeof (ifr->ifr_name) + sizeof (struct sockaddr);
+/*printf(" addr family: %d (%d)\n", ifr->ifr_addr.sa_family, AF_INET);*/
+ inaddr = (struct sockaddr_in *) &ifr->ifr_addr;
+ if (length > HYSOCK_INADDR_LEN)
+ {
+ equals_address = FALSE;
+ }
+ else
+ {
+ equals_address =
+ inaddr->sin_addr.s_addr == *((int *) nlocalAddrBytes);
+ }
+ if (ifr->ifr_addr.sa_family == AF_INET && equals_address)
+ {
+ char *cptr;
+/*printf("interface: %s\n", ifr->ifr_name);
+printf(" addr: %x\n", inaddr->sin_addr.s_addr);*/
+ if ((cptr = strchr (ifr->ifr_name, ':')) != NULL)
+ *cptr = 0;
+ if (ioctl (SOCKET_CAST (socketP), SIOCGIFFLAGS, ifr) != 0)
+ {
+ jclmem_free_memory (env, ifc.ifc_buf);
+ throwJavaNetSocketException (env, errno);
+ return 0;
+ }
+/*printf("flags: %x UP = %x BROADCAST = %x MULTICAST = %x LOOPBACK = %x POINTOPOINT = %x)\n",
+ ifr->ifr_flags, ifr->ifr_flags & IFF_UP, ifr->ifr_flags & IFF_BROADCAST,
+ ifr->ifr_flags & IFF_MULTICAST, ifr->ifr_flags & IFF_LOOPBACK, ifr->ifr_flags & IFF_POINTOPOINT);*/
+ if (ifr->ifr_flags & IFF_UP
+ && !(ifr->ifr_flags & IFF_POINTOPOINT))
+ {
+ result =
+ setsockopt (SOCKET_CAST (socketP), SOL_SOCKET,
+ SO_BINDTODEVICE, ifr,
+ sizeof (struct ifreq));
+ if (result == 0)
+ {
+ int value = TRUE;
+ memset (nlocalAddrBytes, 0, HYSOCK_INADDR6_LEN);
+ length = 0;
+ bindToDevice = TRUE;
+
+ hysock_setopt_bool (socketP, HY_SOL_SOCKET,
+ HY_SO_REUSEADDR, &value);
+ }
+ }
+ }
+ }
+ jclmem_free_memory (env, ifc.ifc_buf);
+ }
+#endif
+
+ if (length == HYSOCK_INADDR6_LEN)
+ {
+ netGetJavaNetInetAddressScopeId (env, inetAddress, &scope_id);
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nlocalAddrBytes, length,
+ HYADDR_FAMILY_AFINET6, nPort, 0, scope_id,
+ socketP);
+ }
+ else
+ {
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nlocalAddrBytes, length,
+ HYADDR_FAMILY_AFINET4, nPort, 0, scope_id,
+ socketP);
+ }
+
+ result = hysock_bind (socketP, &sockaddrP);
+ if (0 != result)
+ {
+ throwJavaNetBindException (env, result);
+ return 0;
+ }
+ }
+ return bindToDevice;
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pmsimpl.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pmsimpl.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pmsimpl.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pmsimpl.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,65 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include "jclglob.h"
+#include "nethelp.h"
+#include "helpers.h"
+#include "jclprots.h"
+
+#if defined(LINUX)
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for struct in_addr */
+#include <sys/ioctl.h>
+#include <net/if.h> /* for struct ifconf */
+#endif
+
+#include "portsock.h"
+
+/**
+ * Create a new socket, for multicast datagrams. The system socket is created and 'linked' to the
+ * the java PlainMulticastSocketImpl by setting the file descriptor value (which is an integer
+ * reference to socket maintained by the system). For Multicast sockets, the REUSEADDR is on by
+ * default for all platforms tested so far including windows. In addition on platforms which support REUSEPORT
+ * this should also be on by default as well.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param thisObjFD pointer to the file descriptor of the java PlainDatagramSocketImpl
+ * @param preferIPv4Stack if application preference is to use only IPv4 sockets (default is false)
+ */
+
+void JNICALL
+Java_java_net_PlainMulticastSocketImpl_createMulticastSocketImpl (JNIEnv *
+ env,
+ jclass
+ thisClz,
+ jobject
+ thisObjFD,
+ jboolean
+ preferIPv4Stack)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ BOOLEAN value = TRUE;
+ hysocket_t socketP;
+ createSocket (env, thisObjFD, HYSOCK_DGRAM, preferIPv4Stack);
+ socketP =
+ (hysocket_t) getJavaIoFileDescriptorContentsAsPointer (env, thisObjFD);
+
+ hysock_setopt_bool (socketP, HY_SOL_SOCKET, HY_SO_REUSEPORT, &value);
+ hysock_setopt_bool (socketP, HY_SOL_SOCKET, HY_SO_REUSEADDR, &value);
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pmsimpl.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pmsimpl.h?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pmsimpl.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/pmsimpl.h Wed Nov 30 21:29:27 2005
@@ -0,0 +1,27 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(pmsimpl_h)
+#define pmsimpl_h
+void JNICALL
+Java_java_net_PlainMulticastSocketImpl_createMulticastSocketImpl (JNIEnv *
+ env,
+ jclass
+ thisClz,
+ jobject
+ thisObjFD,
+ jboolean
+ preferIPv4Stack);
+#endif /* pmsimpl_h */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/process.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/process.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/process.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/process.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,316 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "iohelp.h"
+#include "procimpl.h"
+
+#include "jclglob.h"
+
+/**
+ * Create a System Process with the specified
+ * environment and arguments
+ */
+jlongArray JNICALL
+Java_com_ibm_oti_lang_SystemProcess_createImpl (JNIEnv * env, jclass clazz,
+ jobject recv,
+ jobjectArray arg1,
+ jobjectArray arg2,
+ jbyteArray dir)
+{
+ jbyteArray envString;
+ jlongArray pVals = NULL;
+ jlong npVals[4];
+ char *envArray[256];
+ char *command[256];
+ int i, retVal;
+ IDATA pHandle, inHandle, outHandle, errHandle;
+ int envLength, commandLineLength, len;
+ char *workingDir = NULL;
+ PORT_ACCESS_FROM_ENV (env);
+
+ /* validate sizes */
+ commandLineLength = (*env)->GetArrayLength (env, arg1);
+ envLength = (*env)->GetArrayLength (env, arg2);
+ if (commandLineLength >= 255)
+ {
+ jclass exClass = (*env)->FindClass (env, "java/io/IOException");
+ (*env)->ThrowNew (env, exClass, "Too many arguments");
+ return NULL;
+ }
+ if (envLength >= 255)
+ {
+ jclass exClass = (*env)->FindClass (env, "java/io/IOException");
+ (*env)->ThrowNew (env, exClass, "Too many environment arguments");
+ return NULL;
+ }
+
+ memset (command, 0, sizeof (command));
+ memset (envArray, 0, sizeof (envArray));
+
+ /* Get the command string and arguments */
+ /* convert java.lang.String into C char* */
+ for (i = commandLineLength; --i >= 0;)
+ {
+ jbyteArray element = (*env)->GetObjectArrayElement (env, arg1, i);
+ len = (*env)->GetArrayLength (env, element);
+ command[i] = jclmem_allocate_memory (env, len + 1);
+ if (command[i] == NULL)
+ {
+ throwNewOutOfMemoryError (env, "");
+ goto failed;
+ }
+ (*env)->GetByteArrayRegion (env, element, 0, len, command[i]);
+ command[i][len] = 0;
+ }
+ if (envLength)
+ for (i = 0; i < envLength; i++)
+ {
+ envString = (*env)->GetObjectArrayElement (env, arg2, i);
+ len = (*env)->GetArrayLength (env, envString);
+ envArray[i] = jclmem_allocate_memory (env, len + 1);
+ if (envArray[i] == NULL)
+ {
+ throwNewOutOfMemoryError (env, "");
+ goto failed;
+ }
+ (*env)->GetByteArrayRegion (env, envString, 0, len, envArray[i]);
+ envArray[i][len] = 0;
+ }
+ /* NULL terminate for UNIX (does work on windows too; in fact, it doesn't care) */
+ command[commandLineLength] = NULL;
+ envArray[envLength] = NULL;
+
+ if (dir != NULL)
+ {
+ jsize dirLength = (*env)->GetArrayLength (env, dir);
+
+ workingDir = jclmem_allocate_memory (env, dirLength + 1);
+ if (workingDir)
+ {
+ (*env)->GetByteArrayRegion (env, dir, 0, dirLength,
+ (jbyte *) workingDir);
+ workingDir[dirLength] = '\0';
+ }
+ }
+
+ retVal = execProgram (env, recv,
+ command, commandLineLength, envArray, envLength,
+ workingDir, &pHandle, &inHandle, &outHandle,
+ &errHandle);
+
+ if (workingDir)
+ {
+ jclmem_free_memory (env, workingDir);
+ }
+
+ if (!retVal)
+ { /* Failed to exec program */
+ jclass exClass = (*env)->FindClass (env, "java/io/IOException");
+ (*env)->ThrowNew (env, exClass, "Unable to start program");
+ goto failed;
+ }
+ pVals = (*env)->NewLongArray (env, 4);
+ if (pVals)
+ {
+ npVals[0] = (jlong) pHandle;
+ npVals[1] = (jlong) inHandle;
+ npVals[2] = (jlong) outHandle;
+ npVals[3] = (jlong) errHandle;
+ (*env)->SetLongArrayRegion (env, pVals, 0, 4, (jlong *) (&npVals));
+ }
+
+failed:
+
+ for (i = 0; i < envLength; i++)
+ {
+ if (envArray[i])
+ jclmem_free_memory (env, envArray[i]);
+ }
+ for (i = commandLineLength; --i >= 0;)
+ {
+ if (command[i])
+ jclmem_free_memory (env, command[i]);
+ }
+
+ return pVals;
+}
+
+/* Kill the receiver */
+void JNICALL
+Java_com_ibm_oti_lang_SystemProcess_destroyImpl (JNIEnv * env, jobject recv)
+{
+ jlong pHandle;
+ pHandle =
+ (*env)->GetLongField (env, recv,
+ JCL_CACHE_GET (env,
+ FID_com_ibm_oti_lang_SystemProcess_handle));
+ termProc ((IDATA) pHandle);
+}
+
+/* Close the input stream*/
+void JNICALL
+Java_com_ibm_oti_lang_ProcessInputStream_closeImpl (JNIEnv * env,
+ jobject recv)
+{
+ PORT_ACCESS_FROM_ENV (env);
+
+ new_ioh_close (env, recv,
+ JCL_CACHE_GET (env,
+ FID_com_ibm_oti_lang_ProcessInputStream_fd));
+}
+
+void JNICALL
+Java_com_ibm_oti_lang_ProcessOutputStream_closeImpl (JNIEnv * env,
+ jobject recv)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ new_ioh_close (env, recv,
+ JCL_CACHE_GET (env,
+ FID_com_ibm_oti_lang_ProcessOutputStream_fd));
+}
+
+/* Read nbytes from the receiver */
+jint JNICALL
+Java_com_ibm_oti_lang_ProcessInputStream_readImpl (JNIEnv * env, jobject recv,
+ jbyteArray buffer,
+ jint offset, jint nbytes,
+ jlong handle)
+{
+
+ return (jint) ioh_readbytesImpl (env, recv, buffer, offset, nbytes,
+ (IDATA) handle);
+
+}
+
+/*Return the number of bytes available to be read without blocking */
+jint JNICALL
+Java_com_ibm_oti_lang_ProcessInputStream_availableImpl (JNIEnv * env,
+ jobject recv)
+{
+ jint sHandle;
+ int retVal;
+
+ sHandle =
+ (*env)->GetLongField (env, recv,
+ JCL_CACHE_GET (env,
+ FID_com_ibm_oti_lang_ProcessInputStream_handle));
+ retVal = getAvailable (sHandle);
+ if (retVal < 0)
+ {
+ /* Couldn't read bytes */
+ jclass exClass = (*env)->FindClass (env, "java/io/IOException");
+ (*env)->ThrowNew (env, exClass, "Unable to peek on stream");
+ }
+ return (jint) retVal;
+}
+
+/* Write nbytes to the receiver */
+void JNICALL
+Java_com_ibm_oti_lang_ProcessOutputStream_writeImpl (JNIEnv * env,
+ jobject recv,
+ jbyteArray buffer,
+ jint offset, jint nbytes,
+ jlong handle)
+{
+
+ ioh_writebytesImpl (env, recv, buffer, offset, nbytes, (IDATA) handle);
+
+}
+
+/* Set the descriptor field od the receiver */
+void JNICALL
+Java_com_ibm_oti_lang_ProcessInputStream_setFDImpl (JNIEnv * env,
+ jobject recv,
+ jobject arg1, jlong arg2)
+{
+ setJavaIoFileDescriptorContentsAsPointer (env, arg1, (void *) ((IDATA) arg2));
+}
+
+void JNICALL
+Java_com_ibm_oti_lang_ProcessOutputStream_setFDImpl (JNIEnv * env,
+ jobject recv,
+ jobject arg1, jlong arg2)
+{
+ setJavaIoFileDescriptorContentsAsPointer (env, arg1, (void *) ((IDATA) arg2));
+}
+
+/* Wait for the receiver to finish then return the exit value */
+jint JNICALL
+Java_com_ibm_oti_lang_SystemProcess_waitForCompletionImpl (JNIEnv * env,
+ jobject recv)
+{
+ jlong pHandle;
+ pHandle =
+ (*env)->GetLongField (env, recv,
+ JCL_CACHE_GET (env,
+ FID_com_ibm_oti_lang_SystemProcess_handle));
+ return (jint) waitForProc ((IDATA) pHandle);
+}
+
+void JNICALL
+Java_com_ibm_oti_lang_SystemProcess_oneTimeInitialization (JNIEnv * env,
+ jclass clazz)
+{
+ jfieldID fid = (*env)->GetFieldID (env, clazz, "handle", "J");
+ if (!fid)
+ return;
+ JCL_CACHE_SET (env, FID_com_ibm_oti_lang_SystemProcess_handle, fid);
+}
+
+void JNICALL
+Java_com_ibm_oti_lang_ProcessOutputStream_oneTimeInitialization (JNIEnv * env,
+ jclass clazz)
+{
+ jfieldID fid;
+
+ fid = (*env)->GetFieldID (env, clazz, "handle", "J");
+ if (!fid)
+ return;
+ JCL_CACHE_SET (env, FID_com_ibm_oti_lang_ProcessOutputStream_handle, fid);
+
+ fid = (*env)->GetFieldID (env, clazz, "fd", "Ljava/io/FileDescriptor;");
+ if (!fid)
+ return;
+ JCL_CACHE_SET (env, FID_com_ibm_oti_lang_ProcessOutputStream_fd, fid);
+}
+
+void JNICALL
+Java_com_ibm_oti_lang_ProcessInputStream_oneTimeInitialization (JNIEnv * env,
+ jclass clazz)
+{
+ jfieldID fid;
+
+ fid = (*env)->GetFieldID (env, clazz, "handle", "J");
+ if (!fid)
+ return;
+ JCL_CACHE_SET (env, FID_com_ibm_oti_lang_ProcessInputStream_handle, fid);
+
+ fid = (*env)->GetFieldID (env, clazz, "fd", "Ljava/io/FileDescriptor;");
+ if (!fid)
+ return;
+ JCL_CACHE_SET (env, FID_com_ibm_oti_lang_ProcessInputStream_fd, fid);
+}
+
+/* Close the handle */
+void JNICALL
+Java_com_ibm_oti_lang_SystemProcess_closeImpl (JNIEnv * env, jobject recv)
+{
+ jlong pHandle;
+ pHandle =
+ (*env)->GetLongField (env, recv,
+ JCL_CACHE_GET (env,
+ FID_com_ibm_oti_lang_SystemProcess_handle));
+ closeProc ((IDATA) pHandle);
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/procimpl.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/procimpl.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/procimpl.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/procimpl.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,250 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include <errno.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include "procimpl.h"
+
+void
+sleepFor (unsigned int nanoseconds)
+{
+ struct timespec delay, remDelay;
+ delay.tv_sec = 0;
+ delay.tv_nsec = nanoseconds;
+
+ while (nanosleep (&delay, &remDelay) == -1)
+ {
+ if (errno == EINTR)
+ {
+ delay.tv_nsec = remDelay.tv_nsec; /* tv_sec is zero */
+ }
+ else
+ {
+ break; /* Oops the sleep didn't work ??? */
+ }
+ }
+}
+
+int
+termProc (IDATA procHandle)
+{
+ int rc;
+
+ rc = kill ((pid_t) procHandle, SIGTERM);
+ return rc;
+}
+
+int
+waitForProc (IDATA procHandle)
+{
+ int StatusLocation = -1;
+
+ waitpid ((pid_t) procHandle, &StatusLocation, 0);
+ if (WIFEXITED (StatusLocation) != 0)
+ {
+ StatusLocation = WEXITSTATUS (StatusLocation);
+ }
+ else
+ {
+ if (WIFSIGNALED (StatusLocation) != 0)
+ {
+ StatusLocation = WTERMSIG (StatusLocation);
+ }
+ else
+ {
+ if (WIFSTOPPED (StatusLocation) != 0)
+ {
+ StatusLocation = WSTOPSIG (StatusLocation);
+ }
+ }
+ }
+
+ return StatusLocation;
+}
+
+int
+execProgram (JNIEnv * vmthread, jobject recv,
+ char *command[], int commandLineLength,
+ char *env[], int envSize, char *dir, IDATA * procHandle,
+ IDATA * inHandle, IDATA * outHandle, IDATA * errHandle)
+{
+ /* It is illegal to pass JNIEnv accross threads, so get the vm while
+ * we will go across another thread. The javaObject recv is used in
+ * the new thread ==> make it a globalRef.
+ */
+
+ char result;
+ char *cmd;
+ int grdpid, rc = 0;
+ int newFD[3][2];
+ int execvFailure[2];
+ int forkedChildIsRunning[2];
+
+ /* Build the new io pipes (in/out/err) */
+ pipe (newFD[0]);
+ pipe (newFD[1]);
+ pipe (newFD[2]);
+
+ /* pipes for synchronization */
+ pipe (forkedChildIsRunning);
+ pipe (execvFailure);
+
+ cmd = command[0];
+ grdpid = fork ();
+ if (grdpid == 0)
+ {
+ /* Redirect pipes so grand-child inherits new pipes */
+ char dummy = '\0';
+ dup2 (newFD[0][0], 0);
+ dup2 (newFD[1][1], 1);
+ dup2 (newFD[2][1], 2);
+ /* tells the parent that that very process is running */
+ write (forkedChildIsRunning[1], &dummy, 1);
+
+ if (dir)
+ chdir (dir);
+
+ /* ===try to perform the execv : on success, it does not return ===== */
+ if (envSize == 0)
+ rc = execvp (cmd, command);
+ else
+ rc = execve (cmd, command, env);
+ /* ===================================================== */
+
+ /* if we get here ==> tell the parent that the execv failed ! */
+ write (execvFailure[1], &dummy, 1);
+ /* If the exec failed, we must exit or there will be two VM processes running. */
+ exit (rc);
+ }
+ else
+ {
+ /* in the child-thread (not the grand-child) */
+ int stat_val = -1;
+ jfieldID hid;
+ jmethodID mid;
+ jclass rcvClass;
+ char dummy;
+ int avail = 0;
+ int noDataInThePipe;
+ int nbLoop;
+
+ close (newFD[0][0]);
+ close (newFD[1][1]);
+ close (newFD[2][1]);
+ /* Store the rw handles to the childs io */
+ *(inHandle) = (IDATA) newFD[0][1];
+ *(outHandle) = (IDATA) newFD[1][0];
+ *(errHandle) = (IDATA) newFD[2][0];
+ *(procHandle) = (IDATA) grdpid;
+
+ /* let the forked child start. */
+ read (forkedChildIsRunning[0], &dummy, 1);
+ close (forkedChildIsRunning[0]);
+ close (forkedChildIsRunning[1]);
+
+ /* Use the POSIX setpgid and its errno EACCES to detect the success of the execv function. When the feature is
+ not present on the platform, a delay is provided after which we conclude that if the execv didn't fail, it
+ must have propably succeeded. We loop on reading a pipe which will receive a byte if the execv fails. We
+ also break from the loop, if we have detected the success of the execv (or past a delay if the functionaly
+ is not present) */
+
+ rc = 0; /* at first glance, the execv will succeed (-1 is for failure) */
+ noDataInThePipe = 1;
+ ioctl (execvFailure[0], FIONREAD, &avail);
+ if (avail > 0)
+ {
+ rc = -1; /* failure of the execv */
+ noDataInThePipe = 0;
+ }
+ nbLoop = 0;
+ while (noDataInThePipe)
+ {
+ int setgpidResult;
+ /* =======give the child a chance to run=========== */
+ sleepFor (10000000); /* 10 ms */
+ /*========== probe the child for success of the execv ========*/
+ setgpidResult = setpgid (grdpid, grdpid);
+ if (setgpidResult == -1)
+ {
+ if (errno == EACCES)
+ {
+ /* fprintf(stdout,"\nSUCCESS DETECTED\n");fflush(stdout); */
+ break; /* success of the execv */
+ }
+ else
+ {
+ /* setgpid is probably not supported . Give some a bit of time to the child to tell us if it has
+ failed to launch the execv */
+ nbLoop++;
+ if (nbLoop > 10)
+ {
+ break; /* well, execv has probably succeeded */
+ }
+ }
+ }
+ /* =========Has a byte arrived in the pipe ? (failure test) ========= */
+ ioctl (execvFailure[0], FIONREAD, &avail);
+ if (avail > 0)
+ {
+ rc = -1; /* failure of the execv */
+ noDataInThePipe = 0;
+ }
+ } /* end of the loop. rc==-1 iff the execv failed */
+
+ /* if (rc==-1){ fprintf(stdout,"\nFAILURE DETECTED\n");fflush(stdout); } */
+
+ close (execvFailure[0]);
+ close (execvFailure[1]);
+
+ /* tells the parent what result it should return */
+ if ((grdpid < 0) || (rc == -1))
+ {
+ result = (char) 0;
+ }
+ else
+ {
+ result = (char) 1;
+ }
+ }
+ return (int) result; /* 0 or 1 */
+}
+
+/* Stream handling support */
+/* Return the number of bytes available to be read without blocking */
+int
+getAvailable (IDATA sHandle)
+{
+ int avail, rc;
+ rc = ioctl ((int) sHandle, FIONREAD, &avail);
+ if (rc == -1)
+ return -2;
+ return avail;
+}
+
+int
+closeProc (IDATA procHandle)
+{
+ /* The procHandle (Process ID) should not be closed, as it isn't a file descriptor. */
+ return 0;
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/procimpl.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/procimpl.h?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/procimpl.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/procimpl.h Wed Nov 30 21:29:27 2005
@@ -0,0 +1,32 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(procimpl_h)
+#define procimpl_h
+#define PROC_ALIVE (1)
+#define PROC_DEAD (-1)
+#define WAIT_ERROR PROC_DEAD
+#include <hycomp.h>
+#include <jni.h>
+int getAvailable (IDATA sHandle);
+int execProgram (JNIEnv * vmthread, jobject recv, char *command[],
+ int commandLineLength, char *env[], int envSize, char *dir,
+ IDATA * procHandle, IDATA * inHandle, IDATA * outHandle,
+ IDATA * errHandle);
+int waitForProc (IDATA procHandle);
+int closeProc (IDATA procHandle);
+int termProc (IDATA procHandle);
+void sleepFor (unsigned int nanoseconds);
+#endif /* procimpl_h */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/proxy.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/proxy.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/proxy.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/proxy.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,50 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "iohelp.h"
+#include "jclglob.h"
+
+jclass JNICALL
+Java_java_lang_reflect_Proxy_defineClassImpl (JNIEnv * env, jclass recvClass,
+ jobject classLoader,
+ jstring className,
+ jbyteArray classBytes)
+{
+ const char *name;
+ jbyte *bytes;
+ jclass returnClass;
+ jint length;
+
+ name = (*env)->GetStringUTFChars (env, className, NULL);
+ if (!name)
+ {
+ throwNewOutOfMemoryError (env, "");
+ return 0;
+ };
+ bytes = (*env)->GetByteArrayElements (env, classBytes, NULL);
+ if (!bytes)
+ {
+ (*env)->ReleaseStringUTFChars (env, className, name);
+ throwNewOutOfMemoryError (env, "");
+ return 0;
+ }
+ length = (*env)->GetArrayLength (env, classBytes);
+
+ returnClass = (*env)->DefineClass (env, name, classLoader, bytes, length);
+
+ (*env)->ReleaseByteArrayElements (env, classBytes, bytes, JNI_COMMIT);
+ (*env)->ReleaseStringUTFChars (env, className, name);
+ return returnClass;
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/psimpl2.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/psimpl2.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/psimpl2.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/luni/psimpl2.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,477 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include "nethelp.h"
+#include "jclglob.h"
+#include "jclprots.h"
+#include "portsock.h"
+
+/**
+ * Create a socket, of type stream.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param thisObjFD pointer to the socket file descriptor
+ * @param preferIPv4Stack if application preference is to use only IPv4 sockets (default is false)
+ * @exception SocketException if an error occurs creating the socket
+ */
+
+void JNICALL
+Java_java_net_PlainSocketImpl2_createStreamSocketImpl2 (JNIEnv * env,
+ jclass thisClz,
+ jobject thisObjFD,
+ jboolean
+ preferIPv4Stack)
+{
+ createSocket (env, thisObjFD, HYSOCK_STREAM, preferIPv4Stack);
+}
+
+/**
+ * Connect the socket to the nominated remote host address/port. The socket may then be used to send
+ * and receive data from the remote host.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the socket file descriptor
+ * @param remotePort the port on the remote host to connect to
+ * @param inetAddress the address to connect to
+ *
+ * @exception SocketException if an error occurs connected to the remote host
+ */
+
+void JNICALL
+Java_java_net_PlainSocketImpl2_connectStreamSocketImpl2 (JNIEnv * env,
+ jclass thisClz,
+ jobject
+ fileDescriptor,
+ jint remotePort,
+ jint trafficClass,
+ jobject inetAddress)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte nAddrBytes[HYSOCK_INADDR6_LEN];
+ int length;
+ U_16 nPort;
+ I_32 result;
+ hysocket_t socketP;
+ hysockaddr_struct sockaddrP;
+ U_32 scope_id = 0;
+
+ socketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_BADSOCKET);
+ return;
+ }
+ else
+ {
+ netGetJavaNetInetAddressValue (env, inetAddress, nAddrBytes, &length);
+
+ nPort = hysock_htons ((U_16) remotePort);
+ if (length == HYSOCK_INADDR_LEN)
+ {
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nAddrBytes, length,
+ HYADDR_FAMILY_AFINET4, nPort, 0, scope_id,
+ socketP);
+ }
+ else
+ {
+ netGetJavaNetInetAddressScopeId (env, inetAddress, &scope_id);
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nAddrBytes, length,
+ HYADDR_FAMILY_AFINET6, nPort,
+ (trafficClass & 0xFF) << 20, scope_id,
+ socketP);
+ }
+
+ result = hysock_connect (socketP, &sockaddrP);
+ if (0 != result)
+ {
+ throwJavaNetConnectException (env, result);
+ return;
+ }
+ }
+}
+
+/**
+ * Connect the socket to the nominated remote host address/port. The socket may then be used to send
+ * and receive data from the remote host.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the socket file descriptor
+ * @param remotePort the port on the remote host to connect to
+ * @param timeout timeout in milliseconds
+ * @param trafficClass the traffic class to be used for the connection
+ * @param inetAddress the address to be used for the connection
+ *
+ * @exception SocketException if an error occurs connected to the remote host
+ */
+
+void JNICALL
+Java_java_net_PlainSocketImpl2_connectStreamWithTimeoutSocketImpl2 (JNIEnv *
+ env,
+ jclass
+ thisClz,
+ jobject
+ fileDescriptor,
+ jint
+ remotePort,
+ jint
+ timeout,
+ jint
+ trafficClass,
+ jobject
+ inetAddress)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte nAddrBytes[HYSOCK_INADDR6_LEN];
+ int length;
+ U_16 nPort;
+ I_32 result;
+ hysocket_t socketP;
+ hysockaddr_struct sockaddrP;
+ U_8 *context = NULL;
+ I_32 remainingTimeout = timeout;
+ I_32 passedTimeout = 0;
+ UDATA finishTime = 0;
+ BOOLEAN hasTimeout = timeout > 0;
+ U_32 scope_id = 0;
+
+ /* if a timeout was specified calculate the finish time value */
+ if (hasTimeout)
+ {
+ finishTime = hytime_msec_clock () + (UDATA) timeout;
+ }
+
+ socketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_BADSOCKET);
+ return;
+ }
+ else
+ {
+ netGetJavaNetInetAddressValue (env, inetAddress, nAddrBytes, &length);
+ nPort = hysock_htons ((U_16) remotePort);
+ if (length == HYSOCK_INADDR_LEN)
+ {
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nAddrBytes, length,
+ HYADDR_FAMILY_AFINET4, nPort, 0, scope_id,
+ socketP);
+ }
+ else
+ {
+ netGetJavaNetInetAddressScopeId (env, inetAddress, &scope_id);
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nAddrBytes, length,
+ HYADDR_FAMILY_AFINET6, nPort,
+ (trafficClass & 0xFF) << 20, scope_id,
+ socketP);
+ }
+
+ result =
+ hysock_connect_with_timeout (socketP, &sockaddrP, 0,
+ HY_PORT_SOCKET_STEP_START, &context);
+ if (0 == result)
+ {
+ /* ok we connected right away so we are done */
+ hysock_connect_with_timeout (socketP, &sockaddrP, 0,
+ HY_PORT_SOCKET_STEP_DONE, &context);
+ return;
+ }
+ else if (result != HYPORT_ERROR_SOCKET_NOTCONNECTED)
+ {
+ /* we got an error other than NOTCONNECTED so we cannot continue */
+ if ((HYPORT_ERROR_SOCKET_CONNRESET == result) ||
+ (HYPORT_ERROR_SOCKET_CONNECTION_REFUSED == result) ||
+ (HYPORT_ERROR_SOCKET_ADDRNOTAVAIL == result) ||
+ (HYPORT_ERROR_SOCKET_ADDRINUSE == result) ||
+ (HYPORT_ERROR_SOCKET_ENETUNREACH == result) ||
+ (HYPORT_ERROR_SOCKET_EACCES == result))
+ {
+ hysock_connect_with_timeout (socketP, &sockaddrP,
+ remainingTimeout,
+ HY_PORT_SOCKET_STEP_DONE,
+ &context);
+ throwJavaNetConnectException (env, result);
+ return;
+ }
+ else
+ {
+ hysock_connect_with_timeout (socketP, &sockaddrP, 0,
+ HY_PORT_SOCKET_STEP_DONE,
+ &context);
+ throwJavaNetSocketException (env, result);
+ return;
+ }
+ }
+
+ while (HYPORT_ERROR_SOCKET_NOTCONNECTED == result)
+ {
+
+ passedTimeout = remainingTimeout;
+
+ /**
+ * ok now try and connect. Depending on the platform this may sleep for
+ * up to passedTimeout milliseconds
+ */
+ result =
+ hysock_connect_with_timeout (socketP, &sockaddrP, passedTimeout,
+ HY_PORT_SOCKET_STEP_CHECK, &context);
+
+ /**
+ * now check if the socket is still connected.
+ * Do it here as some platforms seem to think they are connected if the socket
+ * is closed on them
+ */
+ socketP =
+ getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ hysock_connect_with_timeout (socketP, &sockaddrP, 0,
+ HY_PORT_SOCKET_STEP_DONE,
+ &context);
+ throwJavaNetSocketException (env,
+ HYPORT_ERROR_SOCKET_BADSOCKET);
+ return;
+ }
+
+ /* check if we are now connected, if so we can finish the process and return */
+ if (0 == result)
+ {
+ hysock_connect_with_timeout (socketP, &sockaddrP, 0,
+ HY_PORT_SOCKET_STEP_DONE,
+ &context);
+ return;
+ }
+
+ /**
+ * if the error is HYPORT_ERROR_SOCKET_NOTCONNECTED then we have not yet connected
+ * and we may not be done yet
+ */
+ if (HYPORT_ERROR_SOCKET_NOTCONNECTED == result)
+ {
+ /* check if the timeout has expired */
+ if (hasTimeout)
+ {
+ remainingTimeout = finishTime - hytime_msec_clock ();
+ if (remainingTimeout <= 0)
+ {
+ hysock_connect_with_timeout (socketP, &sockaddrP, 0,
+ HY_PORT_SOCKET_STEP_DONE,
+ &context);
+ throwJavaNetSocketTimeoutException (env, result);
+ return;
+ }
+ }
+ else
+ {
+ remainingTimeout = 100;
+ }
+
+ }
+ else
+ {
+ if ((HYPORT_ERROR_SOCKET_CONNRESET == result) ||
+ (HYPORT_ERROR_SOCKET_CONNECTION_REFUSED == result) ||
+ (HYPORT_ERROR_SOCKET_ADDRNOTAVAIL == result) ||
+ (HYPORT_ERROR_SOCKET_ADDRINUSE == result) ||
+ (HYPORT_ERROR_SOCKET_ENETUNREACH == result) ||
+ (HYPORT_ERROR_SOCKET_EACCES == result))
+ {
+ hysock_connect_with_timeout (socketP, &sockaddrP,
+ remainingTimeout,
+ HY_PORT_SOCKET_STEP_DONE,
+ &context);
+ throwJavaNetConnectException (env, result);
+ return;
+ }
+ else
+ {
+ hysock_connect_with_timeout (socketP, &sockaddrP,
+ remainingTimeout,
+ HY_PORT_SOCKET_STEP_DONE,
+ &context);
+ throwJavaNetSocketException (env, result);
+ return;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Send data on this socket to the nominated host address/port.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the file descriptor of the java PlainDatagramSocketImpl
+ * @param data pointer to the java read buffer
+ * @param msgLength the length of the read buffer
+ * @param targetPort target port, in host order
+ * @param inetAddress the address to send the datagram to
+ *
+ * @return the number of bytes sent
+ * @exception SocketException if an error occurs during the call
+ */
+
+jint JNICALL
+Java_java_net_PlainSocketImpl2_sendDatagramImpl2 (JNIEnv * env,
+ jclass thisClz,
+ jobject fileDescriptor,
+ jbyteArray data,
+ jint offset, jint msgLength,
+ jint targetPort,
+ jobject inetAddress)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte *message;
+ jbyte nhostAddrBytes[HYSOCK_INADDR6_LEN];
+ U_16 nPort;
+ I_32 result = 0, sent = 0;
+ hysocket_t socketP;
+ hysockaddr_struct sockaddrP;
+ int length;
+ U_32 scope_id = 0;
+
+ if (inetAddress != NULL)
+ {
+ netGetJavaNetInetAddressValue (env, inetAddress, nhostAddrBytes,
+ &length);
+
+ socketP =
+ (hysocket_t) getJavaIoFileDescriptorContentsAsPointer (env,
+ fileDescriptor);
+ nPort = hysock_htons ((U_16) targetPort);
+ if (length == HYSOCK_INADDR_LEN)
+ {
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nhostAddrBytes, length,
+ HYPROTOCOL_FAMILY_INET4, nPort, 0, scope_id,
+ socketP);
+ }
+ else
+ {
+ netGetJavaNetInetAddressScopeId (env, inetAddress, &scope_id);
+ hysock_sockaddr_init6 (&sockaddrP, (U_8 *) nhostAddrBytes, length,
+ HYPROTOCOL_FAMILY_INET6, nPort, 0, scope_id,
+ socketP);
+ }
+ }
+
+ message = jclmem_allocate_memory (env, msgLength);
+ if (message == NULL)
+ {
+ throwNewOutOfMemoryError (env, "");
+ return 0;
+ }
+ (*env)->GetByteArrayRegion (env, data, offset, msgLength, message);
+ while (sent < msgLength)
+ {
+ socketP =
+ (hysocket_t) getJavaIoFileDescriptorContentsAsPointer (env,
+ fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ jclmem_free_memory (env, message);
+ throwJavaNetSocketException (env,
+ sent ==
+ 0 ? HYPORT_ERROR_SOCKET_BADSOCKET :
+ HYPORT_ERROR_SOCKET_INTERRUPTED);
+ return (jint) 0;
+ }
+ result =
+ hysock_writeto (socketP, (U_8 *) message + sent,
+ (I_32) msgLength - sent, HYSOCK_NOFLAGS, &sockaddrP);
+ if (result < 0)
+ break;
+ sent += result;
+ }
+ jclmem_free_memory (env, message);
+ /**
+ * We should always throw an exception if all the data cannot be sent because Java methods
+ * assume all the data will be sent or an error occurs.
+ */
+ if (result < 0)
+ {
+ throwJavaNetSocketException (env, result);
+ return (jint) 0;
+ }
+ else
+ {
+ return (jint) sent;
+ }
+}
+
+/**
+ * Bind the socket to the specified local address/port. This call is made after socket creation
+ * and prior to read/write operations.
+ *
+ * @param env pointer to the JNI library
+ * @param thisClz pointer to the class of the receiver (of the java message)
+ * @param fileDescriptor pointer to the file descriptor of the socket to bind
+ * @param localPort the port, in host order, to bind the socket on
+ * @param inetAddress address to be used for the bind
+ *
+ * @exception SocketException if an error occurs during the call
+ */
+
+void JNICALL
+Java_java_net_PlainSocketImpl2_socketBindImpl2 (JNIEnv * env, jclass thisClz,
+ jobject fileDescriptor,
+ jint localPort,
+ jobject inetAddress)
+{
+ PORT_ACCESS_FROM_ENV (env);
+ jbyte nlocalAddrBytes[HYSOCK_INADDR6_LEN];
+ int length;
+ U_16 nPort;
+ I_32 result;
+ hysocket_t socketP;
+ hysockaddr_struct sockaddrP;
+ U_32 scope_id = 0;
+
+ socketP = getJavaIoFileDescriptorContentsAsPointer (env, fileDescriptor);
+ if (!hysock_socketIsValid (socketP))
+ {
+ throwJavaNetSocketException (env, HYPORT_ERROR_SOCKET_BADSOCKET);
+ return;
+ }
+ else
+ {
+ netGetJavaNetInetAddressValue (env, inetAddress, nlocalAddrBytes,
+ &length);
+
+ nPort = hysock_htons ((U_16) localPort);
+ if (length == HYSOCK_INADDR6_LEN)
+ {
+ netGetJavaNetInetAddressScopeId (env, inetAddress, &scope_id);
+ hysock_sockaddr_init6 (&sockaddrP, nlocalAddrBytes, length,
+ HYADDR_FAMILY_AFINET6, nPort, 0, scope_id,
+ socketP);
+ }
+ else
+ {
+ hysock_sockaddr_init6 (&sockaddrP, nlocalAddrBytes, length,
+ HYADDR_FAMILY_AFINET4, nPort, 0, scope_id,
+ socketP);
+ }
+ result = hysock_bind (socketP, &sockaddrP);
+ if (0 != result)
+ {
+ throwJavaNetBindException (env, result);
+ return;
+ }
+ }
+}
|