logd: Add pidToName helper

Change-Id: Idd8e804ab65feb8dc432150ae701464de1ad5302
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 5622ee5..99c376a 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <fcntl.h>
 #include <stdarg.h>
 #include <time.h>
 
@@ -23,12 +24,34 @@
 
 #include "LogStatistics.h"
 
-PidStatistics::PidStatistics(pid_t pid)
+PidStatistics::PidStatistics(pid_t pid, char *name)
         : pid(pid)
         , mSizesTotal(0)
         , mElementsTotal(0)
         , mSizes(0)
-        , mElements(0) { }
+        , mElements(0)
+        , name(name)
+{ }
+
+#ifdef DO_NOT_ERROR_IF_PIDSTATISTICS_USES_A_COPY_CONSTRUCTOR
+PidStatistics::PidStatistics(const PidStatistics &copy)
+        : pid(copy->pid)
+        , name(copy->name ? strdup(copy->name) : NULL)
+        , mSizesTotal(copy->mSizesTotal)
+        , mElementsTotal(copy->mElementsTotal)
+        , mSizes(copy->mSizes)
+        , mElements(copy->mElements)
+{ }
+#endif
+
+PidStatistics::~PidStatistics() {
+    free(name);
+}
+
+void PidStatistics::setName(char *new_name) {
+    free(name);
+    name = new_name;
+}
 
 void PidStatistics::add(unsigned short size) {
     mSizesTotal += size;
@@ -50,6 +73,28 @@
     }
 }
 
+// must call free to release return value
+char *PidStatistics::pidToName(pid_t pid) {
+    char *retval = NULL;
+    if (pid != PidStatistics::gone) {
+        char buffer[512];
+        snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
+        int fd = open(buffer, O_RDONLY);
+        if (fd >= 0) {
+            ssize_t ret = read(fd, buffer, sizeof(buffer));
+            if (ret > 0) {
+                buffer[sizeof(buffer)-1] = '\0';
+                // frameworks intermediate state
+                if (strcmp(buffer, "<pre-initialized>")) {
+                    retval = strdup(buffer);
+                }
+            }
+            close(fd);
+        }
+    }
+    return retval;
+}
+
 UidStatistics::UidStatistics(uid_t uid)
         : uid(uid) {
     Pids.clear();
@@ -83,7 +128,7 @@
     bool insert = (last != it)
         && ((p->getPid() == p->gone)
             || ((*last)->sizesTotal() < (size_t) size));
-    p = new PidStatistics(pid);
+    p = new PidStatistics(pid, pidToName(pid));
     if (insert) {
         Pids.insert(last, p);
     } else {
@@ -397,8 +442,8 @@
 
 void LogStatistics::format(char **buf,
                            uid_t uid, unsigned int logMask, log_time oldest) {
-    const unsigned short spaces_current = 13;
-    const unsigned short spaces_total = 19;
+    static const unsigned short spaces_current = 13;
+    static const unsigned short spaces_total = 19;
 
     if (*buf) {
         free(buf);