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

📄 plaindatagramsocketimpl.c

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * java.net.PlainDatagramSocketImpl.c * * Copyright (c) 1996, 1997 *	Transvirtual Technologies, Inc.  All rights reserved. * Copyright (c) 2003 *       Kaffe's team. * * See the file "license.terms" for information on usage and redistribution  * of this file.  */#include "config.h"#include "config-std.h"#include "config-mem.h"#include "config-net.h"#include "config-io.h"#include "config-hacks.h"#include <native.h>#include "java_lang_Integer.h"#include "java_io_FileDescriptor.h"#include "java_io_InterruptedIOException.h"#include "java_net_DatagramPacket.h"#include "java_net_NetworkInterface.h"#include "java_net_SocketAddress.h"#include "gnu_java_net_PlainDatagramSocketImpl.h"#include "java_net_InetSocketAddress.h"#include "java_net_InetAddress.h"#include "java_net_SocketOptions.h"#include "java_util_Vector.h"#include "nets.h"#include <jsyscall.h>#include "Arrays.h"#include "../../../kaffe/kaffevm/debug.h"#include "../../../kaffe/kaffevm/itypes.h"#include "../../../kaffe/kaffevm/exception.h"#include "dummyin6.h"/* * Supported socket options */static const struct {    int jopt;    int level;    int copt;} socketOptions[] = {#ifdef SO_SNDBUF    { java_net_SocketOptions_SO_SNDBUF,		SOL_SOCKET,	SO_SNDBUF },#endif#ifdef SO_RCVBUF    { java_net_SocketOptions_SO_RCVBUF,		SOL_SOCKET,	SO_RCVBUF },#endif#ifdef SO_REUSEADDR    { java_net_SocketOptions_SO_REUSEADDR,	SOL_SOCKET,	SO_REUSEADDR },#endif  };#if defined(KAFFE_VMDEBUG) && !defined(NDEBUG)/* Generate a string for an inet addr (in host form). */static char *ip2str(jint addr) {	static char addrbuf[16];	unsigned int top = (addr >> 24) & 0xFF;	unsigned int tmid = (addr >> 16) & 0xFF;	unsigned int bmid = (addr >> 8) & 0xFF;	unsigned int bottom = addr & 0xFF;	sprintf(addrbuf, "%u.%u.%u.%u", top, tmid, bmid, bottom);	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 datagram socket. */voidgnu_java_net_PlainDatagramSocketImpl_datagramSocketCreate(struct Hgnu_java_net_PlainDatagramSocketImpl* this){	int fd;	int rc;DBG(NATIVENET,	dprintf("datagram_create(%p)\n", this);)	rc = KSOCKET(AF_INET, SOCK_DGRAM, 0, &fd);	if (rc) {		unhand(unhand(this)->fd)->nativeFd = -1;		SignalError("java.net.SocketException", SYS_ERROR(rc));	}	unhand(unhand(this)->fd)->nativeFd = fd;	unhand(this)->native_fd = fd;DBG(NATIVENET,	dprintf("datagram_create(%p) -> fd=%d\n", this, fd);)#if defined(SOL_SOCKET) && defined(SO_BROADCAST)	/* On some systems broadcasting is off by default - enable it here */	{		int brd = 1;		KSETSOCKOPT(fd, SOL_SOCKET, SO_BROADCAST, &brd, sizeof(brd));		/* ignore return code */	}#endif}/* * Bind a port to the socket (IPV4 version). */voidgnu_java_net_PlainDatagramSocketImpl_bind(struct Hgnu_java_net_PlainDatagramSocketImpl* this, jint port,					  struct Hjava_net_InetAddress* laddr){	int r;	KaffeSocketAddr addr;	int alen;	const int fd = unhand(unhand(this)->fd)->nativeFd;	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(port);		memcpy(&addr.addr4.sin_addr, unhand_byte_array(unhand(laddr)->addr),		       sizeof(addr.addr4.sin_addr));DBG(NATIVENET,	dprintf("datagram_bind4(%p, %s, %d)\n", 		this, ip2str(addr.addr4.sin_addr.s_addr), port);)#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(port);		memcpy(&addr.addr6.sin6_addr, unhand_byte_array(unhand(laddr)->addr),		       sizeof(addr.addr6.sin6_addr));DBG(NATIVENET,	dprintf("datagram_bind6(%p, %s, %d)\n", 		this, ip62str(&addr.addr6.sin6_addr), port);)		#endif /* defined(HAVE_STRUCT_SOCKADDR_IN6) */	} else {		SignalError("java.net.SocketException", "Unsupported address family");	}	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;	}	if (port == 0) {		alen = sizeof(addr);		r = KGETSOCKNAME(fd, (struct sockaddr*)&addr, &alen);		if (r) {			SignalError("java.net.SocketException", SYS_ERROR(r));		}		port = ntohs(addr.addr4.sin_port);	}	unhand(this)->localPort = port;DBG(NATIVENET,	dprintf("  datagram_bind(%p, %s, -) -> (localPort: %d)\n",		this, ip2str(addr.addr4.sin_addr.s_addr), port);)}voidgnu_java_net_PlainDatagramSocketImpl_send(struct Hgnu_java_net_PlainDatagramSocketImpl* this, struct Hjava_net_DatagramPacket* pkt){	int rc;	ssize_t bsent;	KaffeSocketAddr addr;	int alen;	DBG(NATIVENET,	dprintf("datagram_send(%p, %p [%d bytes])\n",		this, pkt, unhand(pkt)->length);)        memset(&addr, 0, sizeof(addr));        if (obj_length(unhand(unhand(pkt)->address)->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(unhand(pkt)->port);	    memcpy(&addr.addr4.sin_addr.s_addr, unhand_byte_array(unhand(unhand(pkt)->address)->addr),		   4);DBG(NATIVENET,	dprintf("  datagram_send() to %s:%d\n",		ip2str(ntohl(addr.addr4.sin_addr.s_addr)),		unhand(pkt)->port);)#if defined(HAVE_STRUCT_SOCKADDR_IN6)	} else if (obj_length(unhand(unhand(pkt)->address)->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(unhand(pkt)->port);	    memcpy(&addr.addr6.sin6_addr, unhand_byte_array(unhand(unhand(pkt)->address)->addr),		   sizeof(addr.addr6.sin6_addr));	    DBG(NATIVENET,	dprintf("  datagram_send() to %s / %d\n",		ip62str(&addr.addr6.sin6_addr),		unhand(pkt)->port);)#endif /* defined(HAVE_STRUCT_SOCKADDR_IN6) */        } else {	    SignalError("java.net.SocketException", "Unsupported packet internet address");	}	rc = KSENDTO(unhand(unhand(this)->fd)->nativeFd,		unhand_array(unhand(pkt)->buffer)->body, unhand(pkt)->length,		0, (struct sockaddr *)&addr, alen, &bsent);DBG(NATIVENET,	dprintf("  datagram_send() -> rc=%d bsent=%ld\n", rc, (long) bsent);)	if (rc) {		SignalError("java.net.SocketException", SYS_ERROR(rc));	}}jintgnu_java_net_PlainDatagramSocketImpl_peek(struct Hgnu_java_net_PlainDatagramSocketImpl* this, struct Hjava_net_InetAddress* addr){	ssize_t r;	int rc;	KaffeSocketAddr saddr;	int alen = sizeof(saddr);	rc = KRECVFROM(unhand(unhand(this)->fd)->nativeFd,		0, 0, MSG_PEEK, (struct sockaddr*)&saddr,		&alen, NOTIMEOUT /* timeout */, &r);	if (rc) {		SignalError("java.net.SocketException", SYS_ERROR(rc));	}	if (saddr.addr4.sin_family == AF_INET) {	    memcpy(unhand_byte_array(unhand(addr)->addr), &saddr.addr4.sin_addr, sizeof(saddr.addr4.sin_addr));#if defined(HAVE_STRUCT_SOCKADDR_IN6)	} else if (saddr.addr6.sin6_family == AF_INET6) {	    memcpy(unhand_byte_array(unhand(addr)->addr), &saddr.addr6.sin6_addr, sizeof(saddr.addr6.sin6_addr));#endif /*  defined(HAVE_STRUCT_SOCKADDR_IN6) */	} else {	    SignalError("java.net.SocketException", "Unsupported address family");	}	return ((jint)r);}voidgnu_java_net_PlainDatagramSocketImpl_receive(struct Hgnu_java_net_PlainDatagramSocketImpl* this, struct Hjava_net_DatagramPacket* pkt){	ssize_t r;	int rc;	KaffeSocketAddr addr;	int alen = sizeof(addr);	HArrayOfByte *array_address;	int to_read, offset;	assert(this != NULL);	if (pkt == NULL || unhand(pkt)->buffer == NULL)		SignalError("java.lang.NullPointerException", "null datagram packet");	assert(unhand(pkt)->length <= unhand(unhand(pkt)->buffer)->length);DBG(NATIVENET,	dprintf("datagram_receive(%p, %p [%d bytes])\n",		this, pkt, unhand(pkt)->length);)	/* Which port am I receiving from */	addr.addr4.sin_port = htons(unhand(this)->localPort);	/* XXX should assert (unhand(pkt)->length <= unhand_array(unhand(pkt)->buf)->length), no? */        offset = unhand(pkt)->offset; 	to_read = unhand(pkt)->length;        do { 	        rc = KRECVFROM(unhand(unhand(this)->fd)->nativeFd,			       &(unhand_array(unhand(pkt)->buffer)->body)[offset],			       to_read, 0, (struct sockaddr*)&addr,			       &alen, unhand(this)->timeout, &r);		switch( rc )		{		case 0:		        break;		case ETIMEDOUT: {		        struct Hjava_io_InterruptedIOException* except;		  			except = (struct Hjava_io_InterruptedIOException *)			  execute_java_constructor(						   "java.net.SocketTimeoutException", 0, 0,						   "(Ljava/lang/String;)V",						   checkPtr(stringC2Java("Read timed out")));			except->bytesTransferred = offset-unhand(pkt)->offset;						throwException((struct Hjava_lang_Throwable*)except);			break;		}		case EINTR:		        break;		default:		        SignalError("java.net.SocketException", SYS_ERROR(rc));			break;		}		to_read -= r;		offset += r;	} while (rc == EINTR);	unhand(pkt)->length = r;	unhand(pkt)->port = ntohs(addr.addr4.sin_port);	if (addr.addr4.sin_family == AF_INET) {		array_address = (HArrayOfByte*)AllocArray(sizeof(addr.addr4.sin_addr), TYPE_Byte);		memcpy(unhand_byte_array(array_address), &addr.addr4.sin_addr, sizeof(addr.addr4.sin_addr));				unhand(pkt)->address = (struct Hjava_net_InetAddress*)			execute_java_constructor("java/net/InetAddress", 0, 0, "([B)V",						 array_address);#if defined(HAVE_STRUCT_SOCKADDR_IN6)	} else if (addr.addr6.sin6_family == AF_INET6) {		array_address = (HArrayOfByte*)AllocArray(sizeof(addr.addr6.sin6_addr), TYPE_Byte);

⌨️ 快捷键说明

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