src/java.base/windows/native/libnio/ch/Net.c
branchunixdomainchannels
changeset 58801 119ac9128c1b
parent 57649 b2fde6701654
child 58847 692de65ab293
equal deleted inserted replaced
58799:eb491334113f 58801:119ac9128c1b
    75     DWORD bytesReturned = 0;
    75     DWORD bytesReturned = 0;
    76     WSAIoctl(s, SIO_UDP_CONNRESET, &enable, sizeof(enable),
    76     WSAIoctl(s, SIO_UDP_CONNRESET, &enable, sizeof(enable),
    77              NULL, 0, &bytesReturned, NULL, NULL);
    77              NULL, 0, &bytesReturned, NULL, NULL);
    78 }
    78 }
    79 
    79 
    80 jint handleSocketError(JNIEnv *env, int errorValue)
    80 JNIEXPORT jint JNICALL
       
    81 handleSocketError(JNIEnv *env, int errorValue)
    81 {
    82 {
    82     NET_ThrowNew(env, errorValue, NULL);
    83     NET_ThrowNew(env, errorValue, NULL);
    83     return IOS_THROWN;
    84     return IOS_THROWN;
    84 }
    85 }
    85 
    86 
    86 static jclass isa_class;        /* java.net.InetSocketAddress */
    87 static jclass isa_class;        /* java.net.InetSocketAddress */
    87 static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
    88 static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
       
    89 
       
    90 extern jclass udsa_class;
       
    91 extern jmethodID udsa_ctorID;
       
    92 extern jfieldID udsa_pathID;
       
    93 extern jfieldID udsa_isAbstractID;
       
    94 
       
    95 JNIEXPORT jobject JNICALL
       
    96 NET_SockaddrToUnixAddress(JNIEnv *env, SOCKETADDRESS *sa) {
       
    97     jboolean isAbstract;
       
    98 
       
    99     if (sa->sa.sa_family == AF_UNIX) {
       
   100         char *name = sa->saun.sun_path;
       
   101 
       
   102 #ifdef NOTDEF
       
   103         /* check for abstract name */
       
   104         if (name[0] == 0) {
       
   105             isAbstract = 1;
       
   106             name++; // skip the zero byte
       
   107         } else
       
   108 #endif
       
   109             isAbstract = 0;
       
   110         jstring nstr = JNU_NewStringPlatform(env, name);
       
   111         return (*env)->NewObject(env, udsa_class, udsa_ctorID, nstr);
       
   112     }
       
   113     return NULL;
       
   114 }
       
   115 
       
   116 JNIEXPORT jint JNICALL
       
   117 NET_UnixSocketAddressToSockaddr(JNIEnv *env, jobject uaddr, SOCKETADDRESS *sa, int *len)
       
   118 {
       
   119     jstring path = (*env)->GetObjectField(env, uaddr, udsa_pathID);
       
   120     jboolean isCopy;
       
   121     //jboolean isAbstract = (*env)->GetBooleanField(env, uaddr, udsa_isAbstractID);
       
   122     int ret;
       
   123     const char* pname = JNU_GetStringPlatformChars(env, path, &isCopy);
       
   124     memset(sa, 0, sizeof(SOCKETADDRESS));
       
   125     sa->saun.sun_family = AF_UNIX;
       
   126     size_t name_len = strlen(pname)+1;
       
   127     if (name_len > MAX_UNIX_DOMAIN_PATH_LEN) {
       
   128         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "unix domain path too long");
       
   129         ret = 1;
       
   130         goto finish;
       
   131     }
       
   132 #ifdef NOTDEF
       
   133     if (isAbstract) {
       
   134         strncpy(&sa->saun.sun_path[1], pname, name_len);
       
   135         sa->saun.sun_path[0] = 0;
       
   136         name_len++;
       
   137     } else
       
   138 #endif
       
   139     {
       
   140         strncpy(sa->saun.sun_path, pname, name_len);
       
   141     }
       
   142     *len = (int)(offsetof(struct sockaddr_un, sun_path) + name_len);
       
   143     ret = 0;
       
   144   finish:
       
   145     if (isCopy)
       
   146         JNU_ReleaseStringPlatformChars(env, path, pname);
       
   147     return ret;
       
   148 }
       
   149 
       
   150 JNIEXPORT jboolean JNICALL
       
   151 Java_sun_nio_ch_Net_unixDomainSocketSupported(JNIEnv *env, jclass cl)
       
   152 {
       
   153     SOCKET fd = socket(PF_UNIX, SOCK_STREAM, 0);
       
   154     if (fd < 0) {
       
   155         return JNI_FALSE;
       
   156     }
       
   157     closesocket(fd);
       
   158     return JNI_TRUE;
       
   159 }
       
   160 
       
   161 JNIEXPORT jint JNICALL
       
   162 Java_sun_nio_ch_Net_unixDomainSocket0(JNIEnv *env, jclass cl)
       
   163 {
       
   164     SOCKET fd = socket(PF_UNIX, SOCK_STREAM, 0);
       
   165     if (fd < 0) {
       
   166         return handleSocketError(env, errno);
       
   167     }
       
   168     return (int)fd;
       
   169 }
       
   170 
       
   171 JNIEXPORT void JNICALL
       
   172 Java_sun_nio_ch_Net_unixDomainBind(JNIEnv *env, jclass clazz, jobject fdo, jobject uaddr)
       
   173 {
       
   174     SOCKETADDRESS sa;
       
   175     int sa_len = 0;
       
   176     int rv = 0;
       
   177 
       
   178     if (NET_UnixSocketAddressToSockaddr(env, uaddr, &sa, &sa_len) != 0)
       
   179         return;
       
   180 
       
   181     int fd = fdval(env, fdo);
       
   182 
       
   183     rv = NET_Bind(fdval(env, fdo), &sa, sa_len);
       
   184     if (rv != 0) {
       
   185         int err = WSAGetLastError();
       
   186         NET_ThrowNew(env, err, "bind");
       
   187     }
       
   188 }
       
   189 
       
   190 JNIEXPORT jint JNICALL
       
   191 Java_sun_nio_ch_Net_unixDomainConnect(JNIEnv *env, jclass clazz, jobject fdo, jobject usa)
       
   192 {
       
   193     SOCKETADDRESS sa;
       
   194     int sa_len = 0;
       
   195     int rv;
       
   196 
       
   197     if (NET_UnixSocketAddressToSockaddr(env, usa, &sa, &sa_len) != 0) {
       
   198         return IOS_THROWN;
       
   199     }
       
   200 
       
   201     rv = connect(fdval(env, fdo), (const struct sockaddr *)&sa.saun, sa_len);
       
   202     if (rv != 0) {
       
   203         int err = WSAGetLastError();
       
   204         if (err == WSAEINPROGRESS || err == WSAEWOULDBLOCK) {
       
   205             return IOS_UNAVAILABLE;
       
   206         }
       
   207         NET_ThrowNew(env, err, "connect");
       
   208         return IOS_THROWN;
       
   209     }
       
   210     return 1;
       
   211 }
       
   212 
       
   213 JNIEXPORT jint JNICALL
       
   214 Java_sun_nio_ch_Net_unixDomainAccept(JNIEnv *env, jclass clazz, jobject fdo, jobject newfdo,
       
   215                            jobjectArray usaa)
       
   216 {
       
   217     jint fd = fdval(env, fdo);
       
   218     jint newfd;
       
   219     SOCKETADDRESS sa;
       
   220     socklen_t sa_len = sizeof(SOCKETADDRESS);
       
   221     jobject usa;
       
   222 
       
   223     /* accept connection but ignore ECONNABORTED */
       
   224     for (;;) {
       
   225         newfd = (jint)accept(fd, &sa.sa, &sa_len);
       
   226         if (newfd >= 0) {
       
   227             break;
       
   228         }
       
   229         if (errno != ECONNABORTED) {
       
   230             break;
       
   231         }
       
   232         /* ECONNABORTED => restart accept */
       
   233     }
       
   234 
       
   235     if (newfd < 0) {
       
   236         if (errno == EAGAIN || errno == EWOULDBLOCK)
       
   237             return IOS_UNAVAILABLE;
       
   238         if (errno == EINTR)
       
   239             return IOS_INTERRUPTED;
       
   240         JNU_ThrowIOExceptionWithLastError(env, "Accept failed");
       
   241         return IOS_THROWN;
       
   242     }
       
   243 
       
   244     setfdval(env, newfdo, newfd);
       
   245 
       
   246     usa = NET_SockaddrToUnixAddress(env, &sa);
       
   247     CHECK_NULL_RETURN(usa, IOS_THROWN);
       
   248 
       
   249     (*env)->SetObjectArrayElement(env, usaa, 0, usa);
       
   250 
       
   251     return 1;
       
   252 }
       
   253 
       
   254 JNIEXPORT jobject JNICALL
       
   255 Java_sun_nio_ch_Net_localUnixAddress(JNIEnv *env, jclass clazz, jobject fdo)
       
   256 {
       
   257     SOCKETADDRESS sa;
       
   258     socklen_t sa_len = sizeof(SOCKETADDRESS);
       
   259     if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
       
   260         handleSocketError(env, errno);
       
   261         return NULL;
       
   262     }
       
   263     return NET_SockaddrToUnixAddress(env, &sa);
       
   264 }
    88 
   265 
    89 JNIEXPORT void JNICALL
   266 JNIEXPORT void JNICALL
    90 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
   267 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
    91 {
   268 {
    92      jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
   269      jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");