summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Salyzyn2014-02-26 11:50:16 -0600
committerMark Salyzyn2014-02-26 11:52:35 -0600
commit0175b0747a1f55329109e84c9a1322dcb95e2848 (patch)
treea48dd103279c3efc313028a09fb4570d212e624d /logd/LogListener.cpp
parent9b986497e7f19a7fde9e35eb73d765f4a09dee07 (diff)
downloadplatform-system-core-0175b0747a1f55329109e84c9a1322dcb95e2848.tar.gz
platform-system-core-0175b0747a1f55329109e84c9a1322dcb95e2848.tar.xz
platform-system-core-0175b0747a1f55329109e84c9a1322dcb95e2848.zip
logd: initial checkin.
* Create a new userspace log daemon for handling logging messages. Original-Change-Id: I75267df16359684490121e6c31cca48614d79856 Signed-off-by: Nick Kralevich <nnk@google.com> * Merge conflicts * rename new syslog daemon to logd to prevent confusion with bionic syslog * replace racy getGroups call with KISS call to client->getGid() * Timestamps are filed at logging source * insert entries into list in timestamp order * Added LogTimeEntry tail filtration handling * Added region locking around LogWriter list * separate threads for each writer * /dev/socket/logd* permissions Signed-off-by: Mark Salyzyn <salyzyn@google.com> (cherry picked from commit 3e76e0a49760c4970b7cda6153e51026af98e4f3) Author: Nick Kralevich <nnk@google.com> Change-Id: Ice88b1412d8f9daa7f9119b2b5aaf684a5e28098
Diffstat (limited to 'logd/LogListener.cpp')
-rw-r--r--logd/LogListener.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
new file mode 100644
index 000000000..c6b248bdc
--- /dev/null
+++ b/logd/LogListener.cpp
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C) 2012-2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <sys/socket.h>
18#include <sys/types.h>
19#include <sys/un.h>
20#include <unistd.h>
21
22#include <cutils/sockets.h>
23#include <log/logger.h>
24
25#include "LogListener.h"
26
27LogListener::LogListener(LogBuffer *buf, LogReader *reader)
28 : SocketListener(getLogSocket(), false)
29 , logbuf(buf)
30 , reader(reader)
31{ }
32
33bool LogListener::onDataAvailable(SocketClient *cli) {
34 char buffer[1024];
35 struct iovec iov = { buffer, sizeof(buffer) };
36 memset(buffer, 0, sizeof(buffer));
37
38 char control[CMSG_SPACE(sizeof(struct ucred))];
39 struct msghdr hdr = {
40 NULL,
41 0,
42 &iov,
43 1,
44 control,
45 sizeof(control),
46 0,
47 };
48
49 int socket = cli->getSocket();
50
51 ssize_t n = recvmsg(socket, &hdr, 0);
52 if (n <= (ssize_t) sizeof_log_id_t) {
53 return false;
54 }
55
56 struct ucred *cred = NULL;
57
58 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr);
59 while (cmsg != NULL) {
60 if (cmsg->cmsg_level == SOL_SOCKET
61 && cmsg->cmsg_type == SCM_CREDENTIALS) {
62 cred = (struct ucred *)CMSG_DATA(cmsg);
63 break;
64 }
65 cmsg = CMSG_NXTHDR(&hdr, cmsg);
66 }
67
68 if (cred == NULL) {
69 return false;
70 }
71
72 if (cred->uid == getuid()) {
73 // ignore log messages we send to ourself.
74 // Such log messages are often generated by libraries we depend on
75 // which use standard Android logging.
76 return false;
77 }
78
79 // First log element is always log_id.
80 log_id_t log_id = (log_id_t) *((typeof_log_id_t *) buffer);
81 if (log_id < 0 || log_id >= LOG_ID_MAX) {
82 return false;
83 }
84
85 char *msg = ((char *)buffer) + sizeof_log_id_t;
86 n -= sizeof_log_id_t;
87
88 log_time realtime(msg);
89 msg += sizeof(log_time);
90 n -= sizeof(log_time);
91
92 unsigned short len = n;
93 if (len == n) {
94 logbuf->log(log_id, realtime, cred->uid, cred->pid, msg, len);
95 reader->notifyNewLog();
96 }
97
98 return true;
99}
100
101int LogListener::getLogSocket() {
102 int sock = android_get_control_socket("logdw");
103 int on = 1;
104 if (setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
105 return -1;
106 }
107 return sock;
108}