50 extern jclass udsa_class; |
50 extern jclass udsa_class; |
51 extern jmethodID udsa_ctorID; |
51 extern jmethodID udsa_ctorID; |
52 extern jfieldID udsa_pathID; |
52 extern jfieldID udsa_pathID; |
53 |
53 |
54 JNIEXPORT jobject JNICALL |
54 JNIEXPORT jobject JNICALL |
55 NET_SockaddrToUnixAddress(JNIEnv *env, SOCKETADDRESS *sa) { |
55 NET_SockaddrToUnixAddress(JNIEnv *env, struct sockaddr_un *sa) { |
56 |
56 |
57 if (sa->sa.sa_family == AF_UNIX) { |
57 if (sa->sun_family == AF_UNIX) { |
58 char *name = sa->saun.sun_path; |
58 char *name = sa->sun_path; |
59 |
59 |
60 jstring nstr = JNU_NewStringPlatform(env, name); |
60 jstring nstr = JNU_NewStringPlatform(env, name); |
61 return (*env)->NewObject(env, udsa_class, udsa_ctorID, nstr); |
61 return (*env)->NewObject(env, udsa_class, udsa_ctorID, nstr); |
62 } |
62 } |
63 return NULL; |
63 return NULL; |
64 } |
64 } |
65 |
65 |
66 JNIEXPORT jint JNICALL |
66 JNIEXPORT jint JNICALL |
67 NET_UnixSocketAddressToSockaddr(JNIEnv *env, jobject uaddr, SOCKETADDRESS *sa, int *len) |
67 NET_UnixSocketAddressToSockaddr(JNIEnv *env, jobject uaddr, struct sockaddr_un *sa, int *len) |
68 { |
68 { |
69 jstring path = (*env)->GetObjectField(env, uaddr, udsa_pathID); |
69 jstring path = (*env)->GetObjectField(env, uaddr, udsa_pathID); |
70 jboolean isCopy; |
70 jboolean isCopy; |
71 int ret; |
71 int ret; |
72 const char* pname = JNU_GetStringPlatformChars(env, path, &isCopy); |
72 const char* pname = JNU_GetStringPlatformChars(env, path, &isCopy); |
73 memset(sa, 0, sizeof(SOCKETADDRESS)); |
73 memset(sa, 0, sizeof(struct sockaddr_un)); |
74 sa->saun.sun_family = AF_UNIX; |
74 sa->sun_family = AF_UNIX; |
75 int name_len = strlen(pname) + 1; /* includes null termination */ |
75 int name_len = strlen(pname) + 1; /* includes null termination */ |
76 if (name_len > MAX_UNIX_DOMAIN_PATH_LEN) { |
76 if (name_len > MAX_UNIX_DOMAIN_PATH_LEN) { |
77 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "unix domain path too long"); |
77 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "unix domain path too long"); |
78 ret = 1; |
78 ret = 1; |
79 goto finish; |
79 goto finish; |
80 } |
80 } |
81 strncpy(&sa->saun.sun_path[0], pname, name_len); |
81 strncpy(&sa->sun_path[0], pname, name_len); |
82 *len = offsetof(struct sockaddr_un, sun_path) + name_len; |
82 *len = offsetof(struct sockaddr_un, sun_path) + name_len; |
83 ret = 0; |
83 ret = 0; |
84 finish: |
84 finish: |
85 if (isCopy) |
85 if (isCopy) |
86 JNU_ReleaseStringPlatformChars(env, path, pname); |
86 JNU_ReleaseStringPlatformChars(env, path, pname); |
104 } |
104 } |
105 |
105 |
106 JNIEXPORT void JNICALL |
106 JNIEXPORT void JNICALL |
107 Java_sun_nio_ch_Net_unixDomainBind(JNIEnv *env, jclass clazz, jobject fdo, jobject uaddr) |
107 Java_sun_nio_ch_Net_unixDomainBind(JNIEnv *env, jclass clazz, jobject fdo, jobject uaddr) |
108 { |
108 { |
109 SOCKETADDRESS sa; |
109 struct sockaddr_un sa; |
110 int sa_len = 0; |
110 int sa_len = 0; |
111 int rv = 0; |
111 int rv = 0; |
112 |
112 |
113 if (NET_UnixSocketAddressToSockaddr(env, uaddr, &sa, &sa_len) != 0) |
113 if (NET_UnixSocketAddressToSockaddr(env, uaddr, &sa, &sa_len) != 0) |
114 return; |
114 return; |
115 |
115 |
116 int fd = fdval(env, fdo); |
116 int fd = fdval(env, fdo); |
117 |
117 |
118 rv = NET_Bind(fdval(env, fdo), &sa, sa_len); |
118 rv = bind(fdval(env, fdo), (struct sockaddr *)&sa, sa_len); |
119 if (rv != 0) { |
119 if (rv != 0) { |
120 handleSocketError(env, errno); |
120 handleSocketError(env, errno); |
121 } |
121 } |
122 } |
122 } |
123 |
123 |
124 JNIEXPORT jint JNICALL |
124 JNIEXPORT jint JNICALL |
125 Java_sun_nio_ch_Net_unixDomainConnect(JNIEnv *env, jclass clazz, jobject fdo, jobject usa) |
125 Java_sun_nio_ch_Net_unixDomainConnect(JNIEnv *env, jclass clazz, jobject fdo, jobject usa) |
126 { |
126 { |
127 SOCKETADDRESS sa; |
127 struct sockaddr_un sa; |
128 int sa_len = 0; |
128 int sa_len = 0; |
129 int rv; |
129 int rv; |
130 |
130 |
131 if (NET_UnixSocketAddressToSockaddr(env, usa, &sa, &sa_len) != 0) { |
131 if (NET_UnixSocketAddressToSockaddr(env, usa, &sa, &sa_len) != 0) { |
132 return IOS_THROWN; |
132 return IOS_THROWN; |
133 } |
133 } |
134 |
134 |
135 rv = connect(fdval(env, fdo), &sa.sa, sa_len); |
135 rv = connect(fdval(env, fdo), (struct sockaddr *)&sa, sa_len); |
136 if (rv != 0) { |
136 if (rv != 0) { |
137 if (errno == EINPROGRESS) { |
137 if (errno == EINPROGRESS) { |
138 return IOS_UNAVAILABLE; |
138 return IOS_UNAVAILABLE; |
139 } else if (errno == EINTR) { |
139 } else if (errno == EINTR) { |
140 return IOS_INTERRUPTED; |
140 return IOS_INTERRUPTED; |
148 Java_sun_nio_ch_Net_unixDomainAccept(JNIEnv *env, jclass clazz, jobject fdo, jobject newfdo, |
148 Java_sun_nio_ch_Net_unixDomainAccept(JNIEnv *env, jclass clazz, jobject fdo, jobject newfdo, |
149 jobjectArray usaa) |
149 jobjectArray usaa) |
150 { |
150 { |
151 jint fd = fdval(env, fdo); |
151 jint fd = fdval(env, fdo); |
152 jint newfd; |
152 jint newfd; |
153 SOCKETADDRESS sa; |
153 struct sockaddr_un sa; |
154 socklen_t sa_len = sizeof(SOCKETADDRESS); |
154 socklen_t sa_len = sizeof(struct sockaddr_un); |
155 jobject usa; |
155 jobject usa; |
156 |
156 |
157 /* accept connection but ignore ECONNABORTED */ |
157 /* accept connection but ignore ECONNABORTED */ |
158 for (;;) { |
158 for (;;) { |
159 newfd = accept(fd, &sa.sa, &sa_len); |
159 newfd = accept(fd, (struct sockaddr *)&sa, &sa_len); |
160 if (newfd >= 0) { |
160 if (newfd >= 0) { |
161 break; |
161 break; |
162 } |
162 } |
163 if (errno != ECONNABORTED) { |
163 if (errno != ECONNABORTED) { |
164 break; |
164 break; |
186 } |
186 } |
187 |
187 |
188 JNIEXPORT jobject JNICALL |
188 JNIEXPORT jobject JNICALL |
189 Java_sun_nio_ch_Net_localUnixAddress(JNIEnv *env, jclass clazz, jobject fdo) |
189 Java_sun_nio_ch_Net_localUnixAddress(JNIEnv *env, jclass clazz, jobject fdo) |
190 { |
190 { |
191 SOCKETADDRESS sa; |
191 struct sockaddr_un sa; |
192 socklen_t sa_len = sizeof(SOCKETADDRESS); |
192 socklen_t sa_len = sizeof(struct sockaddr_un); |
193 int port; |
193 int port; |
194 if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) { |
194 if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) { |
195 handleSocketError(env, errno); |
195 handleSocketError(env, errno); |
196 return NULL; |
196 return NULL; |
197 } |
197 } |
198 return NET_SockaddrToUnixAddress(env, &sa); |
198 return NET_SockaddrToUnixAddress(env, &sa); |
199 } |
199 } |