60 flags |= O_NONBLOCK; \
61 fcntl(fd, F_SETFL, flags); \
62 }
63
64 #define SET_BLOCKING(fd) { \
65 int flags = fcntl(fd, F_GETFL); \
66 flags &= ~O_NONBLOCK; \
67 fcntl(fd, F_SETFL, flags); \
68 }
69
70 /*
71 * Create the marker file descriptor by establishing a loopback connection
72 * which we shutdown but do not close the fd. The result is an fd that
73 * can be used for read/write.
74 */
75 static int getMarkerFD()
76 {
77 int sv[2];
78
79 #ifdef AF_UNIX
80 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
81 return -1;
82 }
83 #else
84 return -1;
85 #endif
86
87 /*
88 * Finally shutdown sv[0] (any reads to this fd will get
89 * EOF; any writes will get an error).
90 */
91 shutdown(sv[0], 2);
92 close(sv[1]);
93
94 return sv[0];
95 }
96
97 /*
98 * Return the file descriptor given a PlainSocketImpl
99 */
100 static int getFD(JNIEnv *env, jobject this) {
161 Java_java_net_PlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
162 jboolean stream) {
163 jobject fdObj, ssObj;
164 int fd;
165 int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
166 int domain = ipv6_available() ? AF_INET6 : AF_INET;
167
168 if (socketExceptionCls == NULL) {
169 jclass c = (*env)->FindClass(env, "java/net/SocketException");
170 CHECK_NULL(c);
171 socketExceptionCls = (jclass)(*env)->NewGlobalRef(env, c);
172 CHECK_NULL(socketExceptionCls);
173 }
174 fdObj = (*env)->GetObjectField(env, this, psi_fdID);
175
176 if (fdObj == NULL) {
177 (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
178 return;
179 }
180
181 if ((fd = socket(domain, type, 0)) == -1) {
182 /* note: if you run out of fds, you may not be able to load
183 * the exception class, and get a NoClassDefFoundError
184 * instead.
185 */
186 NET_ThrowNew(env, errno, "can't create socket");
187 return;
188 }
189
190 /* Disable IPV6_V6ONLY to ensure dual-socket support */
191 if (domain == AF_INET6) {
192 int arg = 0;
193 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
194 sizeof(int)) < 0) {
195 NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
196 close(fd);
197 return;
198 }
199 }
200
201 /*
|
60 flags |= O_NONBLOCK; \
61 fcntl(fd, F_SETFL, flags); \
62 }
63
64 #define SET_BLOCKING(fd) { \
65 int flags = fcntl(fd, F_GETFL); \
66 flags &= ~O_NONBLOCK; \
67 fcntl(fd, F_SETFL, flags); \
68 }
69
70 /*
71 * Create the marker file descriptor by establishing a loopback connection
72 * which we shutdown but do not close the fd. The result is an fd that
73 * can be used for read/write.
74 */
75 static int getMarkerFD()
76 {
77 int sv[2];
78
79 #ifdef AF_UNIX
80 if (NET_SocketPair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
81 return -1;
82 }
83 #else
84 return -1;
85 #endif
86
87 /*
88 * Finally shutdown sv[0] (any reads to this fd will get
89 * EOF; any writes will get an error).
90 */
91 shutdown(sv[0], 2);
92 close(sv[1]);
93
94 return sv[0];
95 }
96
97 /*
98 * Return the file descriptor given a PlainSocketImpl
99 */
100 static int getFD(JNIEnv *env, jobject this) {
161 Java_java_net_PlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
162 jboolean stream) {
163 jobject fdObj, ssObj;
164 int fd;
165 int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
166 int domain = ipv6_available() ? AF_INET6 : AF_INET;
167
168 if (socketExceptionCls == NULL) {
169 jclass c = (*env)->FindClass(env, "java/net/SocketException");
170 CHECK_NULL(c);
171 socketExceptionCls = (jclass)(*env)->NewGlobalRef(env, c);
172 CHECK_NULL(socketExceptionCls);
173 }
174 fdObj = (*env)->GetObjectField(env, this, psi_fdID);
175
176 if (fdObj == NULL) {
177 (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
178 return;
179 }
180
181 if ((fd = NET_Socket(domain, type, 0)) == -1) {
182 /* note: if you run out of fds, you may not be able to load
183 * the exception class, and get a NoClassDefFoundError
184 * instead.
185 */
186 NET_ThrowNew(env, errno, "can't create socket");
187 return;
188 }
189
190 /* Disable IPV6_V6ONLY to ensure dual-socket support */
191 if (domain == AF_INET6) {
192 int arg = 0;
193 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
194 sizeof(int)) < 0) {
195 NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
196 close(fd);
197 return;
198 }
199 }
200
201 /*
|