int dbgsysFinishConnect(int fd, long timeout) { int rv = dbgsysPoll(fd, 0, 1, timeout); if (rv == 0) { return DBG_ETIMEOUT; } if (rv > 0) { return 0; } return rv; }
static jdwpTransportError handshake(int fd, jlong timeout) { const char *hello = "JDWP-Handshake"; char b[16]; int rv, helloLen, received; if (timeout > 0) { dbgsysConfigureBlocking(fd, JNI_FALSE); } helloLen = (int)strlen(hello); received = 0; while (received < helloLen) { 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 = recv_fully(fd, buf, helloLen-received); 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); } if (strncmp(b, hello, received) != 0) { char msg[80+2*16]; b[received] = '\0'; /* * We should really use snprintf here but it's not available on Windows. * We can't use jio_snprintf without linking the transport against the VM. */ sprintf(msg, "handshake failed - received >%s< - expected >%s<", b, hello); setLastError(0, msg); return JDWPTRANSPORT_ERROR_IO_ERROR; } if (send_fully(fd, (char*)hello, helloLen) != helloLen) { RETURN_IO_ERROR("send failed during handshake"); } 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 jdwpTransportError JNICALL socketTransport_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 * is a handshake timeout set then it will go into non-blocking mode * anyway for the handshake. */ if (acceptTimeout > 0) { dbgsysConfigureBlocking(serverSocketFD, JNI_TRUE); } if (socketFD < 0) { return JDWPTRANSPORT_ERROR_IO_ERROR; } /* handshake with the debugger */ err = handshake(socketFD, handshakeTimeout); /* * If the handshake fails then close the connection. If there if an accept * timeout then we must adjust the timeout for the next poll. */ if (err) { fprintf(stderr, "Debugger failed to attach: %s\n", getLastError()); dbgsysSocketClose(socketFD); socketFD = -1; if (acceptTimeout > 0) { long endTime = dbgsysCurrentTimeMillis(); acceptTimeout -= (endTime - startTime); if (acceptTimeout <= 0) { setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, "timeout waiting for debugger to connect"); return JDWPTRANSPORT_ERROR_IO_ERROR; } } } } while (socketFD < 0); return JDWPTRANSPORT_ERROR_NONE; }