📄 plainsocketimpl.c
字号:
remote_addr = NULL; memset(&addr, 0, sizeof(addr));#if defined(BSD44) addr.sin_len = sizeof(addr);#endif /* defined(BSD44) */ addr.sin_family = AF_INET; addr.sin_port = htons(unhand(sock)->localport); /* I guess the next line is too much as unhand(sock)->address is not supposed * to be initialized. * addr.sin_addr.s_addr = htonl(unhand(unhand(sock)->address)->address); */ addr.sin_addr.s_addr = INADDR_ANY; DBG(NATIVENET, dprintf("socketAccept(%p, localport=%d, addr=%s, timeout=%d)\n", this, ntohs(addr.sin_port), ip2str(addr.sin_addr.s_addr), unhand(this)->timeout); ); alen = sizeof(addr); do { rc = KACCEPT(fd, (struct sockaddr*)&addr, &alen, unhand(this)->timeout, &r); releaseFileToSocket(this); if (unhand(this)->native_fd < 0) { SignalError("java.net.SocketException", "Socket was closed"); } } while (rc == EINTR); if (rc == ETIMEDOUT) { DBG(NATIVENET, dprintf("socketAcceptTimedOut(%p, localport=%d, addr=%s, timeout=%d)\n", this, ntohs(addr.sin_port), ip2str(addr.sin_addr.s_addr), unhand(this)->timeout); ); SignalError("java.net.SocketTimeoutException", "Accept timed out"); } if (rc) { SignalError("java.io.IOException", SYS_ERROR(rc)); } if (unhand(accepted_socket)->native_fd != -1) { rc1 = KSOCKCLOSE(unhand((struct Hgnu_java_net_PlainSocketImpl *)sock)->native_fd); if (rc1) { SignalError("java.io.IOException", SYS_ERROR(rc1)); } } unhand(accepted_socket)->native_fd = r; unhand(accepted_socket)->fdUsed++; /* Enter information into socket object */ alen = sizeof(addr); r = KGETPEERNAME(r, (struct sockaddr*)&addr, &alen); if (r) { SignalError("java.io.IOException", SYS_ERROR(r)); } /* create a byte array containing the raw address of the connected socket */ switch (addr.sin_family) { case AF_INET: remote_addr = (HArrayOfByte *)newArray(TYPE_CLASS(TYPE_Byte), sizeof(addr.sin_addr)); memcpy(unhand_byte_array(remote_addr), &addr.sin_addr, sizeof(addr.sin_addr)); break;#if defined(notnow) && defined(AF_INET6) case AF_INET6: remote_addr = (HArrayOfByte *)newArray(TYPE_CLASS(TYPE_Byte), sizeof(in6->sin6_addr)); memcpy(unhand_byte_array(remote_addr), &in6->sin6_addr, sizeof(in6->sin6_addr)); break;#endif /* defined(AF_INET6) */ default: /* Ignore */ break; } /* and use that byte array to create an appropriate Inet*Address instance */ do_execute_java_class_method (&jv, "java.net.InetAddress", NULL, "getByAddress", "([B)Ljava/net/InetAddress;", remote_addr); unhand(sock)->address = jv.l; unhand(sock)->port = ntohs(addr.sin_port); alen = sizeof(addr); r = KGETSOCKNAME(unhand(accepted_socket)->native_fd, (struct sockaddr*)&addr, &alen); if (r) { SignalError("java.io.IOException", SYS_ERROR(r)); } unhand(accepted_socket)->localport = ntohs(addr.sin_port); DBG(NATIVENET, dprintf("socketAccept(%p, localport=-, addr=-) -> (sock: %p; addr: %s; port:%d)\n", this, sock, ip2str(addr.sin_addr.s_addr), ntohs(addr.sin_port)); );}/* * Return how many bytes can be read without blocking. */jintgnu_java_net_PlainSocketImpl_socketAvailable(struct Hgnu_java_net_PlainSocketImpl* this){ int r; jint len; int fd;#if (!(defined(HAVE_IOCTL) && defined(FIONREAD)) && !defined(__WIN32__)) static struct timeval tm = { 0, 0 }; fd_set rd;#endif /* (!(defined(HAVE_IOCTL) && defined(FIONREAD)) && !defined(__WIN32__)) */ DBG(NATIVENET, dprintf("socketAvailable(%p)\n", this); ); fd = getFileFromSocket(this);#if defined(HAVE_IOCTL) && defined(FIONREAD) /* XXX make part of system call interface to protect errno */ r = ioctl(fd, FIONREAD, &len); if (r < 0) { releaseFileToSocket(this); SignalError("java.io.IOException", SYS_ERROR(errno)); }#else /* !(defined(HAVE_IOCTL) && defined(FIONREAD)) */#if defined(__WIN32__) /* Windows hack - XXX */ len = 0;#else /* !defined(__WIN32__) */ /* This uses KSELECT() to work out if we can read - but what * happens at the end of file? */ FD_ZERO(&rd); FD_SET(fd, &rd); KSELECT(fd+1, &rd, NULL, NULL, &tm, &r); /* XXX ignore ret code*/ if (r == 1) { len = 1; } else { len = 0; }#endif /* defined(__WIN32__) */#endif /* defined(HAVE_IOCTL) && defined(FIONREAD) */ DBG(NATIVENET, dprintf("socketAvailable(%p) -> %d\n", this, len); ); releaseFileToSocket(this); return (len);}/* * Close this socket. */voidgnu_java_net_PlainSocketImpl_socketClose(struct Hgnu_java_net_PlainSocketImpl* this){ int r; DBG(NATIVENET, dprintf("socketClose(%p)\n", this); ); if (unhand(this)->native_fd != -1) { r = KSOCKSHUTDOWN((int)unhand(this)->native_fd); lockObject((struct Hjava_lang_Object*)this); unhand(this)->fdUsed--; if (unhand(this)->fdUsed == 0 && r == 0) { r = KSOCKCLOSE((int)unhand(this)->native_fd); unhand(this)->native_fd = -1; } unlockObject((struct Hjava_lang_Object*)this); if (r) { SignalError("java.io.IOException", SYS_ERROR(r)); } }}voidgnu_java_net_PlainSocketImpl_socketSetOption(struct Hgnu_java_net_PlainSocketImpl* this, jint opt, struct Hjava_lang_Object* arg){ int r, v; unsigned int k; int fd; DBG(NATIVENET, const char *optstr = "UNKNOWN"; for (k = 0; k < sizeof(optionNames) / sizeof(optionNames[0]); k++) if (optionNames[k].opt == opt) optstr = optionNames[k].name; dprintf("socketSetOption(%p, %s, arg=%p)\n", this, optstr, arg); ); /* Do easy cases */ for (k = 0; k < sizeof(socketOptions) / sizeof(*socketOptions); k++) { if (opt == socketOptions[k].jopt) { struct linger ling; char *optdata; int optlen; fd = getFileFromSocket(this); v = unhand((struct Hjava_lang_Integer*)arg)->value; if( socketOptions[k].copt == SO_LINGER ) { ling.l_onoff = v; ling.l_linger = v; optdata = (char *)&ling; optlen = sizeof(ling); } else { optdata = (char *)&v; optlen = sizeof(v); } r = KSETSOCKOPT(fd, socketOptions[k].level, socketOptions[k].copt, optdata, optlen); releaseFileToSocket(this); if (r) { SignalError("java.net.SocketException", SYS_ERROR(r)); } return; } } /* Do harder cases */ switch(opt) { case java_net_SocketOptions_SO_BINDADDR: SignalError("java.net.SocketException", "Read-only socket option"); break; case java_net_SocketOptions_SO_TIMEOUT: /* java takes care */ case java_net_SocketOptions_IP_MULTICAST_IF: default: SignalError("java.net.SocketException", "Unimplemented socket option"); break; } }jintgnu_java_net_PlainSocketImpl_socketGetOption(struct Hgnu_java_net_PlainSocketImpl* this, jint opt){ struct sockaddr_in addr; socklen_t alen = sizeof(addr); int r = 0, v; socklen_t vsize = sizeof(v); unsigned int k; int fd; DBG(NATIVENET, const char *optstr = "UNKNOWN"; for (k = 0; k < sizeof(optionNames) / sizeof(optionNames[0]); k++) if (optionNames[k].opt == opt) optstr = optionNames[k].name; dprintf("socketGetOption(%p, %s)\n", this, optstr); ); /* Do easy cases */ for (k = 0; k < sizeof(socketOptions) / sizeof(*socketOptions); k++) { if (opt == socketOptions[k].jopt) { fd = getFileFromSocket(this); r = KGETSOCKOPT(fd, socketOptions[k].level, socketOptions[k].copt, &v, &vsize); releaseFileToSocket(this); if (r) { SignalError("java.net.SocketException", SYS_ERROR(r)); } DBG(NATIVENET, dprintf("socketGetOption(%p, -) -> %d\n", this, v); ); return v; } } /* Do harder cases */ switch(opt) { case java_net_SocketOptions_SO_BINDADDR: fd = getFileFromSocket(this); r = KGETSOCKNAME(fd, (struct sockaddr*)&addr, &alen); releaseFileToSocket(this); if (r) { SignalError("java.net.SocketException", SYS_ERROR(r)); } r = htonl(addr.sin_addr.s_addr); break; case java_net_SocketOptions_IP_MULTICAST_IF: case java_net_SocketOptions_SO_TIMEOUT: /* java takes care */ default: SignalError("java.net.SocketException", "Unimplemented socket option"); } DBG(NATIVENET, dprintf("socketGetOption(%p, -) -> %d\n", this, r); ); return (r);}jintgnu_java_net_PlainSocketImpl_socketRead(struct Hgnu_java_net_PlainSocketImpl* this, HArrayOfByte* buf, jint offset, jint len){ ssize_t r; int rc; int fd; int total_read; DBG(NATIVENET, dprintf("socket_read(%p, %p, %d, %d)\n", this, buf, offset, len); ); fd = getFileFromSocket(this); total_read = 0; r = 0; do { rc = KSOCKREAD(fd, &unhand_array(buf)->body[offset], (unsigned)len, unhand(this)->timeout, &r); if (rc == ETIMEDOUT) { struct Hjava_io_InterruptedIOException* except; releaseFileToSocket(this); except = (struct Hjava_io_InterruptedIOException *) execute_java_constructor( "java.net.SocketTimeoutException", NULL, NULL, "(Ljava/lang/String;)V", checkPtr(stringC2Java("Read was interrupted"))); except->bytesTransferred = r; throwException((struct Hjava_lang_Throwable*)except); } else if (rc != EINTR && rc != 0) { releaseFileToSocket(this); if (unhand(this)->native_fd < 0) SignalError("java.net.SocketException", "Socket was closed"); SignalError("java.net.IOException", SYS_ERROR(rc)); } else if (rc == 0 && r == 0 && len > 0) { releaseFileToSocket(this); return (-1); } offset += r; len -= r; total_read += r; } while (rc == EINTR); releaseFileToSocket(this); return (total_read);}voidgnu_java_net_PlainSocketImpl_socketWrite(struct Hgnu_java_net_PlainSocketImpl* this, HArrayOfByte* buf, jint offset, jint len){ int r; int fd; ssize_t nw; DBG(NATIVENET, dprintf("socket_write(%p, %p, %d, %d)\n", this, buf, offset, len); ); fd = getFileFromSocket(this); while (len > 0) { r = KSOCKWRITE(fd, &unhand_array(buf)->body[offset], (unsigned)len, &nw); if (r) { releaseFileToSocket(this); if (unhand(this)->native_fd < 0) { SignalError("java.net.SocketException", "Socket was closed"); } SignalError("java.net.SocketException", SYS_ERROR(r)); } offset += nw; len -= nw; } releaseFileToSocket(this);}voidgnu_java_net_PlainSocketImpl_setBlocking(struct Hgnu_java_net_PlainSocketImpl* this, jboolean blocking){ if (blocking == unhand(this)->blocking) return; unhand(this)->blocking = true; KTHREAD(set_blocking)((int)unhand(this)->native_fd, blocking);}voidgnu_java_net_PlainSocketImpl_waitForConnection(struct Hgnu_java_net_PlainSocketImpl* this){ fd_set w; int fd = getFileFromSocket(this); int o, r; struct timeval tv; struct timeval *ptv = NULL; if (!unhand(this)->blocking) { if (!unhand(this)->connecting) { releaseFileToSocket(this); return; } FD_ZERO(&w); FD_SET(fd, &w); tv.tv_sec = 0; tv.tv_usec = 0; ptv = &tv; } r = KSELECT(fd+1, NULL, &w, NULL, ptv, &o); releaseFileToSocket(this); if (r == EINTR) { SignalError("java.io.InterruptedIOException", SYS_ERROR(r)); } if (r != 0) { SignalError("java.io.IOException", SYS_ERROR(r)); } if (o != 0 && FD_ISSET(fd, &w)) unhand(this)->connecting = false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -