⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plainsocketimpl.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 "support.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 "debug.h"#include "object.h"#include "itypes.h"#include "exception.h"#include "locks.h"#include "dummyin6.h"#define IPV4_ADDRESS_SIZE 4#define IPV6_ADDRESS_SIZE 16#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;	  const 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(uint32 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++) {	    count += sprintf(&addrbuf[count], i == 0 && addr->s6_addr[i] != 0 ? "%x" : addr->s6_addr[i] != 0 ? "%x:" : i != 0 ? ":" : "", addr->s6_addr[i]);	}	return addrbuf;}#endif /* defined(HAVE_STRUCT_SOCKADDR_IN6) */#endif /* defined(KAFFE_VMDEBUG) && !defined(NDEBUG) *//** * This is a helper functions to obtain safely a file descriptor which represents * the socket. * * @param this A valid socket implementation. * @return A valid file descriptor if available. */static intgetFileFromSocket(struct Hgnu_java_net_PlainSocketImpl* this){  int fd;  lockObject((struct Hjava_lang_Object *)this);  fd = (int)unhand(this)->native_fd;  if (fd < 0)    {      unlockObject((struct Hjava_lang_Object *)this);      SignalError("java.net.SocketException", "fd invalid");    }  unhand(this)->fdUsed++;  unlockObject((struct Hjava_lang_Object*)this);    return fd;}/** * This is a helper functions to return safely a file descriptor to * the socket. * * @param this A valid socket implementation. */static voidreleaseFileToSocket(struct Hgnu_java_net_PlainSocketImpl* this){  lockObject((struct Hjava_lang_Object*)this);  unhand(this)->fdUsed--;  if (unhand(this)->fdUsed == 0)    {      KSOCKCLOSE(unhand(this)->native_fd);      unhand(this)->native_fd = -1;    }  unlockObject((struct Hjava_lang_Object*)this);}/* * Create a stream or datagram socket. */voidgnu_java_net_PlainSocketImpl_socketCreate(struct Hgnu_java_net_PlainSocketImpl* this, jboolean 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(this)->native_fd = -1;		SignalError("java.io.IOException", SYS_ERROR(rc));	}	DBG(NATIVENET,	    dprintf("socketCreate(%p, %s) -> fd=%d\n", 		    this, stream ? "stream" : "datagram", fd);	    );	unhand(this)->fdUsed++;	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;	socklen_t alen;	memset(&addr, 0, sizeof(addr));	if (obj_length(unhand(daddr)->addr) == IPV4_ADDRESS_SIZE) {	        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) == IPV6_ADDRESS_SIZE) {	        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 = getFileFromSocket(this);	r = KCONNECT(fd, (struct sockaddr*)&addr, alen, timeout);	if (r == EINTR) {	        releaseFileToSocket(this);		SignalError("java.io.InterruptedIOException", 			    "Connect was interrupted");	}	if (r == ETIMEDOUT) {	        releaseFileToSocket(this);	        SignalError("java.net.SocketTimeoutException",			    "Connect timed out");	}	if (r == EWOULDBLOCK && unhand(this)->blocking) {		unhand(this)->connecting = true;		return;	}	if (r) {	        releaseFileToSocket(this);		SignalError("java.io.IOException", SYS_ERROR(r));	}	/* Enter information into socket object */	alen = sizeof(addr);	r = KGETSOCKNAME(fd, (struct sockaddr*)&addr, &alen);	releaseFileToSocket(this);	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;	socklen_t 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) == IPV4_ADDRESS_SIZE) {	        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) == IPV6_ADDRESS_SIZE) {	        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 = getFileFromSocket(this);	/* 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:	        releaseFileToSocket(this);		SignalError("java.net.BindException", SYS_ERROR(r));		break;	default:	        releaseFileToSocket(this);		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);		releaseFileToSocket(this);		if (r) {			SignalError("java.io.IOException", SYS_ERROR(r));		}#if defined(HAVE_STRUCT_SOCKADDR_IN6)		if (obj_length(unhand(laddr)->addr) == IPV6_ADDRESS_SIZE) {		  lport = ntohs(addr.addr6.sin6_port);		} else#endif		{		  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(getFileFromSocket(this), count);	releaseFileToSocket(this);	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 fd;	int r;	int rc, rc1;	socklen_t alen;	struct sockaddr_in addr;	HArrayOfByte *remote_addr;	struct Hgnu_java_net_PlainSocketImpl* accepted_socket =	  (struct Hgnu_java_net_PlainSocketImpl *)sock;	jvalue jv;	fd = getFileFromSocket(this);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -