Imported Upstream version 3.3.12
[platform/upstream/procps-ng.git] / ps / output.c
index 63ba268..42c04cf 100644 (file)
@@ -96,6 +96,14 @@ static int sr_nop(const proc_t* a, const proc_t* b){
   return 0;
 }
 
+static int sr_cgroup(const proc_t* a, const proc_t* b)
+{
+    /* This is a "vector" of one */
+    if (*a->cgroup == NULL || *b->cgroup == NULL)
+        return 0;
+    return strcmp(*a->cgroup, *b->cgroup);
+}
+
 #define CMP_STR(NAME) \
 static int sr_ ## NAME(const proc_t* P, const proc_t* Q) { \
     return strcmp(P->NAME, Q->NAME); \
@@ -227,6 +235,7 @@ CMP_NS(userns, USERNS);
 CMP_NS(utsns, UTSNS);
 
 CMP_STR(lxcname)
+CMP_STR(cgname)
 
 /* approximation to: kB of address space that could end up in swap */
 static int sr_swapable(const proc_t* P, const proc_t* Q) {
@@ -436,6 +445,13 @@ static int pr_comm(char *restrict const outbuf, const proc_t *restrict const pp)
   return max_rightward-rightward;
 }
 
+static int pr_cgname(char *restrict const outbuf, const proc_t *restrict const pp){
+  int rightward = max_rightward;
+
+  escaped_copy(outbuf, pp->cgname, OUTBUF_SIZE, &rightward);
+  return max_rightward-rightward;
+}
+
 static int pr_cgroup(char *restrict const outbuf,const proc_t *restrict const pp) {
   int rightward = max_rightward;
 
@@ -1185,7 +1201,6 @@ static int pr_sgi_p(char *restrict const outbuf, const proc_t *restrict const pp
   return snprintf(outbuf, COLWID, "*");
 }
 
-#ifdef WITH_SYSTEMD
 /************************* Systemd stuff ********************************/
 static int pr_sd_unit(char *restrict const outbuf, const proc_t *restrict const pp){
   return snprintf(outbuf, COLWID, "%s", pp->sd_unit);
@@ -1214,7 +1229,6 @@ static int pr_sd_seat(char *restrict const outbuf, const proc_t *restrict const
 static int pr_sd_slice(char *restrict const outbuf, const proc_t *restrict const pp){
   return snprintf(outbuf, COLWID, "%s", pp->sd_slice);
 }
-#endif
 /************************ Linux namespaces ******************************/
 
 #define _pr_ns(NAME, ID)\
@@ -1239,67 +1253,69 @@ static int pr_lxcname(char *restrict const outbuf, const proc_t *restrict const
 /****************** FLASK & seLinux security stuff **********************/
 // move the bulk of this to libproc sometime
 
-#if !ENABLE_LIBSELINUX
-
-static int pr_context(char *restrict const outbuf, const proc_t *restrict const pp){
-  char filename[48];
-  size_t len;
-  ssize_t num_read;
-  int fd;
-
-// wchan file is suitable for testing
-//snprintf(filename, sizeof filename, "/proc/%d/wchan", pp->tgid);
-snprintf(filename, sizeof filename, "/proc/%d/attr/current", pp->tgid);
-
-  fd = open(filename, O_RDONLY, 0);
-  if(likely(fd==-1)) goto fail;
-  num_read = read(fd, outbuf, 666);
-  close(fd);
-  if(unlikely(num_read<=0)) goto fail;
-  outbuf[num_read] = '\0';
-
-  len = 0;
-  while(outbuf[len]>' ' && outbuf[len]<='~') len++;
-  outbuf[len] = '\0';
-  if(len) return len;
-
-fail:
-  outbuf[0] = '-';
-  outbuf[1] = '\0';
-  return 1;
-}
-
-#else
-
 // This needs more study, considering:
 // 1. the static linking option (maybe disable this in that case)
 // 2. the -z and -Z option issue
 // 3. width of output
 static int pr_context(char *restrict const outbuf, const proc_t *restrict const pp){
+  static void (*ps_freecon)(char*) = 0;
   static int (*ps_getpidcon)(pid_t pid, char **context) = 0;
+  static int (*ps_is_selinux_enabled)(void) = 0;
   static int tried_load = 0;
+  static int selinux_enabled = 0;
   size_t len;
   char *context;
 
+#if ENABLE_LIBSELINUX
   if(!ps_getpidcon && !tried_load){
     void *handle = dlopen("libselinux.so.1", RTLD_NOW);
     if(handle){
+      ps_freecon = dlsym(handle, "freecon");
+      if(dlerror())
+        ps_freecon = 0;
       dlerror();
       ps_getpidcon = dlsym(handle, "getpidcon");
       if(dlerror())
         ps_getpidcon = 0;
+      ps_is_selinux_enabled = dlsym(handle, "is_selinux_enabled");
+      if(dlerror())
+        ps_is_selinux_enabled = 0;
+      else
+        selinux_enabled = ps_is_selinux_enabled();
     }
     tried_load++;
   }
-  if(ps_getpidcon && !ps_getpidcon(pp->tgid, &context)){
+#endif
+  if(ps_getpidcon && selinux_enabled && !ps_getpidcon(pp->tgid, &context)){
     size_t max_len = OUTBUF_SIZE-1;
     len = strlen(context);
     if(len > max_len) len = max_len;
     memcpy(outbuf, context, len);
     if (outbuf[len-1] == '\n') --len;
     outbuf[len] = '\0';
-    free(context);
+    ps_freecon(context);
   }else{
+    char filename[48];
+    ssize_t num_read;
+    int fd;
+
+// wchan file is suitable for testing
+//snprintf(filename, sizeof filename, "/proc/%d/wchan", pp->tgid);
+    snprintf(filename, sizeof filename, "/proc/%d/attr/current", pp->tgid);
+
+    if ((fd = open(filename, O_RDONLY, 0)) != -1) {
+      num_read = read(fd, outbuf, OUTBUF_SIZE-1);
+      close(fd);
+      if (num_read > 0) {
+        outbuf[num_read] = '\0';
+        len = 0;
+        while(isprint(outbuf[len]))
+          len++;
+        outbuf[len] = '\0';
+        if(len)
+          return len;
+      }
+    }
     outbuf[0] = '-';
     outbuf[1] = '\0';
     len = 1;
@@ -1307,9 +1323,6 @@ static int pr_context(char *restrict const outbuf, const proc_t *restrict const
   return len;
 }
 
-#endif
-
-
 ////////////////////////////// Test code /////////////////////////////////
 
 // like "args"
@@ -1398,9 +1411,7 @@ static int pr_t_left2(char *restrict const outbuf, const proc_t *restrict const
 #define GRP PROC_FILLGRP     /* gid_t -> group names */
 #define NS  PROC_FILLNS      /* read namespace information */
 #define LXC PROC_FILL_LXC    /* value the lxc name field */
-#ifdef WITH_SYSTEMD
 #define SD  PROC_FILLSYSTEMD /* retrieve systemd stuff */
-#endif
 #define SGRP PROC_FILLSTATUS | PROC_FILLSUPGRP  /* supgid -> supgrp (names) */
 #define CGRP PROC_FILLCGROUP | PROC_EDITCGRPCVT /* read cgroup */
 
@@ -1439,7 +1450,8 @@ static const format_struct format_array[] = {
 {"bsdtime",   "TIME",    pr_bsdtime,  sr_nop,     6,   0,    LNX, ET|RIGHT},
 {"c",         "C",       pr_c,        sr_pcpu,    2,   0,    SUN, ET|RIGHT},
 {"caught",    "CAUGHT",  pr_sigcatch, sr_nop,     9,   0,    BSD, TO|SIGNAL}, /*sigcatch*/
-{"cgroup",    "CGROUP",  pr_cgroup,   sr_nop,    27,CGRP,    LNX, PO|UNLIMITED},
+{"cgname",    "CGNAME",  pr_cgname,   sr_cgname, 27,CGRP,    LNX, PO|UNLIMITED},
+{"cgroup",    "CGROUP",  pr_cgroup,   sr_cgroup, 27,CGRP,    LNX, PO|UNLIMITED},
 {"class",     "CLS",     pr_class,    sr_sched,   3,   0,    XXX, TO|LEFT},
 {"cls",       "CLS",     pr_class,    sr_sched,   3,   0,    HPU, TO|RIGHT}, /*says HPUX or RT*/
 {"cmaj_flt",  "-",       pr_nop,      sr_cmaj_flt, 1,  0,    LNX, AN|RIGHT},
@@ -1499,9 +1511,7 @@ static const format_struct format_array[] = {
 {"login",     "LOGNAME", pr_nop,      sr_nop,     8,   0,    BSD, AN|LEFT}, /*logname*/   /* double check */
 {"logname",   "LOGNAME", pr_nop,      sr_nop,     8,   0,    XXX, AN|LEFT}, /*login*/
 {"longtname", "TTY",     pr_tty8,     sr_tty,     8,   0,    DEC, PO|LEFT},
-#ifdef WITH_SYSTEMD
 {"lsession",  "SESSION", pr_sd_session, sr_nop,  11,  SD,    LNX, ET|LEFT},
-#endif
 {"lstart",    "STARTED", pr_lstart,   sr_nop,    24,   0,    XXX, ET|RIGHT},
 {"luid",      "LUID",    pr_nop,      sr_nop,     5,   0,    LNX, ET|RIGHT}, /* login ID */
 {"luser",     "LUSER",   pr_nop,      sr_nop,     8, USR,    LNX, ET|USER}, /* login USER */
@@ -1515,9 +1525,7 @@ static const format_struct format_array[] = {
 {"m_size",    "SIZE",    pr_size,     sr_size,    5, MEM,    LNX, PO|RIGHT},
 {"m_swap",    "SWAP",    pr_nop,      sr_nop,     5,   0,    LNx, PO|RIGHT},
 {"m_trs",     "TRS",     pr_trs,      sr_trs,     5, MEM,    LNx, PO|RIGHT},
-#ifdef WITH_SYSTEMD
 {"machine",   "MACHINE", pr_sd_machine, sr_nop,  31,  SD,    LNX, ET|LEFT},
-#endif
 {"maj_flt",   "MAJFL",   pr_majflt,   sr_maj_flt, 6,   0,    LNX, AN|RIGHT},
 {"majflt",    "MAJFLT",  pr_majflt,   sr_maj_flt, 6,   0,    XXX, AN|RIGHT},
 {"min_flt",   "MINFL",   pr_minflt,   sr_min_flt, 6,   0,    LNX, AN|RIGHT},
@@ -1540,9 +1548,7 @@ static const format_struct format_array[] = {
 {"osz",       "SZ",      pr_nop,      sr_nop,     2,   0,    SUN, PO|RIGHT},
 {"oublk",     "OUBLK",   pr_nop,      sr_nop,     5,   0,    BSD, AN|RIGHT}, /*oublock*/
 {"oublock",   "OUBLK",   pr_nop,      sr_nop,     5,   0,    DEC, AN|RIGHT}, /*oublk*/
-#ifdef WITH_SYSTEMD
 {"ouid",      "OWNER",   pr_sd_ouid,  sr_nop,     5,  SD,    LNX, ET|LEFT},
-#endif
 {"p_ru",      "P_RU",    pr_nop,      sr_nop,     6,   0,    BSD, AN|RIGHT},
 {"paddr",     "PADDR",   pr_nop,      sr_nop,     6,   0,    BSD, AN|RIGHT},
 {"pagein",    "PAGEIN",  pr_majflt,   sr_maj_flt, 6,   0,    XXX, AN|RIGHT},
@@ -1584,9 +1590,7 @@ static const format_struct format_array[] = {
 {"sched",     "SCH",     pr_sched,    sr_sched,   3,   0,    AIX, TO|RIGHT},
 {"scnt",      "SCNT",    pr_nop,      sr_nop,     4,   0,    DEC, AN|RIGHT},  /* man page misspelling of scount? */
 {"scount",    "SC",      pr_nop,      sr_nop,     4,   0,    AIX, AN|RIGHT},  /* scnt==scount, DEC claims both */
-#ifdef WITH_SYSTEMD
 {"seat",      "SEAT",    pr_sd_seat,  sr_nop,    11,  SD,    LNX, ET|LEFT},
-#endif
 {"sess",      "SESS",    pr_sess,     sr_session, 5,   0,    XXX, PO|PIDMAX|RIGHT},
 {"session",   "SESS",    pr_sess,     sr_session, 5,   0,    LNX, PO|PIDMAX|RIGHT},
 {"sgi_p",     "P",       pr_sgi_p,    sr_nop,     1,   0,    LNX, TO|RIGHT}, /* "cpu" number */
@@ -1605,9 +1609,7 @@ static const format_struct format_array[] = {
 {"sigmask",   "BLOCKED", pr_sigmask,  sr_nop,     9,   0,    XXX, TO|SIGNAL}, /*blocked*/
 {"size",      "SIZE",    pr_swapable, sr_swapable, 5,  0,    SCO, PO|RIGHT},
 {"sl",        "SL",      pr_nop,      sr_nop,     3,   0,    XXX, AN|RIGHT},
-#ifdef WITH_SYSTEMD
 {"slice",      "SLICE",  pr_sd_slice, sr_nop,    31,  SD,    LNX, ET|LEFT},
-#endif
 {"spid",      "SPID",    pr_tasks,    sr_tasks,   5,   0,    SGI, TO|PIDMAX|RIGHT},
 {"stackp",    "STACKP",  pr_stackp,   sr_start_stack, 8, 0,  LNX, PO|RIGHT}, /*start_stack*/
 {"start",     "STARTED", pr_start,    sr_nop,     8,   0,    XXX, ET|RIGHT},
@@ -1630,8 +1632,8 @@ static const format_struct format_array[] = {
 {"sz",        "SZ",      pr_sz,       sr_nop,     5,   0,    HPU, PO|RIGHT},
 {"taskid",    "TASKID",  pr_nop,      sr_nop,     5,   0,    SUN, TO|PIDMAX|RIGHT}, // is this a thread ID?
 {"tdev",      "TDEV",    pr_nop,      sr_nop,     4,   0,    XXX, AN|RIGHT},
-{"thcount",   "THCNT",   pr_nlwp,     sr_nlwp,    5,   0,    AIX, PO|RIGHT},
 {"tgid",      "TGID",    pr_procs,    sr_procs,   5,   0,    LNX, PO|PIDMAX|RIGHT},
+{"thcount",   "THCNT",   pr_nlwp,     sr_nlwp,    5,   0,    AIX, PO|RIGHT},
 {"tid",       "TID",     pr_tasks,    sr_tasks,   5,   0,    AIX, TO|PIDMAX|RIGHT},
 {"time",      "TIME",    pr_time,     sr_time,    8,   0,    U98, ET|RIGHT}, /*cputime*/ /* was 6 wide */
 {"timeout",   "TMOUT",   pr_nop,      sr_nop,     5,   0,    LNX, AN|RIGHT}, // 2.0.xx era
@@ -1656,9 +1658,7 @@ static const format_struct format_array[] = {
 {"uid_hack",  "UID",     pr_euser,    sr_euser,   8, USR,    XXX, ET|USER},
 {"umask",     "UMASK",   pr_nop,      sr_nop,     5,   0,    DEC, AN|RIGHT},
 {"uname",     "USER",    pr_euser,    sr_euser,   8, USR,    DEC, ET|USER}, /* man page misspelling of user? */
-#ifdef WITH_SYSTEMD
 {"unit",      "UNIT",    pr_sd_unit,  sr_nop,    31,  SD,    LNX, ET|LEFT},
-#endif
 {"upr",       "UPR",     pr_nop,      sr_nop,     3,   0,    BSD, TO|RIGHT}, /*usrpri*/
 {"uprocp",    "UPROCP",  pr_nop,      sr_nop,     8,   0,    BSD, AN|RIGHT},
 {"user",      "USER",    pr_euser,    sr_euser,   8, USR,    U98, ET|USER}, /* BSD n forces this to UID */
@@ -1668,9 +1668,7 @@ static const format_struct format_array[] = {
 {"util",      "C",       pr_c,        sr_pcpu,    2,   0,    SGI, ET|RIGHT}, // not sure about "C"
 {"utime",     "UTIME",   pr_nop,      sr_utime,   6,   0,    LNx, ET|RIGHT},
 {"utsns",     "UTSNS",   pr_utsns,    sr_utsns,  10,  NS,    LNX, ET|RIGHT},
-#ifdef WITH_SYSTEMD
 {"uunit",     "UUNIT",   pr_sd_uunit, sr_nop,    31,  SD,    LNX, ET|LEFT},
-#endif
 {"vm_data",   "DATA",    pr_nop,      sr_vm_data, 5,   0,    LNx, PO|RIGHT},
 {"vm_exe",    "EXE",     pr_nop,      sr_vm_exe,  5,   0,    LNx, PO|RIGHT},
 {"vm_lib",    "LIB",     pr_nop,      sr_vm_lib,  5,   0,    LNx, PO|RIGHT},