File procps-3.2.7-oom.diff of Package procps

Index: procps-3.2.7/top.c
===================================================================
--- procps-3.2.7.orig/top.c
+++ procps-3.2.7/top.c
@@ -23,9 +23,9 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <ctype.h>
+// #include <ctype.h>
 #include <curses.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -223,8 +223,11 @@ SCB_NUM1(P_SHR, share)
 SCB_NUM1(P_FLT, maj_flt)
 SCB_NUM1(P_DRT, dt)
 SCB_NUMx(P_STA, state)
 
+SCB_NUM1(P_OOM, oom_score)
+SCB_NUM1(P_OOA, oom_adj)
+
 static int sort_P_CMD (const proc_t **P, const proc_t **Q)
 {
    /* if a process doesn't have a cmdline, we'll consider it a kernel thread
       -- since displayed tasks are given special treatment, we must too */
@@ -315,8 +318,13 @@ static const char *tg2 (int x, int y)
 {
    return Cap_can_goto ? tgoto(cursor_address, x, y) : "";
 }
 
+/* isupper/islower/toupper/tolower that work for '[{', '\\|', ']}', '^~' */
+#define isupper(x) (x < 'a'? 1: 0)
+#define islower(x) (x >= 'a'? 1: 0)
+#define toupper(x) (x < 'a'? x: x-32)
+#define tolower(x) (x >= 'a'? x: x+32)
 
 /*######  Exit/Interrput routines  #######################################*/
 
 // The usual program end -- called only by functions in this section.
@@ -1220,8 +1228,9 @@ static proc_t **procs_refresh (proc_t **
 // (own identifiers as documentation and protection against changes)
 #define L_stat     PROC_FILLSTAT
 #define L_statm    PROC_FILLMEM
 #define L_status   PROC_FILLSTATUS
+#define L_oom      PROC_FILLOOM
 #define L_CMDLINE  L_EITHER | PROC_FILLARG
 #define L_EUSER    PROC_FILLUSR
 #define L_RUSER    L_status | PROC_FILLUSR
 #define L_GROUP    L_status | PROC_FILLGRP
@@ -1273,8 +1282,10 @@ static FLD_t Fieldstab[] = {
    { "XxXx", " COMMAND",    " %-*.*s",  -1,    -1, SF(CMD), "Command name/line",    L_EITHER },
    { "YyUu", " WCHAN    ",  " %-9.9s",  -1,    -1, SF(WCH), "Sleeping in Function", L_stat   },
    // next entry's special: the 0's will be replaced with '.'!
    { "ZzZz", " Flags   ",   " %08lx",   -1,    -1, SF(FLG), "Task Flags <sched.h>", L_stat   },
+   { "[{[{", " Badness",    "%8d",      -1,    -1, SF(OOM), "oom_score (badness)",  L_oom    },
+   { "\\|\\|", " Adj",      " %3d",     -1,    -1, SF(OOA), "oom_adjustment (2^X)", L_oom    },
 #if 0
    { "..Qq", "   A",        " %4.4s",    4, SK_no, SF(PID), "Accessed Page count",  L_stat   },
    { "..Nn", "  TRS",       " %4.4s",    4, SK_Kb, SF(PID), "Code in memory (kb)",  L_stat   },
    { "..Rr", "  WP",        " %4.4s",    4, SK_no, SF(PID), "Unwritable Pages",     L_stat   },
@@ -1285,8 +1296,10 @@ static FLD_t Fieldstab[] = {
 #endif
 };
 #undef SF
 
+/* Last valid lowercase letter (z is folowed by {|}~, Z by [\\]^) */
+#define LAST_CHR '|'
 
         /* All right, those-that-follow -- Listen Up!
          * For the above table keys and the following present/future rc file
          * compatibility support, you have Mr. Albert D. Cahalan to thank.
@@ -1419,8 +1432,21 @@ static int rc_read_new (const char *cons
       RCW_t *ptr = &rc->win[i];
       cnt = sscanf(cp, "%3s\tfieldscur=%31s\n", ptr->winname, ptr->fieldscur);
       if (cnt != 2) return 5+100*i;  // OK to have less than 4 windows
       if (WINNAMSIZ <= strlen(ptr->winname)) return -6;
+      /* Handle upgrade */
+      if (strlen(DEF_FIELDS) - strlen(ptr->fieldscur) == 2) {
+	      const int ln = strlen(ptr->fieldscur);
+	      const unsigned char last = ptr->fieldscur[ln-1];
+	      /* If last field is command, insert two new fields prior to it */
+	      if (last == 'x' || last == 'X') {
+		      ptr->fieldscur[ln-1] = '{';
+		      ptr->fieldscur[ln  ] = '|';
+		      ptr->fieldscur[ln+1] = last;
+		      ptr->fieldscur[ln+2] = 0;
+	      } else
+	      	strcat(ptr->fieldscur, "{|");
+      }
       if (strlen(DEF_FIELDS) != strlen(ptr->fieldscur)) return -7;
       cp = strchr(cp, '\n');
       if (!cp++) return -(8+100*i);
 
@@ -1694,9 +1720,9 @@ static void confighlp (char *fields) {
       else           lower[c&0x1f]++;
    }
 
    c = 'a';
-   while (c <= 'z') {
+   while (c <= LAST_CHR) {
       if (upper[c&0x1f] && lower[c&0x1f]) {
          lower[c&0x1f] = 0;             // got both, so wipe out unseen column
          for (;;) {
             cp = strchr(fields, c);
@@ -3198,9 +3224,14 @@ static void task_show (const WIN_t *q, c
             } else {
                MKCOL(lookup_wchan(p->wchan, p->XXXID));
             }
             break;
-
+	 case P_OOM:
+	    MKCOL(p->oom_score);
+	    break;
+	 case P_OOA:
+	    MKCOL(p->oom_adj);
+	    break;
         } /* end: switch 'procflag' */
 
         rp = scat(rp, cbuf+advance);
    } /* end: for 'maxpflgs' */
Index: procps-3.2.7/top.h
===================================================================
--- procps-3.2.7.orig/top.h
+++ procps-3.2.7/top.h
@@ -250,9 +250,10 @@ enum pflag {
    P_PRI, P_NCE,
    P_CPN, P_CPU, P_TME, P_TM2,
    P_MEM, P_VRT, P_SWP, P_RES, P_COD, P_DAT, P_SHR,
    P_FLT, P_DRT,
-   P_STA, P_CMD, P_WCH, P_FLG
+   P_STA, P_CMD, P_WCH, P_FLG,
+   P_OOM, P_OOA,
 };
 
 
 ///////////////////////////////////////////////////////////////////////////
@@ -350,15 +351,15 @@ typedef struct WIN_t {
 #define RCF_EYECATCHER  "RCfile for "
 #define RCF_DEPRECATED  "Id:a, "
 
 // The default fields displayed and their order,
-#define DEF_FIELDS  "AEHIOQTWKNMbcdfgjplrsuvyzX"
+#define DEF_FIELDS  "AEHIOQTWKNMbcdfgjplrsuvyz{|X"
 // Pre-configured field groupss
-#define JOB_FIELDS  "ABcefgjlrstuvyzMKNHIWOPQDX"
-#define MEM_FIELDS  "ANOPQRSTUVbcdefgjlmyzWHIKX"
-#define USR_FIELDS  "ABDECGfhijlopqrstuvyzMKNWX"
+#define JOB_FIELDS  "ABcefgjlrstuvyzMKNHIWOPQD{|X"
+#define MEM_FIELDS  "ANOPQRSTUVbcdefgjlmyzWHIK{|X"
+#define USR_FIELDS  "ABDECGfhijlopqrstuvyzMKNW{|X"
 // Used by fields_sort, placed here for peace-of-mind
-#define NUL_FIELDS  "abcdefghijklmnopqrstuvwxyz"
+#define NUL_FIELDS  "abcdefghijklmnopqrstuvwxyz{|"
 
 
 // The default values for the local config file
 #define DEF_RCFILE { \
Index: procps-3.2.7/proc/readproc.h
===================================================================
--- procps-3.2.7.orig/proc/readproc.h
+++ procps-3.2.7/proc/readproc.h
@@ -138,9 +138,11 @@ typedef struct proc_t {
         fuid, fgid,     // status          fs (used for file access only)
 	tpgid,		// stat            terminal process group id
 	exit_signal,	// stat            might not be SIGCHLD
 	processor;      // stat            current (or most recent?) CPU
-    	char **cgroup;  // cgroup	   current cgroup, looks like a classic filepath
+    int oom_score,	// oom_score	   (badness for OOM killer)
+	oom_adj;	// oom_adj	   (adjustment to OOM score)
+    char **cgroup;  // cgroup	   current cgroup, looks like a classic filepath
 } proc_t;
 
 // PROCTAB: data structure holding the persistent information readproc needs
 // from openproc().  The setup is intentionally similar to the dirent interface
@@ -240,8 +242,9 @@ extern proc_t * get_proc_stats(pid_t pid
 
 #define PROC_LOOSE_TASKS     0x0200 // threat threads as if they were processes
 
 #define PROC_FILLCGROUP      0x0400 // alloc and fill in `cgroup`
+#define PROC_FILLOOM	     0x0800 // alloc and fill in oom_score, oom_adj
 
 // Obsolete, consider only processes with one of the passed:
 #define PROC_PID             0x1000  // process id numbers ( 0   terminated)
 #define PROC_UID             0x4000  // user id numbers    ( length needed )
Index: procps-3.2.7/proc/readproc.c
===================================================================
--- procps-3.2.7.orig/proc/readproc.c
+++ procps-3.2.7/proc/readproc.c
@@ -331,8 +331,19 @@ ENTER(0x220);
 LEAVE(0x220);
 }
 
 ///////////////////////////////////////////////////////////////////////
+static void oomscore2proc(const char* S, proc_t *restrict P)
+{
+    sscanf(S, "%d", &P->oom_score);
+}
+
+static void oomadj2proc(const char* S, proc_t *restrict P)
+{
+    sscanf(S, "%d", &P->oom_adj);
+}
+
+///////////////////////////////////////////////////////////////////////
 
 // Reads /proc/*/stat files, being careful not to trip over processes with
 // names like ":-) 1 2 3 4 5 6".
 static void stat2proc(const char* S, proc_t *restrict P) {
@@ -616,8 +627,15 @@ static proc_t* simple_readproc(PROCTAB *
 	p->environ = file2strvec(path, "environ");
     else
         p->environ = NULL;
 
+    if (unlikely(flags & PROC_FILLOOM)) {
+       if (likely( file2str(path, "oom_score", sbuf, sizeof sbuf) != -1 ))
+           oomscore2proc(sbuf, p);
+       if (likely( file2str(path, "oom_adj", sbuf, sizeof sbuf) != -1 ))
+           oomadj2proc(sbuf, p);
+    } /* struct has been zeroed out before, so no worries about clearing garbage here */
+
     if(linux_version_code>=LINUX_VERSION(2,6,24) && (flags & PROC_FILLCGROUP)) {
 	p->cgroup = file2strvec(path, "cgroup"); 	/* read /proc/#/cgroup */
     	if(p->cgroup && *p->cgroup) {
 		int i = strlen(*p->cgroup);
openSUSE Build Service is sponsored by