summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sysutils/FrameworkListener.h7
-rw-r--r--include/sysutils/SocketClient.h17
-rw-r--r--include/sysutils/SocketListener.h8
-rw-r--r--libsysutils/src/FrameworkListener.cpp38
-rw-r--r--libsysutils/src/SocketClient.cpp59
-rw-r--r--libsysutils/src/SocketListener.cpp45
6 files changed, 120 insertions, 54 deletions
diff --git a/include/sysutils/FrameworkListener.h b/include/sysutils/FrameworkListener.h
index 142f50c..756bacf 100644
--- a/include/sysutils/FrameworkListener.h
+++ b/include/sysutils/FrameworkListener.h
@@ -24,11 +24,17 @@ class SocketClient;
class FrameworkListener : public SocketListener {
public:
static const int CMD_ARGS_MAX = 16;
+
+ /* 1 out of errorRate will be dropped */
+ int errorRate;
private:
+ int mCommandCount;
+ bool mWithSeq;
FrameworkCommandCollection *mCommands;
public:
FrameworkListener(const char *socketName);
+ FrameworkListener(const char *socketName, bool withSeq);
virtual ~FrameworkListener() {}
protected:
@@ -37,5 +43,6 @@ protected:
private:
void dispatchCommand(SocketClient *c, char *data);
+ void init(const char *socketName, bool withSeq);
};
#endif
diff --git a/include/sysutils/SocketClient.h b/include/sysutils/SocketClient.h
index 7d2b1d6..6473b3a 100644
--- a/include/sysutils/SocketClient.h
+++ b/include/sysutils/SocketClient.h
@@ -4,6 +4,7 @@
#include "../../../frameworks/base/include/utils/List.h"
#include <pthread.h>
+#include <cutils/atomic.h>
#include <sys/types.h>
class SocketClient {
@@ -24,20 +25,27 @@ class SocketClient {
pthread_mutex_t mRefCountMutex;
int mRefCount;
+ int mCmdNum;
+
+ bool mUseCmdNum;
+
public:
SocketClient(int sock, bool owned);
+ SocketClient(int sock, bool owned, bool useCmdNum);
virtual ~SocketClient();
int getSocket() { return mSocket; }
pid_t getPid() const { return mPid; }
uid_t getUid() const { return mUid; }
gid_t getGid() const { return mGid; }
+ void setCmdNum(int cmdNum) { android_atomic_release_store(cmdNum, &mCmdNum); }
+ int getCmdNum() { return mCmdNum; }
// Send null-terminated C strings:
int sendMsg(int code, const char *msg, bool addErrno);
- int sendMsg(const char *msg);
+ int sendMsg(int code, const char *msg, bool addErrno, bool useCmdNum);
- // Sending binary data:
+ //Sending binary data:
int sendData(const void *data, int len);
// Optional reference counting. Reference count starts at 1. If
@@ -46,6 +54,11 @@ public:
// decRef() when it's done with the client.
void incRef();
bool decRef(); // returns true at 0 (but note: SocketClient already deleted)
+
+private:
+ // Send null-terminated C strings
+ int sendMsg(const char *msg);
+ void init(int socket, bool owned, bool useCmdNum);
};
typedef android::List<SocketClient *> SocketClientCollection;
diff --git a/include/sysutils/SocketListener.h b/include/sysutils/SocketListener.h
index 6592b01..8f56230 100644
--- a/include/sysutils/SocketListener.h
+++ b/include/sysutils/SocketListener.h
@@ -21,16 +21,18 @@
#include <sysutils/SocketClient.h>
class SocketListener {
- int mSock;
+ bool mListen;
const char *mSocketName;
+ int mSock;
SocketClientCollection *mClients;
pthread_mutex_t mClientsLock;
- bool mListen;
int mCtrlPipe[2];
pthread_t mThread;
+ bool mUseCmdNum;
public:
SocketListener(const char *socketName, bool listen);
+ SocketListener(const char *socketName, bool listen, bool useCmdNum);
SocketListener(int socketFd, bool listen);
virtual ~SocketListener();
@@ -38,7 +40,6 @@ public:
int stopListener();
void sendBroadcast(int code, const char *msg, bool addErrno);
- void sendBroadcast(const char *msg);
protected:
virtual bool onDataAvailable(SocketClient *c) = 0;
@@ -46,5 +47,6 @@ protected:
private:
static void *threadStart(void *obj);
void runListener();
+ void init(const char *socketName, int socketFd, bool listen, bool useCmdNum);
};
#endif
diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp
index 90be754..6731cf1 100644
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -25,9 +25,21 @@
#include <sysutils/FrameworkCommand.h>
#include <sysutils/SocketClient.h>
+FrameworkListener::FrameworkListener(const char *socketName, bool withSeq) :
+ SocketListener(socketName, true, withSeq) {
+ init(socketName, withSeq);
+}
+
FrameworkListener::FrameworkListener(const char *socketName) :
- SocketListener(socketName, true) {
+ SocketListener(socketName, true, false) {
+ init(socketName, false);
+}
+
+void FrameworkListener::init(const char *socketName, bool withSeq) {
mCommands = new FrameworkCommandCollection();
+ errorRate = 0;
+ mCommandCount = 0;
+ mWithSeq = withSeq;
}
bool FrameworkListener::onDataAvailable(SocketClient *c) {
@@ -69,6 +81,7 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
bool esc = false;
bool quote = false;
int k;
+ bool haveCmdNum = !mWithSeq;
memset(argv, 0, sizeof(argv));
memset(tmp, 0, sizeof(tmp));
@@ -115,9 +128,20 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
*q = *p++;
if (!quote && *q == ' ') {
*q = '\0';
- if (argc >= CMD_ARGS_MAX)
- goto overflow;
- argv[argc++] = strdup(tmp);
+ if (!haveCmdNum) {
+ char *endptr;
+ int cmdNum = (int)strtol(tmp, &endptr, 0);
+ if (endptr == NULL || *endptr != '\0') {
+ cli->sendMsg(500, "Invalid sequence number", false);
+ goto out;
+ }
+ cli->setCmdNum(cmdNum);
+ haveCmdNum = true;
+ } else {
+ if (argc >= CMD_ARGS_MAX)
+ goto overflow;
+ argv[argc++] = strdup(tmp);
+ }
memset(tmp, 0, sizeof(tmp));
q = tmp;
continue;
@@ -140,6 +164,12 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
goto out;
}
+ if (errorRate && (++mCommandCount % errorRate == 0)) {
+ /* ignore this command - let the timeout handler handle it */
+ SLOGE("Faking a timeout");
+ goto out;
+ }
+
for (i = mCommands->begin(); i != mCommands->end(); ++i) {
FrameworkCommand *c = *i;
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
index 722dcb2..d9fc48c 100644
--- a/libsysutils/src/SocketClient.cpp
+++ b/libsysutils/src/SocketClient.cpp
@@ -10,16 +10,25 @@
#include <sysutils/SocketClient.h>
-SocketClient::SocketClient(int socket, bool owned)
- : mSocket(socket)
- , mSocketOwned(owned)
- , mPid(-1)
- , mUid(-1)
- , mGid(-1)
- , mRefCount(1)
-{
+SocketClient::SocketClient(int socket, bool owned) {
+ init(socket, owned, false);
+}
+
+SocketClient::SocketClient(int socket, bool owned, bool useCmdNum) {
+ init(socket, owned, useCmdNum);
+}
+
+void SocketClient::init(int socket, bool owned, bool useCmdNum) {
+ mSocket = socket;
+ mSocketOwned = owned;
+ mUseCmdNum = useCmdNum;
pthread_mutex_init(&mWriteMutex, NULL);
pthread_mutex_init(&mRefCountMutex, NULL);
+ mPid = -1;
+ mUid = -1;
+ mGid = -1;
+ mRefCount = 1;
+ mCmdNum = 0;
struct ucred creds;
socklen_t szCreds = sizeof(creds);
@@ -41,26 +50,32 @@ SocketClient::~SocketClient()
}
int SocketClient::sendMsg(int code, const char *msg, bool addErrno) {
+ return sendMsg(code, msg, addErrno, mUseCmdNum);
+}
+
+int SocketClient::sendMsg(int code, const char *msg, bool addErrno, bool useCmdNum) {
char *buf;
- const char* arg;
- const char* fmt;
- char tmp[1];
- int len;
+ int ret = 0;
if (addErrno) {
- fmt = "%.3d %s (%s)";
- arg = strerror(errno);
+ if (useCmdNum) {
+ ret = asprintf(&buf, "%d %d %s (%s)", code, getCmdNum(), msg, strerror(errno));
+ } else {
+ ret = asprintf(&buf, "%d %s (%s)", code, msg, strerror(errno));
+ }
} else {
- fmt = "%.3d %s";
- arg = NULL;
+ if (useCmdNum) {
+ ret = asprintf(&buf, "%d %d %s", code, getCmdNum(), msg);
+ } else {
+ ret = asprintf(&buf, "%d %s", code, msg);
+ }
}
- /* Measure length of required buffer */
- len = snprintf(tmp, sizeof tmp, fmt, code, msg, arg);
- /* Allocate in the stack, then write to it */
- buf = (char*)alloca(len+1);
- snprintf(buf, len+1, fmt, code, msg, arg);
/* Send the zero-terminated message */
- return sendMsg(buf);
+ if (ret != -1) {
+ ret = sendMsg(buf);
+ free(buf);
+ }
+ return ret;
}
int SocketClient::sendMsg(const char *msg) {
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index 3f871ea..0361641 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -29,18 +29,25 @@
#include <sysutils/SocketListener.h>
#include <sysutils/SocketClient.h>
+#define LOG_NDEBUG 0
+
SocketListener::SocketListener(const char *socketName, bool listen) {
- mListen = listen;
- mSocketName = socketName;
- mSock = -1;
- pthread_mutex_init(&mClientsLock, NULL);
- mClients = new SocketClientCollection();
+ init(socketName, -1, listen, false);
}
SocketListener::SocketListener(int socketFd, bool listen) {
+ init(NULL, socketFd, listen, false);
+}
+
+SocketListener::SocketListener(const char *socketName, bool listen, bool useCmdNum) {
+ init(socketName, -1, listen, useCmdNum);
+}
+
+void SocketListener::init(const char *socketName, int socketFd, bool listen, bool useCmdNum) {
mListen = listen;
- mSocketName = NULL;
+ mSocketName = socketName;
mSock = socketFd;
+ mUseCmdNum = useCmdNum;
pthread_mutex_init(&mClientsLock, NULL);
mClients = new SocketClientCollection();
}
@@ -73,13 +80,14 @@ int SocketListener::startListener() {
mSocketName, strerror(errno));
return -1;
}
+ SLOGV("got mSock = %d for %s", mSock, mSocketName);
}
if (mListen && listen(mSock, 4) < 0) {
SLOGE("Unable to listen on socket (%s)", strerror(errno));
return -1;
} else if (!mListen)
- mClients->push_back(new SocketClient(mSock, false));
+ mClients->push_back(new SocketClient(mSock, false, mUseCmdNum));
if (pipe(mCtrlPipe)) {
SLOGE("pipe failed (%s)", strerror(errno));
@@ -164,11 +172,11 @@ void SocketListener::runListener() {
max = fd;
}
pthread_mutex_unlock(&mClientsLock);
-
+ SLOGV("mListen=%d, max=%d, mSocketName=%s", mListen, max, mSocketName);
if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) {
if (errno == EINTR)
continue;
- SLOGE("select failed (%s)", strerror(errno));
+ SLOGE("select failed (%s) mListen=%d, max=%d", strerror(errno), mListen, max);
sleep(1);
continue;
} else if (!rc)
@@ -184,6 +192,7 @@ void SocketListener::runListener() {
do {
alen = sizeof(addr);
c = accept(mSock, &addr, &alen);
+ SLOGV("%s got %d from accept", mSocketName, c);
} while (c < 0 && errno == EINTR);
if (c < 0) {
SLOGE("accept failed (%s)", strerror(errno));
@@ -191,7 +200,7 @@ void SocketListener::runListener() {
continue;
}
pthread_mutex_lock(&mClientsLock);
- mClients->push_back(new SocketClient(c, true));
+ mClients->push_back(new SocketClient(c, true, mUseCmdNum));
pthread_mutex_unlock(&mClientsLock);
}
@@ -217,6 +226,7 @@ void SocketListener::runListener() {
* connection-based, remove and destroy it */
if (!onDataAvailable(c) && mListen) {
/* Remove the client from our array */
+ SLOGV("going to zap %d for %s", c->getSocket(), mSocketName);
pthread_mutex_lock(&mClientsLock);
for (it = mClients->begin(); it != mClients->end(); ++it) {
if (*it == c) {
@@ -238,19 +248,8 @@ void SocketListener::sendBroadcast(int code, const char *msg, bool addErrno) {
SocketClientCollection::iterator i;
for (i = mClients->begin(); i != mClients->end(); ++i) {
- if ((*i)->sendMsg(code, msg, addErrno)) {
- SLOGW("Error sending broadcast (%s)", strerror(errno));
- }
- }
- pthread_mutex_unlock(&mClientsLock);
-}
-
-void SocketListener::sendBroadcast(const char *msg) {
- pthread_mutex_lock(&mClientsLock);
- SocketClientCollection::iterator i;
-
- for (i = mClients->begin(); i != mClients->end(); ++i) {
- if ((*i)->sendMsg(msg)) {
+ // broadcasts are unsolicited and should not include a cmd number
+ if ((*i)->sendMsg(code, msg, addErrno, false)) {
SLOGW("Error sending broadcast (%s)", strerror(errno));
}
}