lsof: Print process user name.

Change-Id: I6e96faba894ad8c2eeb06e514d332c8ab2ec52f0
diff --git a/toolbox/lsof.c b/toolbox/lsof.c
index c55384b..4e2f77a 100644
--- a/toolbox/lsof.c
+++ b/toolbox/lsof.c
@@ -37,11 +37,16 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include <pwd.h>
+#include <sys/stat.h>
+
 #define BUF_MAX 1024
-#define CMD_DISPLAY_MAX 10
+#define CMD_DISPLAY_MAX (9 + 1)
+#define USER_DISPLAY_MAX (10 + 1)
 
 struct pid_info_t {
     pid_t pid;
+    char user[USER_DISPLAY_MAX];
 
     char cmdline[CMD_DISPLAY_MAX];
 
@@ -82,7 +87,8 @@
     if (!strcmp(link_dest, "/"))
         goto out;
 
-    printf("%-9s %5d %10s %4s %9s %18s %9s %10s %s\n", info->cmdline, info->pid, "???", type,
+    printf("%-9s %5d %10s %4s %9s %18s %9s %10s %s\n",
+            info->cmdline, info->pid, info->user, type,
             "???", "???", "???", "???", link_dest);
 
 out:
@@ -113,7 +119,8 @@
         if (inode == 0 || !strcmp(device, "00:00"))
             continue;
 
-        printf("%-9s %5d %10s %4s %9s %18s %9zd %10ld %s\n", info->cmdline, info->pid, "???", "mem",
+        printf("%-9s %5d %10s %4s %9s %18s %9zd %10ld %s\n",
+                info->cmdline, info->pid, info->user, "mem",
                 "???", device, offset, inode, file);
     }
 
@@ -136,7 +143,8 @@
     if (dir == NULL) {
         char msg[BUF_MAX];
         snprintf(msg, sizeof(msg), "%s (opendir: %s)", info->path, strerror(errno));
-        printf("%-9s %5d %10s %4s %9s %18s %9s %10s %s\n", info->cmdline, info->pid, "???", "FDS",
+        printf("%-9s %5d %10s %4s %9s %18s %9s %10s %s\n",
+                info->cmdline, info->pid, info->user, "FDS",
                 "", "", "", "", msg);
         goto out;
     }
@@ -159,12 +167,26 @@
 {
     int fd;
     struct pid_info_t info;
+    struct stat pidstat;
+    struct passwd *pw;
+
     info.pid = pid;
-
     snprintf(info.path, sizeof(info.path), "/proc/%d/", pid);
-
     info.parent_length = strlen(info.path);
 
+    // Get the UID by calling stat on the proc/pid directory.
+    if (!stat(info.path, &pidstat)) {
+        pw = getpwuid(pidstat.st_uid);
+        if (pw) {
+            strncpy(info.user, pw->pw_name, USER_DISPLAY_MAX - 1);
+            info.user[USER_DISPLAY_MAX - 1] = '\0';
+        } else {
+            snprintf(info.user, USER_DISPLAY_MAX, "%d", (int)pidstat.st_uid);
+        }
+    } else {
+        strcpy(info.user, "???");
+    }
+
     // Read the command line information; each argument is terminated with NULL.
     strncat(info.path, "cmdline", sizeof(info.path));
     fd = open(info.path, O_RDONLY);
@@ -219,7 +241,7 @@
                 continue;
 
             // Only inspect directories that are PID numbers
-                pid = strtol(de->d_name, &endptr, 10);
+            pid = strtol(de->d_name, &endptr, 10);
             if (*endptr != '\0')
                 continue;