sockettransport.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 754 行 · 第 1/2 页
C
754 行
/* * @(#)socketTransport.c 1.34 06/10/26 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */#include <stdio.h>#include <string.h>#include <errno.h>#include <stdlib.h>#include <ctype.h>#include "jdwpTransport.h"#include "sysSocket.h"#include "JDWP.h"/* * The Socket Transport Library. * * This module is an implementation of the Java Debug Wire Protocol Transport * Service Provider Interface - see src/share/javavm/export/jdwpTransport.h. */static int serverSocketFD = -1;static int socketFD = -1;static jdwpTransportCallback *callback;static JavaVM *jvm;static int tlsIndex;static jboolean initialized;static struct jdwpTransportNativeInterface_ jdwpInterface;static jdwpTransportEnv single_env = (jdwpTransportEnv)&jdwpInterface;#define RETURN_ERROR(err, msg) \ if (1==1) { \ setLastError(err, msg); \ return err; \ } #define RETURN_IO_ERROR(msg) RETURN_ERROR(JDWPTRANSPORT_ERROR_IO_ERROR, msg);#define RETURN_RECV_ERROR(n) \ if (n == 0) { \ RETURN_ERROR(JDWPTRANSPORT_ERROR_IO_ERROR, "premature EOF"); \ } else { \ RETURN_IO_ERROR("recv error"); \ } #define HEADER_SIZE 11#define MAX_DATA_SIZE 1000/* * Record the last error for this thread. */static voidsetLastError(jdwpTransportError err, char *newmsg) { char buf[255]; char *msg; /* get any I/O first in case any system calls override errno */ if (err == JDWPTRANSPORT_ERROR_IO_ERROR) { dbgsysGetLastIOError(buf, sizeof(buf)); } msg = (char *)dbgsysTlsGet(tlsIndex); if (msg != NULL) { (*callback->free)(msg); } if (err == JDWPTRANSPORT_ERROR_IO_ERROR) { char *join_str = ": "; int msg_len = strlen(newmsg) + strlen(join_str) + strlen(buf) + 3; msg = (*callback->alloc)(msg_len); if (msg != NULL) { strcpy(msg, newmsg); strcat(msg, join_str); strcat(msg, buf); } } else { msg = (*callback->alloc)(strlen(newmsg)+1); if (msg != NULL) { strcpy(msg, newmsg); } } dbgsysTlsPut(tlsIndex, msg);}/* * Return the last error for this thread (may be NULL) */static char*getLastError() { return (char *)dbgsysTlsGet(tlsIndex); }static jdwpTransportError setOptions(int fd) { jvalue dontcare = {0}; int err; dontcare.i = 0; /* keep compiler happy */ err = dbgsysSetSocketOption(fd, SO_REUSEADDR, JNI_TRUE, dontcare); if (err < 0) { RETURN_IO_ERROR("setsockopt SO_REUSEADDR failed"); } err = dbgsysSetSocketOption(fd, TCP_NODELAY, JNI_TRUE, dontcare); if (err < 0) { RETURN_IO_ERROR("setsockopt TCPNODELAY failed"); } return JDWPTRANSPORT_ERROR_NONE;}static jdwpTransportError handshake(int fd, jlong timeout) { char *hello = "JDWP-Handshake"; char b[16]; int rv, received, i; if (timeout > 0) { dbgsysConfigureBlocking(fd, JNI_FALSE); } received = 0; while (received < (int)strlen(hello)) { int n; char *buf; if (timeout > 0) { rv = dbgsysPoll(fd, JNI_TRUE, JNI_FALSE, (long)timeout); if (rv <= 0) { setLastError(0, "timeout during handshake"); return JDWPTRANSPORT_ERROR_IO_ERROR; } } buf = b; buf += received; n = dbgsysRecv(fd, buf, strlen(hello)-received, 0); if (n == 0) { setLastError(0, "handshake failed - connection prematurally closed"); return JDWPTRANSPORT_ERROR_IO_ERROR; } if (n < 0) { RETURN_IO_ERROR("recv failed during handshake"); } received += n; } if (timeout > 0) { dbgsysConfigureBlocking(fd, JNI_TRUE); } for (i=0; i<(int)strlen(hello); i++) { if (b[i] != hello[i]) { char msg[64]; strcpy(msg, "handshake failed - received >"); strncat(msg, b, strlen(hello)); strcat(msg, "< - excepted >"); strcat(msg, hello); strcat(msg, "<"); setLastError(0, msg); return JDWPTRANSPORT_ERROR_IO_ERROR; } } if (dbgsysSend(fd, hello, strlen(hello), 0) != (int)strlen(hello)) { RETURN_IO_ERROR("send failed during handshake"); } return JDWPTRANSPORT_ERROR_NONE;}static jdwpTransportErrorparseAddress(const char *address, struct sockaddr_in *sa, U_SOCKINT32 defaultHost) { char *colon; memset((void *)sa,0,sizeof(struct sockaddr_in)); sa->sin_family = AF_INET; /* check for host:port or port */ colon = strchr(address, ':'); if (colon == NULL) { u_short port = (u_short)atoi(address); sa->sin_port = dbgsysHostToNetworkShort(port); sa->sin_addr.s_addr = dbgsysHostToNetworkLong(defaultHost); } else { char *buf; char *hostname; u_short port; U_SOCKINT32 addr; buf = (*callback->alloc)(strlen(address)+1); if (buf == NULL) { RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory"); } strcpy(buf, address); buf[colon - address] = '\0'; hostname = buf; port = atoi(colon + 1); sa->sin_port = dbgsysHostToNetworkShort(port); /* * First see if the host is a literal IP address. * If not then try to resolve it. */ addr = dbgsysInetAddr(hostname); if (addr == 0xffffffff) { struct hostent *hp = dbgsysGetHostByName(hostname); if (hp == NULL) { /* don't use RETURN_IO_ERROR as unknown host is normal */ setLastError(0, "gethostbyname: unknown host"); (*callback->free)(buf); return JDWPTRANSPORT_ERROR_IO_ERROR; } /* lookup was successful */ memcpy(&(sa->sin_addr), hp->h_addr_list[0], hp->h_length); } else { sa->sin_addr.s_addr = addr; } (*callback->free)(buf); } return JDWPTRANSPORT_ERROR_NONE;}static jdwpTransportError JNICALLsocketTransport_getCapabilities(jdwpTransportEnv* env, JDWPTransportCapabilities* capabilitiesPtr) { JDWPTransportCapabilities result; memset(&result, 0, sizeof(result)); result.can_timeout_attach = JNI_TRUE; result.can_timeout_accept = JNI_TRUE; result.can_timeout_handshake = JNI_TRUE; *capabilitiesPtr = result; return JDWPTRANSPORT_ERROR_NONE;}static jdwpTransportError JNICALLsocketTransport_startListening(jdwpTransportEnv* env, const char* address, char** actualAddress){ struct sockaddr_in sa; int err; memset((void *)&sa,0,sizeof(struct sockaddr_in)); sa.sin_family = AF_INET; /* no address provided */ if ((address == NULL) || (address[0] == '\0')) { address = "0"; } err = parseAddress(address, &sa, INADDR_ANY); if (err != JDWPTRANSPORT_ERROR_NONE) { return err; } serverSocketFD = dbgsysSocket(AF_INET, SOCK_STREAM, 0); if (serverSocketFD < 0) { RETURN_IO_ERROR("socket creation failed"); } err = setOptions(serverSocketFD); if (err) { return err; } err = dbgsysBind(serverSocketFD, (struct sockaddr *)&sa, sizeof(sa)); if (err < 0) { RETURN_IO_ERROR("bind failed"); } err = dbgsysListen(serverSocketFD, 1); if (err < 0) { RETURN_IO_ERROR("listen failed"); } { char buf[20]; int len = sizeof(sa); jint portNum; err = dbgsysGetSocketName(serverSocketFD, (struct sockaddr *)&sa, &len); portNum = dbgsysNetworkToHostShort(sa.sin_port); sprintf(buf, "%d", portNum); *actualAddress = (*callback->alloc)(strlen(buf) + 1); if (*actualAddress == NULL) { RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory"); } else { strcpy(*actualAddress, buf); } } return JDWPTRANSPORT_ERROR_NONE;}static jdwpTransportError JNICALLsocketTransport_accept(jdwpTransportEnv* env, jlong acceptTimeout, jlong handshakeTimeout) { int socketLen, err; struct sockaddr_in socket; jlong startTime = (jlong)0; /* * Use a default handshake timeout if not specified - this avoids an indefinite * hang in cases where something other than a debugger connects to our port. */ if (handshakeTimeout == 0) { handshakeTimeout = 2000; } do { /* * If there is an accept timeout then we put the socket in non-blocking * mode and poll for a connection. */ if (acceptTimeout > 0) { int rv; dbgsysConfigureBlocking(serverSocketFD, JNI_FALSE); startTime = dbgsysCurrentTimeMillis(); rv = dbgsysPoll(serverSocketFD, JNI_TRUE, JNI_FALSE, (long)acceptTimeout); if (rv <= 0) { /* set the last error here as could be overridden by configureBlocking */ if (rv == 0) { setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, "poll failed"); } /* restore blocking state */ dbgsysConfigureBlocking(serverSocketFD, JNI_TRUE); if (rv == 0) { RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "timed out waiting for connection"); } else { return JDWPTRANSPORT_ERROR_IO_ERROR; } } } /* * Accept the connection */ memset((void *)&socket,0,sizeof(struct sockaddr_in)); socketLen = sizeof(socket); socketFD = dbgsysAccept(serverSocketFD, (struct sockaddr *)&socket, &socketLen); /* set the last error here as could be overridden by configureBlocking */ if (socketFD < 0) { setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, "accept failed"); } /* * Restore the blocking state - note that the accepted socket may be in * blocking or non-blocking mode (platform dependent). However as there
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?