#define kJdwpControlName "\0jdwp-control"
#define kJdwpControlNameLen (sizeof(kJdwpControlName)-1)
-struct JdwpNetState {
+struct JdwpNetState : public JdwpNetStateBase {
int controlSock;
- int clientSock;
bool awaitingHandshake;
bool shuttingDown;
int wakeFds[2];
struct sockaddr_un controlAddrUn;
struct sockaddr controlAddrPlain;
} controlAddr;
+
+ JdwpNetState()
+ {
+ controlSock = -1;
+ awaitingHandshake = false;
+ shuttingDown = false;
+ wakeFds[0] = -1;
+ wakeFds[1] = -1;
+
+ inputCount = 0;
+
+ controlAddr.controlAddrUn.sun_family = AF_UNIX;
+ controlAddrLen = sizeof(controlAddr.controlAddrUn.sun_family) +
+ kJdwpControlNameLen;
+ memcpy(controlAddr.controlAddrUn.sun_path, kJdwpControlName,
+ kJdwpControlNameLen);
+ }
};
static void
netState->wakeFds[1] = -1;
}
- free(netState);
-}
-
-
-static JdwpNetState* adbStateAlloc()
-{
- JdwpNetState* netState = (JdwpNetState*) calloc(sizeof(*netState),1);
-
- netState->controlSock = -1;
- netState->clientSock = -1;
-
- netState->controlAddr.controlAddrUn.sun_family = AF_UNIX;
- netState->controlAddrLen =
- sizeof(netState->controlAddr.controlAddrUn.sun_family) +
- kJdwpControlNameLen;
-
- memcpy(netState->controlAddr.controlAddrUn.sun_path,
- kJdwpControlName, kJdwpControlNameLen);
-
- netState->wakeFds[0] = -1;
- netState->wakeFds[1] = -1;
-
- return netState;
+ delete netState;
}
-
/*
* Do initial prep work, e.g. binding to ports and opening files. This
* runs in the main thread, before the JDWP thread starts, so it shouldn't
{
JdwpNetState* netState;
- LOGV("ADB transport startup\n");
+ ALOGV("ADB transport startup");
- state->netState = netState = adbStateAlloc();
+ state->netState = netState = new JdwpNetState;
if (netState == NULL)
return false;
if (ret <= 0) {
if (ret < 0) {
- LOGW("receiving file descriptor from ADB failed (socket %d): %s\n",
+ ALOGW("receiving file descriptor from ADB failed (socket %d): %s",
netState->controlSock, strerror(errno));
- } else {
- LOGD("adbd disconnected\n");
}
close(netState->controlSock);
netState->controlSock = -1;
netState->controlSock = socket(PF_UNIX, SOCK_STREAM, 0);
if (netState->controlSock < 0) {
- LOGE("Could not create ADB control socket:%s\n",
+ ALOGE("Could not create ADB control socket:%s",
strerror(errno));
return false;
}
if (pipe(netState->wakeFds) < 0) {
- LOGE("pipe failed");
+ ALOGE("pipe failed");
return false;
}
if (!ret) {
if (!socket_peer_is_trusted(netState->controlSock)) {
if (shutdown(netState->controlSock, SHUT_RDWR)) {
- LOGE("trouble shutting down socket: %s", strerror(errno));
+ ALOGE("trouble shutting down socket: %s", strerror(errno));
}
return false;
}
} while (ret < 0 && errno == EINTR);
if (ret >= 0) {
- LOGV("PID sent as '%.*s' to ADB\n", 4, buff);
+ ALOGV("PID sent as '%.*s' to ADB", 4, buff);
break;
}
- LOGE("Weird, can't send JDWP process pid to ADB: %s\n",
+ ALOGE("Weird, can't send JDWP process pid to ADB: %s",
strerror(errno));
return false;
}
- LOGV("Can't connect to ADB control socket:%s\n",
+ ALOGV("Can't connect to ADB control socket:%s",
strerror(errno));
usleep( sleep_ms*1000 );
sleep_ms += (sleep_ms >> 1);
if (sleep_ms > sleep_max_ms)
sleep_ms = sleep_max_ms;
+
+ if (netState->shuttingDown)
+ return false;
}
}
- LOGV("trying to receive file descriptor from ADB\n");
+ ALOGV("trying to receive file descriptor from ADB");
/* now we can receive a client file descriptor */
netState->clientSock = receiveClientFd(netState);
if (netState->shuttingDown)
if (netState->clientSock < 0) {
if (++retryCount > 5) {
- LOGE("adb connection max retries exceeded\n");
+ ALOGE("adb connection max retries exceeded");
return false;
}
goto retry;
} else {
- LOGV("received file descriptor %d from ADB\n", netState->clientSock);
+ ALOGV("received file descriptor %d from ADB", netState->clientSock);
netState->awaitingHandshake = 1;
netState->inputCount = 0;
return true;
if (netState->clientSock < 0)
return;
- LOGV("+++ closed JDWP <-> ADB connection\n");
+ ALOGV("+++ closed JDWP <-> ADB connection");
close(netState->clientSock);
netState->clientSock = -1;
}
if (netState->wakeFds[1] >= 0) {
- LOGV("+++ writing to wakePipe\n");
- write(netState->wakeFds[1], "", 1);
+ ALOGV("+++ writing to wakePipe");
+ TEMP_FAILURE_RETRY(write(netState->wakeFds[1], "", 1));
}
}
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;
if (maxfd < fd)
maxfd = fd;
} else {
- LOGI("NOTE: entering select w/o wakepipe\n");
+ ALOGI("NOTE: entering select w/o wakepipe");
}
if (maxfd < 0) {
- LOGV("+++ all fds are closed\n");
+ ALOGV("+++ all fds are closed");
return false;
}
if (selCount < 0) {
if (errno == EINTR)
continue;
- LOGE("select failed: %s\n", strerror(errno));
+ ALOGE("select failed: %s", strerror(errno));
goto fail;
}
if (netState->wakeFds[0] >= 0 &&
FD_ISSET(netState->wakeFds[0], &readfds))
{
- LOGD("Got wake-up signal, bailing out of select\n");
+ ALOGD("Got wake-up signal, bailing out of select");
goto fail;
}
if (netState->controlSock >= 0 &&
{
int sock = receiveClientFd(netState);
if (sock >= 0) {
- LOGI("Ignoring second debugger -- accepting and dropping\n");
+ ALOGI("Ignoring second debugger -- accepting and dropping");
close(sock);
} else {
assert(netState->controlSock < 0);
/* 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 */
- LOGV("+++ peer disconnected\n");
+ ALOGV("+++ 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;
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;
}