1/*
2 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26/*
27 */
28
29#include "jni.h"
30#include "jni_util.h"
31#include "jvm.h"
32#include "jlong.h"
33// Android removed.
34//
35#include <unistd.h>
36#include <sys/types.h>
37#include <sys/uio.h>
38#include <sys/socket.h>
39#include <string.h>
40
41#include "nio_util.h"
42#include <limits.h>
43
44#include "nio.h"
45#include "JNIHelp.h"
46
47#define NATIVE_METHOD(className, functionName, signature) \
48{ #functionName, signature, (void*)(Java_sun_nio_ch_ ## className ## _ ## functionName) }
49
50JNIEXPORT jint JNICALL
51Java_sun_nio_ch_DatagramDispatcher_read0(JNIEnv *env, jclass clazz,
52                         jobject fdo, jlong address, jint len)
53{
54    jint fd = fdval(env, fdo);
55    void *buf = (void *)jlong_to_ptr(address);
56    int result = recv(fd, buf, len, 0);
57    if (result < 0 && errno == ECONNREFUSED) {
58        JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
59        return -2;
60    }
61    return convertReturnVal(env, result, JNI_TRUE);
62}
63
64// Android-changed : Use sysconf for IOV_MAX.
65static int iov_max = -1;
66
67JNIEXPORT jlong JNICALL
68Java_sun_nio_ch_DatagramDispatcher_readv0(JNIEnv *env, jclass clazz,
69                              jobject fdo, jlong address, jint len)
70{
71    jint fd = fdval(env, fdo);
72    ssize_t result = 0;
73    struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
74    struct msghdr m;
75
76    // Android-changed : Use sysconf for IOV_MAX.
77    if (iov_max == -1) {
78        iov_max = sysconf(_SC_IOV_MAX);
79    }
80    if (len > iov_max) {
81        len = iov_max;
82    }
83
84    // initialize the message
85    memset(&m, 0, sizeof(m));
86    m.msg_iov = iov;
87    m.msg_iovlen = len;
88
89    result = recvmsg(fd, &m, 0);
90    if (result < 0 && errno == ECONNREFUSED) {
91        JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
92        return -2;
93    }
94    return convertLongReturnVal(env, (jlong)result, JNI_TRUE);
95}
96
97JNIEXPORT jint JNICALL
98Java_sun_nio_ch_DatagramDispatcher_write0(JNIEnv *env, jclass clazz,
99                              jobject fdo, jlong address, jint len)
100{
101    jint fd = fdval(env, fdo);
102    void *buf = (void *)jlong_to_ptr(address);
103    int result = send(fd, buf, len, 0);
104    if (result < 0 && errno == ECONNREFUSED) {
105        JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
106        return -2;
107    }
108    return convertReturnVal(env, result, JNI_FALSE);
109}
110
111JNIEXPORT jlong JNICALL
112Java_sun_nio_ch_DatagramDispatcher_writev0(JNIEnv *env, jclass clazz,
113                                       jobject fdo, jlong address, jint len)
114{
115    jint fd = fdval(env, fdo);
116    struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
117    struct msghdr m;
118    ssize_t result = 0;
119
120    // Android-changed : Use sysconf for IOV_MAX.
121    if (iov_max == -1) {
122        iov_max = sysconf(_SC_IOV_MAX);
123    }
124
125    if (len > iov_max) {
126        len = iov_max;
127    }
128
129    // initialize the message
130    memset(&m, 0, sizeof(m));
131    m.msg_iov = iov;
132    m.msg_iovlen = len;
133
134    result = sendmsg(fd, &m, 0);
135    if (result < 0 && errno == ECONNREFUSED) {
136        JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
137        return -2;
138    }
139    return convertLongReturnVal(env, (jlong)result, JNI_FALSE);
140}
141
142static JNINativeMethod gMethods[] = {
143  NATIVE_METHOD(DatagramDispatcher, read0, "(Ljava/io/FileDescriptor;JI)I"),
144  NATIVE_METHOD(DatagramDispatcher, readv0, "(Ljava/io/FileDescriptor;JI)J"),
145  NATIVE_METHOD(DatagramDispatcher, write0, "(Ljava/io/FileDescriptor;JI)I"),
146  NATIVE_METHOD(DatagramDispatcher, writev0, "(Ljava/io/FileDescriptor;JI)J"),
147};
148
149void register_sun_nio_ch_DatagramDispatcher(JNIEnv* env) {
150  jniRegisterNativeMethods(env, "sun/nio/ch/DatagramDispatcher", gMethods, NELEM(gMethods));
151}
152