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; }
jint send_fully(int f, char *buf, int len) { int nbytes = 0; while (nbytes < len) { int res = dbgsysSend(f, buf + nbytes, len - nbytes, 0); if (res < 0) { if (errno == EINTR) continue; return res; } else if (res == 0) { break; /* eof, return nbytes which is less than len */ } nbytes += res; } return nbytes; }
static jdwpTransportError JNICALL socketTransport_writePacket(jdwpTransportEnv* env, const jdwpPacket *packet) { jint len, data_len, id; /* * room for header and up to MAX_DATA_SIZE data bytes */ char header[HEADER_SIZE + MAX_DATA_SIZE]; jbyte *data; /* packet can't be null */ if (packet == NULL) { RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is NULL"); } len = packet->type.cmd.len; /* includes header */ data_len = len - HEADER_SIZE; /* bad packet */ if (data_len < 0) { RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "invalid length"); } /* prepare the header for transmission */ len = (jint)dbgsysHostToNetworkLong(len); id = (jint)dbgsysHostToNetworkLong(packet->type.cmd.id); memcpy(header + 0, &len, 4); memcpy(header + 4, &id, 4); header[8] = packet->type.cmd.flags; if (packet->type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) { jshort errorCode = dbgsysHostToNetworkShort(packet->type.reply.errorCode); memcpy(header + 9, &errorCode, 2); } else { header[9] = packet->type.cmd.cmdSet; header[10] = packet->type.cmd.cmd; } data = packet->type.cmd.data; /* Do one send for short packets, two for longer ones */ if (data_len <= MAX_DATA_SIZE) { memcpy(header + HEADER_SIZE, data, data_len); if (dbgsysSend(socketFD, (char *)&header, HEADER_SIZE + data_len, 0) != HEADER_SIZE + data_len) { RETURN_IO_ERROR("send failed"); } } else { memcpy(header + HEADER_SIZE, data, MAX_DATA_SIZE); if (dbgsysSend(socketFD, (char *)&header, HEADER_SIZE + MAX_DATA_SIZE, 0) != HEADER_SIZE + MAX_DATA_SIZE) { RETURN_IO_ERROR("send failed"); } /* Send the remaining data bytes right out of the data area. */ if (dbgsysSend(socketFD, (char *)data + MAX_DATA_SIZE, data_len - MAX_DATA_SIZE, 0) != data_len - MAX_DATA_SIZE) { RETURN_IO_ERROR("send failed"); } } return JDWPTRANSPORT_ERROR_NONE; }