📄 plainsocketimpl.c
字号:
/* * java.net.PlainSocketImpl.c * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "config.h"#include "config-std.h"#include "config-io.h"#include "config-mem.h"#include "config-net.h"#include <native.h>#include "java_io_FileDescriptor.h"#include "java_lang_Integer.h"#include "java_net_SocketImpl.h"#include "java_net_InetAddress.h"#include "gnu_java_net_PlainSocketImpl.h"#include "java_net_SocketOptions.h"#include "java_io_InterruptedIOException.h"#include "nets.h"#include <jsyscall.h>#include <jthread.h>#include "../../../kaffe/kaffevm/debug.h"#include "../../../kaffe/kaffevm/object.h"#include "../../../kaffe/kaffevm/itypes.h"#include "../../../kaffe/kaffevm/exception.h"#include "dummyin6.h"#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)#include "getaddrinfo.h"#endif /* !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) *//* * Supported socket options */ static const struct { int jopt; int level; int copt; } socketOptions[] = {#if defined(SO_SNDBUF) { java_net_SocketOptions_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF },#endif /* defined(SO_SNDBUF) */#if defined(SO_RCVBUF) { java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },#endif /* defined(SO_RCVBUF) */#if defined(SO_LINGER) { java_net_SocketOptions_SO_LINGER, SOL_SOCKET, SO_LINGER },#endif /* defined(SO_LINGER) */#if defined(SO_REUSEADDR) { java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR },#endif /* defined(SO_REUSEADDR) */#if defined(TCP_NODELAY) { java_net_SocketOptions_TCP_NODELAY, IPPROTO_TCP, TCP_NODELAY },#endif /* defined(TCP_NODELAY) */ };#if defined(KAFFE_VMDEBUG) && !defined(NDEBUG)/* * Option names (for debugging only) */ static const struct { int opt; char *name; } optionNames[] = {#if defined(SO_SNDBUF) { java_net_SocketOptions_SO_SNDBUF, "SO_SNDBUF" },#endif /* defined(SO_SNDBUF) */#if defined(SO_RCVBUF) { java_net_SocketOptions_SO_RCVBUF, "SO_RCVBUF" },#endif /* defined(SO_RCVBUF) */#if defined(SO_LINGER) { java_net_SocketOptions_SO_LINGER, "SO_LINGER" },#endif /* defined(SO_LINGER) */#if defined(SO_REUSEADDR) { java_net_SocketOptions_SO_REUSEADDR, "SO_REUSEADDR" },#endif /* defined(SO_REUSEADDR) */#if defined(TCP_NODELAY) { java_net_SocketOptions_TCP_NODELAY, "TCP_NODELAY" },#endif /* defined(TCP_NODELAY) */ { java_net_SocketOptions_SO_BINDADDR, "SO_BINDADDR" }, { java_net_SocketOptions_SO_TIMEOUT, "SO_TIMEOUT" }, { java_net_SocketOptions_IP_MULTICAST_IF, "IP_MULTICAST_IF" } };static char *ip2str(jint addr) { static char addrbuf[16]; addr = ntohl(addr); sprintf(addrbuf, "%u.%u.%u.%u", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, (addr ) & 0xff); return addrbuf;}#if defined(HAVE_STRUCT_SOCKADDR_IN6)/* Generate a string for an inet6 addr (in host form). */static char *ip62str(struct in6_addr *addr) { static char addrbuf[255]; int i, count; for (count=0,i=0;i<16;i++) { char *format; if (i == 0 && addr->s6_addr[i] != 0) format = "%x"; else if (addr->s6_addr[i] != 0) format = "%x:"; else if (i != 0) format = ":"; else format = ""; count += sprintf(&addrbuf[count], format, addr->s6_addr[i]); } return addrbuf;}#endif /* defined(HAVE_STRUCT_SOCKADDR_IN6) */#endif /* defined(KAFFE_VMDEBUG) && !defined(NDEBUG) *//* * Create a stream or datagram socket. */voidgnu_java_net_PlainSocketImpl_socketCreate(struct Hgnu_java_net_PlainSocketImpl* this, jbool stream){ int fd; int type; int rc; if (stream == 0) { type = SOCK_DGRAM; } else { type = SOCK_STREAM; } DBG(NATIVENET, dprintf("socketCreate(%p, %s)\n", this, stream ? "stream" : "datagram"); ) rc = KSOCKET(AF_INET, type, 0, &fd); if (rc) { unhand(unhand(this)->fd)->nativeFd = -1; SignalError("java.io.IOException", SYS_ERROR(rc)); } DBG(NATIVENET, dprintf("socketCreate(%p, %s) -> fd=%d\n", this, stream ? "stream" : "datagram", fd); ) unhand(unhand(this)->fd)->nativeFd = fd; unhand(this)->native_fd = fd;}/* * Connect the socket to someone. */voidgnu_java_net_PlainSocketImpl_socketConnect(struct Hgnu_java_net_PlainSocketImpl* this, struct Hjava_net_InetAddress* daddr, jint dport, jint timeout){ int fd; int r; KaffeSocketAddr addr; int alen; memset(&addr, 0, sizeof(addr)); if (obj_length(unhand(daddr)->addr) == 4) { alen = sizeof(addr.addr4); #if defined(BSD44) addr.addr4.sin_len = sizeof(addr.addr4);#endif /* defined(BSD44) */ addr.addr4.sin_family = AF_INET; addr.addr4.sin_port = htons(dport); memcpy(&addr.addr4.sin_addr, unhand_byte_array(unhand(daddr)->addr), sizeof(addr.addr4.sin_addr));#if defined(HAVE_STRUCT_SOCKADDR_IN6) } else if (obj_length(unhand(daddr)->addr) == 16) { alen = sizeof(addr.addr6);#if defined(BSD44) addr.addr6.sin6_len = sizeof(addr.addr6);#endif /* defined(BSD44) */ addr.addr6.sin6_family = AF_INET6; addr.addr6.sin6_port = htons(dport); memcpy(&addr.addr6.sin6_addr, unhand_byte_array(unhand(daddr)->addr), sizeof(addr.addr6.sin6_addr));#endif /* defined(HAVE_STRUCT_SOCKADDR_IN6) */ } else { SignalError("java.net.SocketException", "Unsupported address family"); } DBG(NATIVENET, dprintf("socketConnect(%p, %s, %d, %d)\n", this, ip2str(addr.addr4.sin_addr.s_addr), dport, timeout); ) fd = (int)unhand(unhand(this)->fd)->nativeFd; r = KCONNECT(fd, (struct sockaddr*)&addr, alen, timeout); if (r == EINTR) { SignalError("java.io.InterruptedIOException", "Connect was interrupted"); } if (r == ETIMEDOUT) { SignalError("java.net.SocketTimeoutException", "Connect timed out"); } if (r == EWOULDBLOCK && unhand(this)->blocking) { unhand(this)->connecting = true; return; } if (r) { SignalError("java.io.IOException", SYS_ERROR(r)); } /* Enter information into socket object */ alen = sizeof(addr); r = KGETSOCKNAME(fd, (struct sockaddr*)&addr, &alen); if (r) { SignalError("java.io.IOException", SYS_ERROR(r)); } DBG(NATIVENET, dprintf("socketConnect(%p, %s, %d) -> (lport: %d)\n", this, ip2str(addr.addr4.sin_addr.s_addr), dport, ntohs(addr.addr4.sin_port) ); ) unhand(this)->address = daddr; unhand(this)->port = dport; unhand(this)->localport = ntohs(addr.addr4.sin_port);}/* * Bind this socket to an address. */voidgnu_java_net_PlainSocketImpl_socketBind(struct Hgnu_java_net_PlainSocketImpl* this, struct Hjava_net_InetAddress* laddr, jint lport){ int r; KaffeSocketAddr addr; int fd; int on = 1; int alen; DBG(NATIVENET, dprintf("socketBind(%p, %s, %d)\n", this, ip2str(unhand(laddr)->address), lport); ) memset(&addr, 0, sizeof(addr)); if (obj_length(unhand(laddr)->addr) == 4) { alen = sizeof(addr.addr4);#if defined(BSD44) addr.addr4.sin_len = sizeof(addr.addr4);#endif /* defined(BSD44) */ addr.addr4.sin_family = AF_INET; addr.addr4.sin_port = htons(lport); memcpy(&addr.addr4.sin_addr, unhand_byte_array(unhand(laddr)->addr), sizeof(addr.addr4.sin_addr)); DBG(NATIVENET, dprintf("socketBind(%p, %s, -) -> (lport: %d)\n", this, ip2str(addr.addr4.sin_addr.s_addr), lport); );#if defined(HAVE_STRUCT_SOCKADDR_IN6) } else if (obj_length(unhand(laddr)->addr) == 16) { alen = sizeof(addr.addr6);#if defined(BSD44) addr.addr6.sin6_len = sizeof(addr.addr6);#endif /* defined(BSD44) */ addr.addr6.sin6_family = AF_INET6; addr.addr6.sin6_port = htons(lport); memcpy(&addr.addr6.sin6_addr, unhand_byte_array(unhand(laddr)->addr), sizeof(addr.addr6.sin6_addr)); DBG(NATIVENET, dprintf("socketBind(%p, %s, -) -> (lport: %d)\n", this, ip62str(&addr.addr6.sin6_addr), lport); );#endif /* defined(HAVE_STRUCT_SOCKADDR_IN6) */ } else { SignalError("java.net.SocketException", "Unsupported address family"); } fd = (int)unhand(unhand(this)->fd)->nativeFd; /* Allow rebinding to socket - ignore errors */ (void)KSETSOCKOPT(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)); r = KBIND(fd, (struct sockaddr*)&addr, alen); switch( r ) { case 0: break; case EADDRNOTAVAIL: case EADDRINUSE: case EACCES: SignalError("java.net.BindException", SYS_ERROR(r)); break; default: SignalError("java.net.SocketException", SYS_ERROR(r)); break; } /* Enter information into socket object */ unhand(this)->address = laddr; if (lport == 0) { alen = sizeof(addr); r = KGETSOCKNAME(fd, (struct sockaddr*)&addr, &alen); if (r) { SignalError("java.io.IOException", SYS_ERROR(r)); } lport = ntohs(addr.addr4.sin_port); } unhand(this)->localport = lport;}/* * Turn this socket into a listener. */voidgnu_java_net_PlainSocketImpl_socketListen(struct Hgnu_java_net_PlainSocketImpl* this, jint count){ int r; DBG(NATIVENET, dprintf("socketListen(%p, count=%d)\n", this, count); ) r = KLISTEN((int)unhand(unhand(this)->fd)->nativeFd, count); if (r) { SignalError("java.io.IOException", SYS_ERROR(r)); }}/* * Accept a connection. */voidgnu_java_net_PlainSocketImpl_socketAccept(struct Hgnu_java_net_PlainSocketImpl* this, struct Hjava_net_SocketImpl* sock){ int r; int rc; int alen; struct sockaddr_in addr; HArrayOfByte *remote_addr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -