1. xxx.rc 中使用 /dev/socket/xxx
logd.rc 中 有 "socket logd stream 0666 logd logd" 以及 "socket logdr seqpacket 0666 logd logd"
这样的写法,实际会将logd 服务 与??"/dev/socket/logd" "dev/socket/logdr" socket节点进行绑定
?/system/core/logd/logd.rc
service logd /system/bin/logd
socket logd stream 0666 logd logd
socket logdr seqpacket 0666 logd logd
socket logdw dgram+passcred 0222 logd logd
file /proc/kmsg r
file /dev/kmsg w
user logd
group logd system package_info readproc
capabilities SYSLOG AUDIT_CONTROL
priority 10
task_profiles ServiceCapacityLow
2. SocketListener 分析
1)?通过继承?SocketListener 类,
SocketListener, class LogReader : public SocketListener {}"
2) 实现构造方法:
LogListener::LogListener(LogBuffer* buf, LogReader* reader) ? ? : SocketListener(getLogSocket(), false), logbuf(buf), reader(reader) {}
3) 通过?startListener()? 以及重载的 onDataAvailable()方法 完成通信
system/core/libsysutils/include/sysutils/SocketListener.h
class SocketListener {
bool mListen;
const char *mSocketName;
int mSock;
std::unordered_map<int, SocketClient*> mClients;
pthread_mutex_t mClientsLock;
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();
int startListener();
int startListener(int backlog);
int stopListener();
void sendBroadcast(int code, const char *msg, bool addErrno);
void runOnEachSocket(SocketClientCommand *command);
bool release(SocketClient *c) { return release(c, true); }
protected:
virtual bool onDataAvailable(SocketClient *c) = 0;
private:
static void *threadStart(void *obj);
// Add all clients to a separate list, so we don't have to hold the lock
// while processing it.
std::vector<SocketClient*> snapshotClients();
bool release(SocketClient *c, bool wakeup);
void runListener();
void init(const char *socketName, int socketFd, bool listen, bool useCmdNum);
};
natvie 代码里面通过 android_get_control_socket(xxx) 获取 "/dev/socket/xxx"
/system/core/libsysutils/src/SocketListener.cpp
SocketListener::SocketListener(const char *socketName, bool listen) {
init(socketName, -1, listen, false)
}
SocketListener::SocketListener(int socketFd, bool listen) {
init(nullptr, socketFd, listen, false)
}
void SocketListener::init(const char *socketName, int socketFd, bool listen, bool
useCmdNum) {
mListen = listen
mSocketName = socketName
mSock = socketFd
mUseCmdNum = useCmdNum
pthread_mutex_init(&mClientsLock, nullptr)
}
int SocketListener::startListener() {
return startListener(4)
}
int SocketListener::startListener(int backlog) {
if (mSocketName) {
// 重要,获取 socket 的地方,通过 mSocketName 获取socket
mSock = android_get_control_socket(mSocketName))
fcntl(mSock, F_SETFD, FD_CLOEXEC)
}
if (mListen && listen(mSock, backlog) < 0)
else if(!mListen)
mClients[mSock] = new SocketClient(mSock, false, mUseCmdNum)
(pthread_create(&mThread, nullptr, SocketListener::threadStart, this)
}
void *SocketListener::threadStart(void *obj) {
SocketListener *me = reinterpret_cast<SocketListener *>(obj)
me->runListener()
}
// 继承于 SocketListener 的子类,通过重载 onDataAvailable()方法,基于这个模型实现通信的
void SocketListener::runListener() {
while (true) {
for (SocketClient* c : pending) {
onDataAvailable(c)
}
}
}
3.?FrameworkListener 分析
FrameworkListener 继承于 SocketListener ,也可以基于 FrameworkListener 进行通信设计
通过 registerCmd 方法注册,然后调用对应 FrameworkCommand 的runCommand()方法
system/core/libsysutils/include/sysutils/FrameworkListener.h
class FrameworkListener : public SocketListener {}
/system/core/libsysutils/src/FrameworkListener.cpp
FrameworkListener::FrameworkListener(const char *socketName, bool withSeq) :
SocketListener(socketName, true, withSeq) {
init(socketName, withSeq)
}
FrameworkListener::FrameworkListener(const char *socketName) :
SocketListener(socketName, true, false) {
init(socketName, false)
}
void FrameworkListener::init(const char* /*socketName*/, bool withSeq) {
mWithSeq = withSeq
mSkipToNextNullByte = false
}
bool FrameworkListener::onDataAvailable(SocketClient *c) {
len = TEMP_FAILURE_RETRY(read(c->getSocket(), buffer, sizeof(buffer)))
for (i = 0; i < len; i++) {
if (buffer[i] == '\0') {
dispatchCommand(c, buffer + offset)
offset = i + 1
}
}
}
void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
while(*p) {
for (auto* c : mCommands) {
if (!strcmp(argv[0], c->getCommand())) {
if (c->runCommand(cli, argc, argv))
}
}
}
}
// 通过 registerCmd 方法注册,然后调用对应 FrameworkCommand 的runCommand()方法
void FrameworkListener::registerCmd(FrameworkCommand *cmd) {
mCommands.push_back(cmd)
}
4. 通过 SocketListener 及 FrameworkListener 实现通信例子
// 继承 SocketListener 实现通信
/system/core/logd/LogListener.cpp
LogListener::LogListener(LogBuffer* buf, LogReader* reader)
: SocketListener(getLogSocket(), false), logbuf(buf), reader(reader) {}
int LogListener::getLogSocket() {
static const char socketName[] = "logdw";
int sock = android_get_control_socket(socketName);
if (sock < 0) {
sock = socket_local_server(
socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM);
setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))
}
return sock
}
bool LogListener::onDataAvailable(SocketClient* cli) {
}
/system/core/logd/CommandListener.cpp
int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc,char** argv) {
if (argc < 2) {
cli->sendMsg("Missing Argument");
return 0;
}
cli->sendMsg(mBuf.clear((log_id_t)id, uid) ? "busy" : "success")
return 0
}
// 服务端,守护进程 logd
/system/core/logd/main.cpp
int main(int argc, char* argv[]) {
// 继承于 SocketListener, class LogReader : public SocketListener {}
LogReader* reader = new LogReader(logBuf)
reader->startListener()
// 继承于 SocketListener, class LogListener : public SocketListener {}
LogListener* swl = new LogListener(logBuf, reader)
swl->startListener(600)
// 继承于FrameworkListener, class CommandListener : public FrameworkListener {}
CommandListener* cl = new CommandListener(logBuf, reader, swl)
cl->startListener()
}
// 使用者客户端, logcat?
/system/core/logcat/logcat.cpp
int main(int argc, char** argv) {
return logcat.Run(argc, argv)
}
int Logcat::Run(int argc, char** argv) {
while (!max_count_ || print_count_ < max_count_) {
int ret = android_logger_list_read(logger_list.get(), &log_msg)
}
}
/system/core/liblog/logd_reader.cpp
int LogdRead(struct logger_list* logger_list, struct log_msg* log_msg) {
int ret = logdOpen(logger_list)
}
static int logdOpen(struct logger_list* logger_list) {
sock = socket_local_client("logdr", SOCK_SEQPACKET)
ret = TEMP_FAILURE_RETRY(write(sock, buffer, cp - buffer))
}
static int socket_local_client(const std::string& name, int type) {
std::string path = "/dev/socket/" + name;
strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path))
int fd = socket(AF_LOCAL, type | SOCK_CLOEXEC, 0)
connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))
}
|