*
* We only talk to one debugger at a time.
*/
-struct JdwpNetState {
+struct JdwpNetState : public JdwpNetStateBase {
short listenPort;
int listenSock; /* listen for connection from debugger */
- int clientSock; /* active connection to debugger */
int wakePipe[2]; /* break out of select */
struct in_addr remoteAddr;
/* pending data from the network; would be more efficient as circular buf */
unsigned char inputBuffer[kInputBufferSize];
int inputCount;
+
+ JdwpNetState()
+ {
+ listenPort = 0;
+ listenSock = -1;
+ wakePipe[0] = -1;
+ wakePipe[1] = -1;
+
+ awaitingHandshake = false;
+
+ inputCount = 0;
+ }
};
static JdwpNetState* netStartup(short port);
}
}
if (state->netState == NULL) {
- LOGE("JDWP net startup failed (req port=%d)\n", pParams->port);
+ ALOGE("JDWP net startup failed (req port=%d)", pParams->port);
return false;
}
} else {
}
if (pParams->suspend)
- LOGI("JDWP will wait for debugger on port %d\n", port);
+ ALOGI("JDWP will wait for debugger on port %d", port);
else
- LOGD("JDWP will %s on port %d\n",
+ ALOGD("JDWP will %s on port %d",
pParams->server ? "listen" : "connect", port);
return true;
*/
static JdwpNetState* netStartup(short port)
{
- JdwpNetState* netState;
int one = 1;
-
- netState = (JdwpNetState*) malloc(sizeof(*netState));
- memset(netState, 0, sizeof(*netState));
- netState->listenSock = -1;
- netState->clientSock = -1;
- netState->wakePipe[0] = -1;
- netState->wakePipe[1] = -1;
+ JdwpNetState* netState = new JdwpNetState;
if (port < 0)
return netState;
netState->listenSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (netState->listenSock < 0) {
- LOGE("Socket create failed: %s\n", strerror(errno));
+ ALOGE("Socket create failed: %s", strerror(errno));
goto fail;
}
if (setsockopt(netState->listenSock, SOL_SOCKET, SO_REUSEADDR, &one,
sizeof(one)) < 0)
{
- LOGE("setsockopt(SO_REUSEADDR) failed: %s\n", strerror(errno));
+ ALOGE("setsockopt(SO_REUSEADDR) failed: %s", strerror(errno));
goto fail;
}
inet_aton("127.0.0.1", &addr.addrInet.sin_addr);
if (bind(netState->listenSock, &addr.addrPlain, sizeof(addr)) != 0) {
- LOGV("attempt to bind to port %u failed: %s\n", port, strerror(errno));
+ ALOGV("attempt to bind to port %u failed: %s", port, strerror(errno));
goto fail;
}
netState->listenPort = port;
- LOGVV("+++ bound to port %d\n", netState->listenPort);
+ LOGVV("+++ bound to port %d", netState->listenPort);
if (listen(netState->listenSock, 5) != 0) {
- LOGE("Listen failed: %s\n", strerror(errno));
+ ALOGE("Listen failed: %s", strerror(errno));
goto fail;
}
/* if we might be sitting in select, kick us loose */
if (netState->wakePipe[1] >= 0) {
- LOGV("+++ writing to wakePipe\n");
- (void) write(netState->wakePipe[1], "", 1);
+ ALOGV("+++ writing to wakePipe");
+ TEMP_FAILURE_RETRY(write(netState->wakePipe[1], "", 1));
}
}
static void netShutdownExtern(JdwpState* state)
netState->wakePipe[1] = -1;
}
- free(netState);
+ delete netState;
}
static void netFreeExtern(JdwpState* state)
{
if (FD_ISSET(sock, &readfds)) /* make sure it's our fd */
return true;
- LOGE("WEIRD: odd behavior in select (count=%d)\n", count);
+ ALOGE("WEIRD: odd behavior in select (count=%d)", count);
return false;
}
#endif
// When we call shutdown() on the socket, accept() returns with
// EINVAL. Don't gripe about it.
if (errno == EINVAL)
- LOGVV("accept failed: %s\n", strerror(errno));
+ LOGVV("accept failed: %s", strerror(errno));
else
- LOGE("accept failed: %s\n", strerror(errno));
+ ALOGE("accept failed: %s", strerror(errno));
return false;
}
} while (sock < 0);
netState->remoteAddr = addr.addrInet.sin_addr;
netState->remotePort = ntohs(addr.addrInet.sin_port);
- LOGV("+++ accepted connection from %s:%u\n",
+ ALOGV("+++ accepted connection from %s:%u",
inet_ntoa(netState->remoteAddr), netState->remotePort);
netState->clientSock = sock;
netState->awaitingHandshake = true;
netState->inputCount = 0;
- LOGV("Setting TCP_NODELAY on accepted socket\n");
+ ALOGV("Setting TCP_NODELAY on accepted socket");
setNoDelay(netState->clientSock);
if (pipe(netState->wakePipe) < 0) {
- LOGE("pipe failed");
+ ALOGE("pipe failed");
return false;
}
int cc = gethostbyname_r(state->params.host, &he, auxBuf, sizeof(auxBuf),
&pEntry, &h_errno);
if (cc != 0) {
- LOGW("gethostbyname_r('%s') failed: %s\n",
+ ALOGW("gethostbyname_r('%s') failed: %s",
state->params.host, strerror(errno));
return false;
}
h_errno = 0;
pEntry = gethostbyname(state->params.host);
if (pEntry == NULL) {
- LOGW("gethostbyname('%s') failed: %s\n",
+ ALOGW("gethostbyname('%s') failed: %s",
state->params.host, strerror(h_errno));
return false;
}
addr.addrInet.sin_port = htons(state->params.port);
- LOGI("Connecting out to '%s' %d\n",
+ ALOGI("Connecting out to '%s' %d",
inet_ntoa(addr.addrInet.sin_addr), ntohs(addr.addrInet.sin_port));
/*
netState = state->netState;
netState->clientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (netState->clientSock < 0) {
- LOGE("Unable to create socket: %s\n", strerror(errno));
+ ALOGE("Unable to create socket: %s", strerror(errno));
return false;
}
* Try to connect.
*/
if (connect(netState->clientSock, &addr.addrPlain, sizeof(addr)) != 0) {
- LOGE("Unable to connect to %s:%d: %s\n",
+ ALOGE("Unable to connect to %s:%d: %s",
inet_ntoa(addr.addrInet.sin_addr), ntohs(addr.addrInet.sin_port),
strerror(errno));
close(netState->clientSock);
return false;
}
- LOGI("Connection established to %s (%s:%d)\n",
+ ALOGI("Connection established to %s (%s:%d)",
state->params.host, inet_ntoa(addr.addrInet.sin_addr),
ntohs(addr.addrInet.sin_port));
netState->awaitingHandshake = true;
setNoDelay(netState->clientSock);
if (pipe(netState->wakePipe) < 0) {
- LOGE("pipe failed");
+ ALOGE("pipe failed");
return false;
}
if (netState->clientSock < 0)
return;
- LOGV("+++ closed connection to %s:%u\n",
+ ALOGV("+++ closed connection to %s:%u",
inet_ntoa(netState->remoteAddr), netState->remotePort);
close(netState->clientSock);
dataLen = length - (buf - packetBuf);
- LOGV("--- %s: dataLen=%u id=0x%08x flags=0x%02x cmd=%d/%d\n",
+ ALOGV("--- %s: dataLen=%u id=0x%08x flags=0x%02x cmd=%d/%d",
reply ? "reply" : "req",
dataLen, id, flags, cmdSet, cmd);
if (dataLen > 0)
hdr.cmd = cmd;
dvmJdwpProcessRequest(state, &hdr, buf, dataLen, pReply);
if (expandBufGetLength(pReply) > 0) {
- int cc;
+ ssize_t cc = netState->writePacket(pReply);
- /*
- * TODO: we currently assume the write() will complete in one
- * go, which may not be safe for a network socket. We may need
- * to mutex this against sendRequest().
- */
- cc = write(netState->clientSock, expandBufGetBuffer(pReply),
- expandBufGetLength(pReply));
- if (cc != (int) expandBufGetLength(pReply)) {
- LOGE("Failed sending reply to debugger: %s\n", strerror(errno));
+ if (cc != (ssize_t) expandBufGetLength(pReply)) {
+ ALOGE("Failed sending reply to debugger: %s", strerror(errno));
expandBufFree(pReply);
return false;
}
} else {
- LOGW("No reply created for set=%d cmd=%d\n", cmdSet, cmd);
+ ALOGW("No reply created for set=%d cmd=%d", cmdSet, cmd);
}
expandBufFree(pReply);
} else {
- LOGV("reply?!\n");
+ ALOGV("reply?!");
assert(false);
}
- LOGV("----------\n");
+ ALOGV("----------");
consumeBytes(netState, length);
return true;
maxfd = netState->wakePipe[0];
if (maxfd < 0) {
- LOGV("+++ all fds are closed\n");
+ ALOGV("+++ all fds are closed");
return false;
}
if (fd >= 0) {
FD_SET(fd, &readfds);
} else {
- LOGI("NOTE: entering select w/o wakepipe\n");
+ ALOGI("NOTE: entering select w/o wakepipe");
}
/*
if (selCount < 0) {
if (errno == EINTR)
continue;
- LOGE("select failed: %s\n", strerror(errno));
+ ALOGE("select failed: %s", strerror(errno));
goto fail;
}
FD_ISSET(netState->wakePipe[0], &readfds))
{
if (netState->listenSock >= 0)
- LOGE("Exit wake set, but not exiting?\n");
+ ALOGE("Exit wake set, but not exiting?");
else
- LOGD("Got wake-up signal, bailing out of select\n");
+ ALOGD("Got wake-up signal, bailing out of select");
goto fail;
}
if (netState->listenSock >= 0 &&
FD_ISSET(netState->listenSock, &readfds))
{
- LOGI("Ignoring second debugger -- accepting and dropping\n");
+ ALOGI("Ignoring second debugger -- accepting and dropping");
union {
struct sockaddr_in addrInet;
struct sockaddr addrPlain;
tmpSock = accept(netState->listenSock, &addr.addrPlain,
&addrlen);
if (tmpSock < 0)
- LOGI("Weird -- accept failed\n");
+ ALOGI("Weird -- accept failed");
else
close(tmpSock);
}
/* read failed */
if (errno != EINTR)
goto fail;
- LOGD("+++ EINTR hit\n");
+ ALOGD("+++ EINTR hit");
return true;
} else if (readCount == 0) {
/* EOF hit -- far end went away */
- LOGD("+++ peer disconnected\n");
+ ALOGD("+++ peer disconnected");
goto fail;
} else
break;
if (memcmp(netState->inputBuffer,
kMagicHandshake, kMagicHandshakeLen) != 0)
{
- LOGE("ERROR: bad handshake '%.14s'\n", netState->inputBuffer);
+ ALOGE("ERROR: bad handshake '%.14s'", netState->inputBuffer);
goto fail;
}
errno = 0;
- cc = write(netState->clientSock, netState->inputBuffer,
- kMagicHandshakeLen);
+ cc = TEMP_FAILURE_RETRY(write(netState->clientSock, netState->inputBuffer,
+ kMagicHandshakeLen));
if (cc != kMagicHandshakeLen) {
- LOGE("Failed writing handshake bytes: %s (%d of %d)\n",
+ ALOGE("Failed writing handshake bytes: %s (%d of %d)",
strerror(errno), cc, (int) kMagicHandshakeLen);
goto fail;
}
consumeBytes(netState, kMagicHandshakeLen);
netState->awaitingHandshake = false;
- LOGV("+++ handshake complete\n");
+ ALOGV("+++ handshake complete");
return true;
}
static bool sendRequest(JdwpState* state, ExpandBuf* pReq)
{
JdwpNetState* netState = state->netState;
- int cc;
/*dumpPacket(expandBufGetBuffer(pReq));*/
if (netState->clientSock < 0) {
/* can happen with some DDMS events */
- LOGV("NOT sending request -- no debugger is attached\n");
+ ALOGV("NOT sending request -- no debugger is attached");
return false;
}
- /*
- * TODO: we currently assume the write() will complete in one
- * go, which may not be safe for a network socket. We may need
- * to mutex this against handlePacket().
- */
errno = 0;
- cc = write(netState->clientSock, expandBufGetBuffer(pReq),
- expandBufGetLength(pReq));
- if (cc != (int) expandBufGetLength(pReq)) {
- LOGE("Failed sending req to debugger: %s (%d of %d)\n",
- strerror(errno), cc, (int) expandBufGetLength(pReq));
+ ssize_t cc = netState->writePacket(pReq);
+
+ if (cc != (ssize_t) expandBufGetLength(pReq)) {
+ ALOGE("Failed sending req to debugger: %s (%d of %d)",
+ strerror(errno), (int) cc, (int) expandBufGetLength(pReq));
return false;
}
if (netState->clientSock < 0) {
/* can happen with some DDMS events */
- LOGV("NOT sending request -- no debugger is attached\n");
+ ALOGV("NOT sending request -- no debugger is attached");
return false;
}
for (i = 0; i < iovcnt; i++)
expected += iov[i].iov_len;
- /*
- * TODO: we currently assume the writev() will complete in one
- * go, which may not be safe for a network socket. We may need
- * to mutex this against handlePacket().
- */
- ssize_t actual;
- actual = writev(netState->clientSock, iov, iovcnt);
+ ssize_t actual = netState->writeBufferedPacket(iov, iovcnt);
+
if ((size_t)actual != expected) {
- LOGE("Failed sending b-req to debugger: %s (%d of %zu)\n",
+ ALOGE("Failed sending b-req to debugger: %s (%d of %zu)",
strerror(errno), (int) actual, expected);
return false;
}