1035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak/*
2035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
3035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak *
5035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * This code is free software; you can redistribute it and/or modify it
6035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * under the terms of the GNU General Public License version 2 only, as
7035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * published by the Free Software Foundation.  Oracle designates this
8035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * particular file as subject to the "Classpath" exception as provided
9035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * by Oracle in the LICENSE file that accompanied this code.
10035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak *
11035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * This code is distributed in the hope that it will be useful, but WITHOUT
12035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * version 2 for more details (a copy is included in the LICENSE file that
15035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * accompanied this code).
16035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak *
17035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * You should have received a copy of the GNU General Public License version
18035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * 2 along with this work; if not, write to the Free Software Foundation,
19035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak *
21035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * or visit www.oracle.com if you need additional information or have any
23035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak * questions.
24035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak */
25035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
26035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include <stdlib.h>
27035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include <sys/types.h>
28035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include <sys/socket.h>
29035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include <unistd.h>
30035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include <fcntl.h>
31035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
32035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include "jni.h"
33035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
34035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include "jni.h"
35035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include "jni_util.h"
36035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include "net_util.h"
37035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
38035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include "sun_nio_ch_InheritedChannel.h"
39035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
40035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#include "JNIHelp.h"
41035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
42035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#define NATIVE_METHOD(className, functionName, signature) \
43035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak{ #functionName, signature, (void*)(Java_sun_nio_ch_ ## className ## _ ## functionName) }
44035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
45035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniakstatic int matchFamily(struct sockaddr *sa) {
46035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    int family = sa->sa_family;
47035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#ifdef AF_INET6
48035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    if (ipv6_available()) {
49035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        return (family == AF_INET6);
50035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    }
51035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak#endif
52035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    return (family == AF_INET);
53035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak}
54035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
55035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJNIEXPORT jobject JNICALL
56035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJava_sun_nio_ch_InheritedChannel_peerAddress0(JNIEnv *env, jclass cla, jint fd)
57035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak{
58035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    struct sockaddr *sa;
59035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    socklen_t sa_len;
60035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    jobject remote_ia = NULL;
61035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    jint remote_port;
62035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
63035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    NET_AllocSockaddr(&sa, (int *)&sa_len);
64035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    if (getpeername(fd, sa, &sa_len) == 0) {
65035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        if (matchFamily(sa)) {
66035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            remote_ia = NET_SockaddrToInetAddress(env, sa, (int *)&remote_port);
67035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        }
68035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    }
69035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    free((void *)sa);
70035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
71035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    return remote_ia;
72035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak}
73035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
74035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
75035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJNIEXPORT jint JNICALL
76035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJava_sun_nio_ch_InheritedChannel_peerPort0(JNIEnv *env, jclass cla, jint fd)
77035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak{
78035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    struct sockaddr *sa;
79035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    socklen_t sa_len;
80035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    jint remote_port = -1;
81035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
82035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    NET_AllocSockaddr(&sa, (int *)&sa_len);
83035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    if (getpeername(fd, sa, &sa_len) == 0) {
84035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        if (matchFamily(sa)) {
85035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            NET_SockaddrToInetAddress(env, sa, (int *)&remote_port);
86035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        }
87035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    }
88035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    free((void *)sa);
89035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
90035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    return remote_port;
91035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak}
92035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
93035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJNIEXPORT jint JNICALL
94035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJava_sun_nio_ch_InheritedChannel_soType0(JNIEnv *env, jclass cla, jint fd)
95035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak{
96035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    int sotype;
97035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    socklen_t arglen=sizeof(sotype);
98035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen) == 0) {
99035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        if (sotype == SOCK_STREAM)
100035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            return sun_nio_ch_InheritedChannel_SOCK_STREAM;
101035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        if (sotype == SOCK_DGRAM)
102035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            return sun_nio_ch_InheritedChannel_SOCK_DGRAM;
103035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    }
104035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    return sun_nio_ch_InheritedChannel_UNKNOWN;
105035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak}
106035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
107035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJNIEXPORT jint JNICALL
108035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJava_sun_nio_ch_InheritedChannel_dup(JNIEnv *env, jclass cla, jint fd)
109035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak{
110035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak   int newfd = dup(fd);
111035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak   if (newfd < 0) {
112035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        JNU_ThrowIOExceptionWithLastError(env, "dup failed");
113035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak   }
114035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak   return (jint)newfd;
115035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak}
116035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
117035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJNIEXPORT void JNICALL
118035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJava_sun_nio_ch_InheritedChannel_dup2(JNIEnv *env, jclass cla, jint fd, jint fd2)
119035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak{
120035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak   if (dup2(fd, fd2) < 0) {
121035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
122035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak   }
123035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak}
124035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
125035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJNIEXPORT jint JNICALL
126035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJava_sun_nio_ch_InheritedChannel_open0(JNIEnv *env, jclass cla, jstring path, jint oflag)
127035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak{
128035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    const char* str;
129035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    int oflag_actual;
130035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
131035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    /* convert to OS specific value */
132035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    switch (oflag) {
133035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        case sun_nio_ch_InheritedChannel_O_RDWR :
134035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            oflag_actual = O_RDWR;
135035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            break;
136035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        case sun_nio_ch_InheritedChannel_O_RDONLY :
137035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            oflag_actual = O_RDONLY;
138035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            break;
139035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        case sun_nio_ch_InheritedChannel_O_WRONLY :
140035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            oflag_actual = O_WRONLY;
141035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            break;
142035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        default :
143035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            JNU_ThrowInternalError(env, "Unrecognized file mode");
144035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            return -1;
145035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    }
146035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
147035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    str = JNU_GetStringPlatformChars(env, path, NULL);
148035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    if (str == NULL) {
149035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        return (jint)-1;
150035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    } else {
151035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        int fd = open(str, oflag_actual);
152035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        if (fd < 0) {
153035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak            JNU_ThrowIOExceptionWithLastError(env, str);
154035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        }
155035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        JNU_ReleaseStringPlatformChars(env, path, str);
156035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        return (jint)fd;
157035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    }
158035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak}
159035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
160035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJNIEXPORT void JNICALL
161035c91d75c90c5cdc049606649586140202d697aPrzemyslaw SzczepaniakJava_sun_nio_ch_InheritedChannel_close0(JNIEnv *env, jclass cla, jint fd)
162035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak{
163035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    if (close(fd) < 0) {
164035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak        JNU_ThrowIOExceptionWithLastError(env, "close failed");
165035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak    }
166035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak}
167035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
168035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniakstatic JNINativeMethod gMethods[] = {
169035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak  NATIVE_METHOD(InheritedChannel, dup, "(I)I"),
170035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak  NATIVE_METHOD(InheritedChannel, dup2, "(II)V"),
171035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak  NATIVE_METHOD(InheritedChannel, open0, "(Ljava/lang/String;I)I"),
172035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak  NATIVE_METHOD(InheritedChannel, close0, "(I)V"),
173035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak  NATIVE_METHOD(InheritedChannel, soType0, "(I)I"),
174035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak  NATIVE_METHOD(InheritedChannel, peerAddress0, "(I)Ljava/net/InetAddress;"),
175035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak  NATIVE_METHOD(InheritedChannel, peerPort0, "(I)I"),
176035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
177035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak};
178035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak
179035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniakvoid register_sun_nio_ch_InheritedChannel(JNIEnv* env) {
18009f993b04651359387d5e089b076994bb6cccc5fNarayan Kamath  jniRegisterNativeMethods(env, "sun/nio/ch/InheritedChannel", gMethods, NELEM(gMethods));
181035c91d75c90c5cdc049606649586140202d697aPrzemyslaw Szczepaniak}
182