logd: auditd: add logd.auditd.dmesg property

Change-Id: If4a579c2221eec99cf3f6acf59ead8c2d5230517
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index cc3e583..ea6eece 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -19,15 +19,18 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <sys/klog.h>
+#include <sys/uio.h>
 
 #include "libaudit.h"
 #include "LogAudit.h"
 
-LogAudit::LogAudit(LogBuffer *buf, LogReader *reader)
+LogAudit::LogAudit(LogBuffer *buf, LogReader *reader, int fdDmsg)
         : SocketListener(getLogSocket(), false)
         , logbuf(buf)
-        , reader(reader) {
-    logDmsg();
+        , reader(reader)
+        , fdDmesg(-1) {
+    logDmesg();
+    fdDmesg = fdDmsg;
 }
 
 bool LogAudit::onDataAvailable(SocketClient *cli) {
@@ -62,6 +65,17 @@
         return rc;
     }
 
+    if (fdDmesg >= 0) {
+        struct iovec iov[2];
+
+        iov[0].iov_base = str;
+        iov[0].iov_len = strlen(str);
+        iov[1].iov_base = const_cast<char *>("\n");
+        iov[1].iov_len = 1;
+
+        writev(fdDmesg, iov, sizeof(iov) / sizeof(iov[0]));
+    }
+
     pid_t pid = getpid();
     pid_t tid = gettid();
     uid_t uid = getuid();
@@ -141,7 +155,7 @@
     return rc;
 }
 
-void LogAudit::logDmsg() {
+void LogAudit::logDmesg() {
     int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
     if (len <= 0) {
         return;
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index 3e57eed..111030a 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -23,16 +23,17 @@
 class LogAudit : public SocketListener {
     LogBuffer *logbuf;
     LogReader *reader;
+    int fdDmesg;
 
 public:
-    LogAudit(LogBuffer *buf, LogReader *reader);
+    LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg);
 
 protected:
     virtual bool onDataAvailable(SocketClient *cli);
 
 private:
     static int getLogSocket();
-    void logDmsg();
+    void logDmesg();
     int logPrint(const char *fmt, ...)
         __attribute__ ((__format__ (__printf__, 2, 3)));
 };
diff --git a/logd/main.cpp b/logd/main.cpp
index 83ec6c0..7346e2f 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -84,6 +84,13 @@
 // space logger.  Additional transitory per-client threads are created
 // for each reader once they register.
 int main() {
+    int fdDmesg = -1;
+    char dmesg[PROPERTY_VALUE_MAX];
+    property_get("logd.auditd.dmesg", dmesg, "1");
+    if (atol(dmesg)) {
+        fdDmesg = open("/dev/kmsg", O_WRONLY);
+    }
+
     if (drop_privs() != 0) {
         return -1;
     }
@@ -136,9 +143,10 @@
     // and LogReader is notified to send updates to connected clients.
 
     // failure is an option ... messages are in dmesg (required by standard)
-    LogAudit *al = new LogAudit(logBuf, reader);
+    LogAudit *al = new LogAudit(logBuf, reader, fdDmesg);
     if (al->startListener()) {
         delete al;
+        close(fdDmesg);
     }
 
     pause();