From c8b820d04f6890a674712458cfafeb667e5a3625 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Tue, 4 Oct 2011 20:16:46 +0200 Subject: [PATCH 01/21] build-sys: add --disable-kill build option The kill from procps-ng is not always wanted. For example RedHat seems to prefer kill from util-linux package. Reported-by: Jaromir Capik Signed-off-by: Sami Kerola --- Makefile.am | 9 +++++---- configure.ac | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 890f71bc..82ac8e6a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,9 +9,6 @@ AM_LDFLAGS = ./proc/libproc-ng.la sbin_PROGRAMS = \ sysctl -bin_PROGRAMS = \ - kill - usrbin_exec_PROGRAMS = \ free \ pgrep \ @@ -27,7 +24,6 @@ usrbin_exec_PROGRAMS = \ dist_man_MANS = \ free.1 \ - kill.1 \ pgrep.1 \ pkill.1 \ pmap.1 \ @@ -41,6 +37,11 @@ dist_man_MANS = \ vmstat.8 \ w.1 +if BUILD_KILL +bin_PROGRAMS = kill +dist_man_MANS += kill.1 +endif + if HAVE_NCURSES usrbin_exec_PROGRAMS += \ slabtop \ diff --git a/configure.ac b/configure.ac index aa124050..bcc0264c 100644 --- a/configure.ac +++ b/configure.ac @@ -142,6 +142,12 @@ if test "x$with_ncurses" != xno; then fi AC_SUBST([NCURSES_LIBS]) +AC_ARG_ENABLE([kill], + AS_HELP_STRING([--disable-kill], [do not build kill]), + [], enable_kill=yes +) +AM_CONDITIONAL(BUILD_KILL, test "x$enable_kill" = xyes) + AC_ARG_ENABLE([oomem], AS_HELP_STRING([--enable-oomem], [add out-of-memory fields to the library and top]), [], enable_oomem=no From 6d42a58200ceccd298ede647fce868c7db4bbdec Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Tue, 4 Oct 2011 20:40:19 +0200 Subject: [PATCH 02/21] build-sys: add --enable-w-from build option Some distributions apparently want to have w command to print FROM field by default. Reported-by: Jaromir Capik Signed-off-by: Sami Kerola --- configure.ac | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configure.ac b/configure.ac index bcc0264c..183e24a9 100644 --- a/configure.ac +++ b/configure.ac @@ -156,6 +156,14 @@ if test "x$enable_oomem" = xyes; then AC_DEFINE(OOMEM_ENABLE, 1, [add out-of-memory fields to the library and top]) fi +AC_ARG_ENABLE([w-from], + AS_HELP_STRING([--enable-w-from], [enable w from field by default]), + [], enable_w_from=no +) +if test "x$enable_w_from" = xyes; then + AC_DEFINE(W_SHOWFROM, 1, [enable w from field by default]) +fi + AC_CONFIG_FILES([ Makefile proc/Makefile From ee2e674182a008f66d82ab9d25eb117057458c60 Mon Sep 17 00:00:00 2001 From: jimmy jam Date: Tue, 4 Oct 2011 12:16:30 -0500 Subject: [PATCH 03/21] add the customary redhat FAQ --- FAQ | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 FAQ diff --git a/FAQ b/FAQ new file mode 100644 index 00000000..ae9df265 --- /dev/null +++ b/FAQ @@ -0,0 +1,82 @@ +Why does "ps -aux" complain about a bogus '-'? + +According to the POSIX and UNIX standards, the above command asks to display +all processes with a TTY (generally the commands users are running) plus all +processes owned by a user named "x". If that user doesn't exist, then ps will +assume you really meant "ps aux". The warning is given to gently break you of a +habit that will cause you trouble if a user named "x" were created. + + +Why don't I see SMP (per-CPU) stats in top? + +You didn't enable it. Press '?' for built-in help or read the man page. Per-CPU +stats are disabled by default because they take up too much space. Some Linux +systems have hundreds of CPUs. + + +Why do long usernames get printed as numbers? + +The UNIX and POSIX standards require that user names and group names be printed +as decimal integers when there is not enough room in the column. Truncating the +names, besides being a violation of the standard, would lead to confusion +between names like MichelleRichards and MichelleRichardson. The UNIX and POSIX +way to change column width is to rename the column: + + ps -o pid,user=CumbersomeUserNames -o comm + +The easy way is to directly specify the desired width: + + ps -o pid,user:19,comm + + +Why is %CPU underreported for multi-threaded (Java, etc.) apps? + +You need to upgrade to the 2.6.10 kernel at least. Older kernels do not provide +a reasonable way to get this information. + + +Why do ps and top show threads individually? + +The 2.4.xx kernel does not provide proper support for grouping threads by +process. Hacks exist to group them anyway, but such hacks will falsely group +similar tasks and will fail to group tasks due to race conditions. The hacks +are also slow. As none of this is acceptable in a critical system tool, task +grouping is not currently available for the 2.4.xx kernel. The 2.6.xx kernel +allows for proper thread grouping and reporting. To take advantage of this, +your programs must use a threading library that features the CLONE_THREAD flag. +The NPTL pthreads provided by recent glibc releases use CLONE_THREAD. + + +What systems are supported? + +Linux 2.4.xx and 2.6.xx are commonly tested and expected to work well. SMP is +well supported. Multi-node cluster views require a multi-node /proc filesystem; +without that you will see a single-node view. + + +Where to I send bug reports? + +You may use the Debian bug tracking system or send your report to +procps-feedback@lists.sf.net (no subscription required) instead. + + +Why are there so many procps projects? + +The original maintainer seems to have had little time for procps. Whatever his +reasons, the project didn't get maintained. Starting in 1997, Albert Cahalan +wrote a new ps program for the package. For the next few years, Albert quietly +helped the Debian package maintainer fix bugs. In 2001, Rik van Riel decided to +do something about what appeared to be the lack of a maintainer. He picked up +the buggy old code in Red Hat's CVS and started adding patches. Meanwhile, +other people have patched procps in a great many ways. In 2002, Albert moved +procps to this site. This was done to ensure that years of testing and bug +fixes would not be lost. The major version number was changed to 3, partly to +avoid confusing users and partly because the top program has been redone. + + +Why does ps get signal 17? + +No ps release has ever had this problem. Most likely your system has been +broken into. You might want to install a more recent version of the OS. If +you'd rather take your chances, simply upgrade procps. + From d73bd233ca4f5734ef0cfda20a8055dc479d2b42 Mon Sep 17 00:00:00 2001 From: jimmy jam Date: Tue, 4 Oct 2011 12:17:23 -0500 Subject: [PATCH 04/21] adapt redhat FAQ for procps-ng --- FAQ | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/FAQ b/FAQ index ae9df265..c68bf7bc 100644 --- a/FAQ +++ b/FAQ @@ -57,7 +57,7 @@ without that you will see a single-node view. Where to I send bug reports? You may use the Debian bug tracking system or send your report to -procps-feedback@lists.sf.net (no subscription required) instead. +procps@freelists.org (no subscription required) instead. Why are there so many procps projects? @@ -68,10 +68,27 @@ wrote a new ps program for the package. For the next few years, Albert quietly helped the Debian package maintainer fix bugs. In 2001, Rik van Riel decided to do something about what appeared to be the lack of a maintainer. He picked up the buggy old code in Red Hat's CVS and started adding patches. Meanwhile, -other people have patched procps in a great many ways. In 2002, Albert moved -procps to this site. This was done to ensure that years of testing and bug -fixes would not be lost. The major version number was changed to 3, partly to -avoid confusing users and partly because the top program has been redone. +other people have patched procps in a great many ways. + +In 2002, Albert moved procps to http://procps.sourceforge.net. This was done to +ensure that years of testing and bug fixes would not be lost. The major version +number was changed to 3, partly to avoid confusing users and partly because the +top program had been redone. + +After development essentially stopped on sourceforge.net, in 2011 the project +found a new home at http://gitorious.org/procps. This represents the Debian, +Fedora and openSUSE fork of procps. To avoid confusion and potential name +clashes the package is now known as procps-ng (next generation), the version +number was raised to 3.3.0 and the library soname changed to libproc-ng-3.3.0. + + +What is being done to procps-ng at its new home? + +All programs are in the process of being modernized, both in terms of coding +style and supporting documentation. Autotools have been integrated and the +library API has been expanded with many new fields supported such as control +groups, supplementary groups, etc. The top program has been rewritten offering +many new capabilities while providing performance improvements up to 300%. Why does ps get signal 17? From ab27c0050c5516fec0c4e3006a1c2bad939eb600 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Thu, 6 Oct 2011 16:26:24 +0200 Subject: [PATCH 05/21] build-sys: add BUGS, FAQ and README.top to distribution After `make install' I expect to see some files in /share/doc/procps-ng directory, this commit adds few most obvious ones to there. Signed-off-by: Sami Kerola --- Makefile.am | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 82ac8e6a..25925b31 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,12 +65,16 @@ sysconf_DATA = sysctl.conf EXTRA_DIST = \ autogen.sh \ - BUGS \ CodingStyle \ contrib/dummy.c \ contrib/minimal.c \ contrib/tmp-junk.c \ contrib/utmp.c \ COPYING.LIB \ - README.top \ $(sysconf_DATA) + +procpsngdir = $(docdir) +dist_procpsng_DATA = \ + BUGS \ + FAQ \ + README.top From f9ae59f5dfec00a1dc5f8e5c4354eb523113434c Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sat, 8 Oct 2011 19:02:58 -0500 Subject: [PATCH 06/21] libtool accommodation: kill, skill, snice --- skill.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/skill.c b/skill.c index 96cc386e..1aa1a54d 100644 --- a/skill.c +++ b/skill.c @@ -46,8 +46,7 @@ static int saved_argc; static int sig_or_pri; -static int program; -#define PROG_GARBAGE 0 /* keep this 0 */ +static int program = -1; #define PROG_KILL 1 #define PROG_SKILL 2 /* #define PROG_NICE 3 */ /* easy, but the old one isn't broken */ @@ -558,17 +557,13 @@ int main(int argc, const char *argv[]){ tmpstr=strrchr(*argv,'/'); if(tmpstr) tmpstr++; if(!tmpstr) tmpstr=*argv; - program = PROG_GARBAGE; - if(*tmpstr=='s'){ - setpriority(PRIO_PROCESS,my_pid,-20); - if(!strcmp(tmpstr,"snice")) program = PROG_SNICE; - if(!strcmp(tmpstr,"skill")) program = PROG_SKILL; - }else{ - if(!strcmp(tmpstr,"kill")) program = PROG_KILL; - } + if(strstr(tmpstr,"kill")) program = PROG_KILL; + if(strstr(tmpstr,"skill")) program = PROG_SKILL; + if(strstr(tmpstr,"snice")) program = PROG_SNICE; switch(program){ case PROG_SNICE: case PROG_SKILL: + setpriority(PRIO_PROCESS,my_pid,-20); skillsnice_parse(argc, argv); /* show_lists(); */ iterate(); /* this is it, go get them */ From 4820619f15b02c6f40b8421e519af5ddcba624bc Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 08:34:26 -0500 Subject: [PATCH 07/21] redhat analysis: proc/readproc --- proc/readproc.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/proc/readproc.c b/proc/readproc.c index 4949704e..45ec4150 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -1112,15 +1112,13 @@ next_proc: } next_task: - for (;;) { - // fills in our path, plus x->tid and x->tgid - if ((!(PT->taskfinder(PT,&skel_p,x,path))) // simple_nexttid - || (!(ret = PT->taskreader(PT,new_p,x,path)))) { // simple_readtask - goto next_proc; - } - if (!new_p) new_p = ret; - return ret; + // fills in our path, plus x->tid and x->tgid + if ((!(PT->taskfinder(PT,&skel_p,x,path))) // simple_nexttid + || (!(ret = PT->taskreader(PT,new_p,x,path)))) { // simple_readtask + goto next_proc; } + if (!new_p) new_p = ret; + return ret; end_procs: if (!saved_x) free(x); @@ -1152,7 +1150,7 @@ PROCTAB* openproc(int flags, ...) { PT->finder = listed_nextpid; }else{ PT->procfs = opendir("/proc"); - if(!PT->procfs) return NULL; + if(!PT->procfs) { free(PT); return NULL; } PT->finder = simple_nextpid; } PT->flags = flags; From b49055e65752d340963d7070ee177d4d7f0b82b7 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 09:12:55 -0500 Subject: [PATCH 08/21] redhat analysis: proc/sysinfo --- proc/sysinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proc/sysinfo.c b/proc/sysinfo.c index 5e224f12..a919f3f6 100644 --- a/proc/sysinfo.c +++ b/proc/sysinfo.c @@ -845,8 +845,8 @@ unsigned int getdiskstat(struct disk_stat **disks, struct partition_stat **parti break; } fields = sscanf(buff, " %*d %*d %*s %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u", &dummy); + (*disks) = realloc(*disks, (cDisk+1)*sizeof(struct disk_stat)); if (fields == 1){ - (*disks) = realloc(*disks, (cDisk+1)*sizeof(struct disk_stat)); sscanf(buff, " %*d %*d %15s %u %u %llu %u %u %u %llu %u %u %u %u", //&disk_major, //&disk_minor, From 0ebe39734529a1a93240e9044c5ac340bd7bc982 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 09:40:36 -0500 Subject: [PATCH 09/21] redhat analysis: proc/slab --- proc/slab.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proc/slab.c b/proc/slab.c index 60c56960..d53b327d 100644 --- a/proc/slab.c +++ b/proc/slab.c @@ -312,11 +312,13 @@ int get_slabinfo(struct slab_info **list, struct slab_stat *stats) if (!fgets(buffer, SLABINFO_VER_LEN, slabfile)) { fprintf(stderr, "cannot read from slabinfo\n"); + free(slabfile); return 1; } if (sscanf(buffer, "slabinfo - version: %d.%d", &major, &minor) != 2) { fprintf(stderr, "not the good old slabinfo we know\n"); + free(slabfile); return 1; } @@ -328,6 +330,7 @@ int get_slabinfo(struct slab_info **list, struct slab_stat *stats) ret = parse_slabinfo10(list, stats, slabfile); else { fprintf(stderr, "unrecognizable slabinfo version\n"); + free(slabfile); return 1; } From 8f3303e4d82df697af8e7363b3a48012c1e1dfb9 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 09:31:00 -0500 Subject: [PATCH 10/21] redhat analysis: proc/sig --- proc/sig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proc/sig.c b/proc/sig.c index ea633973..3d6e0584 100644 --- a/proc/sig.c +++ b/proc/sig.c @@ -214,7 +214,7 @@ void pretty_print_signals(void){ while(++i <= number_of_signals){ int n; n = printf("%2d %s", i, signal_number_to_name(i)); - if(i%7) printf(" \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n); + if(n>0 && i%7) printf(" \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n); else printf("\n"); } if((i-1)%7) printf("\n"); From 6317f8e685dd9063a28bf53a16513cbfc7a50516 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 10:43:30 -0500 Subject: [PATCH 11/21] redhat analysis: ps/parser --- ps/parser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ps/parser.c b/ps/parser.c index 3e8f8875..70d94fe1 100644 --- a/ps/parser.c +++ b/ps/parser.c @@ -119,6 +119,7 @@ static const char *parse_gid(char *str, sel_union *ret){ static const char *parse_cmd(char *str, sel_union *ret){ strncpy(ret->cmd, str, sizeof ret->cmd); // strncpy pads to end + ret->cmd[sizeof(ret->cmd)-1] = '\0'; // but let's be safe return 0; } From 0e663aacbc86257b8220a68c66cb6302aa50ec80 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 11:05:39 -0500 Subject: [PATCH 12/21] redhat analysis: ps/display --- ps/display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ps/display.c b/ps/display.c index 0c5e6753..74d1119b 100644 --- a/ps/display.c +++ b/ps/display.c @@ -379,7 +379,7 @@ static void prep_forest_sort(void){ if(!sort_list) { /* assume start time order */ incoming = search_format_array("start_time"); - if(!incoming) fprintf(stderr, "Could not find start_time!\n"); + if(!incoming) { fprintf(stderr, "Could not find start_time!\n"); exit(1); } tmp_list = malloc(sizeof(sort_node)); tmp_list->reverse = 0; tmp_list->typecode = '?'; /* what was this for? */ @@ -390,7 +390,7 @@ static void prep_forest_sort(void){ } /* this is required for the forest option */ incoming = search_format_array("ppid"); - if(!incoming) fprintf(stderr, "Could not find ppid!\n"); + if(!incoming) { fprintf(stderr, "Could not find ppid!\n"); exit(1); } tmp_list = malloc(sizeof(sort_node)); tmp_list->reverse = 0; tmp_list->typecode = '?'; /* what was this for? */ From ba13a764224674188aa9106b291fcafdd67dd488 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 11:20:41 -0500 Subject: [PATCH 13/21] redhat analysis: ps/sortformat --- ps/sortformat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ps/sortformat.c b/ps/sortformat.c index 36d5d435..dec351e8 100644 --- a/ps/sortformat.c +++ b/ps/sortformat.c @@ -103,7 +103,7 @@ static void O_wrap(sf_node *sfn, int otype){ endp->next = fnode; fnode = do_one_spec(trailer,NULL); - if(!fnode)fprintf(stderr,"Seriously crashing. Goodbye cruel world.\n"); + if(!fnode) { fprintf(stderr,"Seriously crashing. Goodbye cruel world.\n"); exit(1); } endp = fnode; while(endp->next) endp = endp->next; /* find end */ endp->next = sfn->f_cooked; sfn->f_cooked = fnode; From 415c593ad52e0c5fbf317b52baa2b8eb42bfc805 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 10:02:06 -0500 Subject: [PATCH 14/21] redhat analysis: vmstat --- vmstat.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vmstat.c b/vmstat.c index e0d3c23f..756ec4f9 100644 --- a/vmstat.c +++ b/vmstat.c @@ -303,6 +303,8 @@ static int diskpartition_format(const char* partition_name){ } } if(!current_partition){ + free(disks); + free(partitions); return -1; } diskpartition_header(partition_name); @@ -323,6 +325,8 @@ static int diskpartition_format(const char* partition_name){ } } if(!current_partition){ + free(disks); + free(partitions); return -1; } printf (format, @@ -422,7 +426,7 @@ static void slabformat (void){ fSlab=fopen("/proc/slabinfo", "rb"); if(!fSlab){ - fprintf(stderr, "Your kernel doesn't support slabinfo.\n"); + fprintf(stderr, "Your kernel doesn't support slabinfo or your permissions are insufficient.\n"); return; } @@ -454,6 +458,7 @@ static void slabformat (void){ } free(slabs); } + free(fSlab); } //////////////////////////////////////////////////////////////////////////// From b23baee15cb8bef5bd1b922fc63ea85b2f31848c Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 15:58:26 -0500 Subject: [PATCH 15/21] redhat analysis: pgrep --- pgrep.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pgrep.c b/pgrep.c index bbb7cd11..5492fa72 100644 --- a/pgrep.c +++ b/pgrep.c @@ -193,19 +193,22 @@ static union el *read_pidfile(void) int fd; struct stat sbuf; char *endp; - int pid; + int n, pid; union el *list = NULL; fd = open(opt_pidfile, O_RDONLY|O_NOCTTY|O_NONBLOCK); if(fd<0) - goto out; + goto just_ret; if(fstat(fd,&sbuf) || !S_ISREG(sbuf.st_mode) || sbuf.st_size<1) goto out; // type of lock, if any, is not standardized on Linux if(opt_lock && !has_flock(fd) && !has_fcntl(fd)) - goto out; + goto out; memset(buf,'\0',sizeof buf); - buf[read(fd,buf+1,sizeof buf-2)] = '\0'; + n = read(fd,buf+1,sizeof buf-2); + if (n<1) + goto out; + buf[n] = '\0'; pid = strtoul(buf+1,&endp,10); if(endp<=buf+1 || pid<1 || pid>0x7fffffff) goto out; @@ -216,6 +219,7 @@ static union el *read_pidfile(void) list[1].num = pid; out: close(fd); +just_ret: return list; } @@ -376,6 +380,7 @@ static PROCTAB *do_openproc (void) } flags |= PROC_UID; ptp = openproc (flags, uids, num); + free(uids); } else { ptp = openproc (flags); } @@ -404,6 +409,7 @@ static regex_t * do_regcomp (void) } re_err = regcomp (preg, re, REG_EXTENDED | REG_NOSUB | opt_case); + free(re); if (re_err) { regerror (re_err, preg, errbuf, sizeof(errbuf)); fputs(errbuf,stderr); @@ -530,8 +536,8 @@ static union el * select_procs (int *num) memset (&task, 0, sizeof (task)); } closeproc (ptp); - *num = matches; + free(preg); return list; } From 3f7539056347571fcda0b75f2bb49fb972c49038 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Thu, 6 Oct 2011 12:21:28 -0500 Subject: [PATCH 16/21] redhat analysis: pwdx --- pwdx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pwdx.c b/pwdx.c index bda1bf11..ac42736b 100644 --- a/pwdx.c +++ b/pwdx.c @@ -35,7 +35,7 @@ static void version(void) int main(int argc, char* argv[]) { - char buf[PATH_MAX+1]; + static char buf[PATH_MAX+1]; // null terminate string via static regex_t re; int i; From 9408b9721b8d21301014ec549e3ab66eb124be6d Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Tue, 18 Oct 2011 03:43:25 -0500 Subject: [PATCH 17/21] rh analysis #2: tload http://www.freelists.org/post/procps/Scan-results,5 --- tload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tload.c b/tload.c index 1d346bbe..14c02166 100644 --- a/tload.c +++ b/tload.c @@ -87,7 +87,7 @@ int main(int argc, char **argv) if (argc > optind) { if ((fd = open(argv[optind], 1)) == -1) { - perror(argv[optind]); + perror("tty"); exit(1); } } From d3786c5321e3848f60021c08fbbd5be85536a1b5 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Tue, 18 Oct 2011 02:36:22 -0500 Subject: [PATCH 18/21] rh analysis #2: pmap http://www.freelists.org/post/procps/Scan-results,5 --- pmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmap.c b/pmap.c index 24a4e427..9fcaa2af 100644 --- a/pmap.c +++ b/pmap.c @@ -311,7 +311,7 @@ int main(int argc, char *argv[]){ char *arg2 = strchr(arg1,','); if(arg2) *arg2 = '\0'; - arg2 = arg2 ? arg2++ : arg1; + arg2 = *arg2 ? arg2++ : arg1; if(*arg1) range_low = STRTOUKL(arg1,&arg1,16); From cea2e7ca5b9d697945d8a42c1dc48c5f6878f360 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Wed, 12 Oct 2011 00:55:12 -0500 Subject: [PATCH 19/21] rh analysis #2: top http://www.freelists.org/post/procps/Scan-results,5 --- top.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/top.c b/top.c index b7beb4da..9a8c66c9 100644 --- a/top.c +++ b/top.c @@ -1412,7 +1412,7 @@ static void calibrate_fields (void) { f = w->pflgsall[i + w->begpflg]; w->procflgs[i] = f; #ifndef USE_X_COLHDR - if (P_MAXPFLGS < f) continue; + if (P_MAXPFLGS <= f) continue; #endif h = Fieldstab[f].head; // oops, won't fit -- we're outta here... @@ -1463,7 +1463,7 @@ static void calibrate_fields (void) { w->hdrcaplen += strlen(Caps_off) + strlen(w->capclr_msg); } #else - if (P_MAXPFLGS < f) continue; + if (P_MAXPFLGS <= f) continue; #endif h = Fieldstab[f].head; if (P_WCH == f) needpsdb = 1; @@ -3334,8 +3334,8 @@ static void summary_show (void) { int shift = 0; /*** hotplug_acclimated ***/ - if (kb_main_total > 9999999) { which = "Mb"; shift = 10; } - if (kb_main_total > 9999999999) { which = "Gb"; shift = 20; } + if (kb_main_total > 9999999) { which = "Mb"; shift = 10; } + if (kb_main_total > 9999999999ull) { which = "Gb"; shift = 20; } show_special(0, fmtmk(MEMORY_twolines , which, mkM(total), mkM(used), mkM(free), mkM(buffers) From db6a427ecfb3d23cd8f43f151622b17e37e3e04c Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Wed, 19 Oct 2011 09:39:36 +0200 Subject: [PATCH 20/21] docs: add rh analysis #2 information to contrib Reference information. Signed-off-by: Sami Kerola --- Makefile.am | 5 +- contrib/response.filtered-with-patches.err | 312 +++++++++++++++++++++ 2 files changed, 313 insertions(+), 4 deletions(-) create mode 100644 contrib/response.filtered-with-patches.err diff --git a/Makefile.am b/Makefile.am index 25925b31..9ca3c53b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -66,10 +66,7 @@ sysconf_DATA = sysctl.conf EXTRA_DIST = \ autogen.sh \ CodingStyle \ - contrib/dummy.c \ - contrib/minimal.c \ - contrib/tmp-junk.c \ - contrib/utmp.c \ + contrib/ \ COPYING.LIB \ $(sysconf_DATA) diff --git a/contrib/response.filtered-with-patches.err b/contrib/response.filtered-with-patches.err new file mode 100644 index 00000000..ae6cda01 --- /dev/null +++ b/contrib/response.filtered-with-patches.err @@ -0,0 +1,312 @@ +See http://www.freelists.org/post/procps/Scan-results,5 + + + based on: +filtered-with-patches.err + + these are the categories i've assigned: +defect_was_fixed + EVALUATION_ORDER + pmap + TAINTED_STRING + tload + +possibly_filter_out_? + MISSING_BREAK + slabtop + ps/output + +avoidable_false_positive + DEADCODE + proc/readproc + FORWARD_NULL + top + vmstat + RESOURCE_LEAK + ps/parser (3) + STRING_NULL + pwdx + proc/readproc + TAINTED_SCALAR + pgrep + slabtop + top (3) + TAINTED_STRING + watch (2) + TOCTOU + sysctl (2) + UNINIT + ps/output (2) + +unavoidable_false_positive_? + UNREACHABLE + ps/sortformat + +unavoidable_false_positive_but_patched_anyway + OVERRUN_STATIC + top (no defect, but i yield) + + + + pgrep ------------------------------------------------------------------------ +Error: TAINTED_SCALAR: + agree that argv might be tainted + but the (int)argv[1][1] index is being passed to isdigit() function (and glibc safely indexes into array sized at 384 bytes) + my_category: avoidable_false_positive (out of step with current glibc implementation) +pgrep.c:720: tainted_data: Passing tainted variable "argv" to a tainted sink. +pgrep.c:558: data_index: Using tainted variable "(int)argv[1][1]" as an index to pointer "*__ctype_b_loc()". + + + pmap ------------------------------------------------------------------------- +Error: EVALUATION_ORDER: + agree that there is a problem. + moreover, it deals with an undocumented command line argument (but sami has documentation addition pending) + a deference was added in line with intent, hopefully avoids this warning + my_category: defect_was_fixed +pmap.c:314: write_write_order: In "arg2 = (arg2 ? arg2++ : arg1)", "arg2" is written in "arg2" (the assignment left-hand side) and written in "arg2 ? arg2++ : arg1" but the order in which the side effects take place is undefined because there is no intervening sequence point. + + + + pwdx ------------------------------------------------------------------------- +Error: STRING_NULL: + static buffer is initialized to 0 + it is +1 larger than size passed to readlink + was fixed in previous analysis + my_category: avoidable_false_positive +pwdx.c:86: string_null_argument: Function "readlink" does not terminate string "*buf". +pwdx.c:73: var_assign_var: Assigning: "s" = "buf". Both now point to the same unterminated string. +pwdx.c:73: var_assign_var: Assigning: "s" = "buf". Both now point to the same unterminated string. +pwdx.c:73: var_assign_var: Assigning: "s" = "buf". Both now point to the same unterminated string. +pwdx.c:92: string_null: Passing unterminated string "s" to "printf". + + + + slabtop ---------------------------------------------------------------------- +Error: MISSING_BREAK: + intentional fall through after setting return code + no change made + my_category: possibly_filter_out_? +slabtop.c:314: unterminated_case: This case (value 104) is not terminated by a 'break' statement. +slabtop.c:316: fallthrough: The above case falls through to this one. + +Error: TAINTED_SCALAR: + read limited to single byte signed 'char' + ultimately passed to toupper() function (and glibc safely indexes into array sized at 384 bytes) + my_category: avoidable_false_positive (out of step with current glibc implementation) +slabtop.c:387: tainted_data_argument: Calling function "read" taints argument "c". +slabtop.c:389: tainted_data: Passing tainted variable "c" to a tainted sink. +slabtop.c:233: data_index: Using tainted variable "(int)c" as an index to pointer "*__ctype_toupper_loc()". + + + + sysctl ----------------------------------------------------------------------- +Error: TOCTOU: + the pathlength between these two events cannot be reduced further + instead of assessing intervening lines of code, perhaps tool should assess 'if' statements (2) + my_category: avoidable_false_positive +sysctl.c:149: fs_check_call: Calling function "stat" to perform check on "tmpname". +sysctl.c:168: toctou: Calling function "fopen" that uses "tmpname" after a check function. This can cause a time-of-check, time-of-use race condition. + +Error: TOCTOU: + the pathlength between these two events cannot be reduced further + instead of assessing intervening lines of code, perhaps tool should assess 'if' statements (2) + my_category: avoidable_false_positive +sysctl.c:327: fs_check_call: Calling function "stat" to perform check on "tmpname". +sysctl.c:345: toctou: Calling function "fopen" that uses "tmpname" after a check function. This can cause a time-of-check, time-of-use race condition. + + + + tload ------------------------------------------------------------------------ +Error: TAINTED_STRING: + altered perror call to provide an untainted string + my_category: defect_was_fixed +tload.c:89: tainted_string: Passing tainted string "argv[optind]" to a function that cannot accept tainted data. + + + + top -------------------------------------------------------------------------- +Error: FORWARD_NULL: + cpus cannot be NULL without fp also being NULL + the very next 'if (!fp)' ensures cpus will be allocated + my_category: avoidable_false_positive +top.c:1790: assign_zero: Assigning: "cpus" = 0. +top.c:1807: var_deref_op: Dereferencing null variable "cpus". + +Error: OVERRUN_STATIC: + This "error" is centered around the following code: + f = w->pflgsall[i + w->begpflg]; + w->procflgs[i] = f; + #ifndef USE_X_COLHDR + if (P_MAXPFLGS < f) continue; + #endif + h = Fieldstab[f].head; + + The enum P_MAXPFLGS is strictly a fencepost and can *never* appear in the arrays pflgsall or procflgs. + Thus it (39th element) cannot be used in referencing Fieldstab. + However, two enums of higher value (X_XON=40 and X_XOF=41) *can* appear in those arrays. + But the test against the fencepost ensures that those two enums are *never* used in referencing Fieldstab. + + When the analyzer sees the conditional using '<' and not '<=' it reports a false positive. + + i'm tired of explaining this so the program was changed to accommodate the tool's deficiency + my_category: unavoidable_false_positive_but_patched_anyway +top.c:1417: overrun-local: Overrunning static array "Fieldstab", with 39 elements, at position 39 with index variable "f". + +Error: TAINTED_SCALAR: + the index is used subordinate to a case statement ensuring a value between '1' and '4' + my_category: avoidable_false_positive +top.c:2442: tainted_data_argument: Calling function "chin" taints argument "ch". +top.c:848: tainted_data_argument: Calling function "read" taints parameter "*buf". +top.c:2452: tainted_data: Using tainted variable "ch - 49" as an index into an array "Winstk". + +Error: TAINTED_SCALAR: + the index is used subordinate to as case statement ensuring a value between '1' and '4' + my_category: avoidable_false_positive +top.c:2719: tainted_data_argument: Calling function "chin" taints argument "ch". +top.c:848: tainted_data_argument: Calling function "read" taints parameter "*buf". +top.c:2720: tainted_data: Passing tainted variable "ch" to a tainted sink. +top.c:2452: data_index: Using tainted variable "ch - 49" as an index to array "Winstk". + +Error: TAINTED_SCALAR: + buf tainted by chin is zero terminated + single char is ultimately passed to isprintf() function (and glibc safely indexes into array sized at 384 bytes) + my_category: avoidable_false_positive (out of step with current glibc implementation) +top.c:972: tainted_data_return: Function "keyin" returns tainted data. +top.c:912: tainted_data_argument: Function "chin" taints argument "buf". +top.c:848: tainted_data_argument: Calling function "read" taints parameter "*buf". +top.c:926: return_tainted_data: Returning tainted variable "buf[0]". +top.c:972: var_assign: Assigning: "key" = "keyin", which taints "key". +top.c:1001: tainted_data: Using tainted variable "(int)key" as an index to pointer "*__ctype_b_loc()". + + + + vmstat ----------------------------------------------------------------------- +Error: FORWARD_NULL: + partition made non-null with optarg for -p where statMode |= PARTITIONSTAT + if no optarg then program exits with usage + thus call to diskpartition_format will be with non-null pointer + my_category: avoidable_false_positive +vmstat.c:593: assign_zero: Assigning: "partition" = 0. +vmstat.c:669: var_deref_model: Passing null variable "partition" to function "diskpartition_format", which dereferences it. +vmstat.c:301: deref_parm_in_call: Function "strcmp" dereferences parameter "partition_name". (The dereference is assumed on the basis of the 'nonnull' parameter attribute.) + + + + watch ------------------------------------------------------------------------ +Error: TAINTED_STRING: + even though the environment variable COLUMNS might begin tainted, from my analysis, the tool is totally mistaken + strtol actually untaints data in the form of 't' and 'endptr' then the environment variable COLUMNS is potentially purified with -1 + my_category: avoidable_false_positive +watch.c:95: tainted_string_return_content: "getenv" returns tainted string content. +watch.c:95: var_assign: Assigning: "s" = "getenv("COLUMNS")", which taints "s". +watch.c:100: tainted_data_transitive: Call to function "strtol" with tainted argument "s" returns tainted data. +watch.c:100: var_assign: Assigning: "t" = "strtol(s, &endptr, 0)", which taints "t". +watch.c:101: var_assign_var: Assigning: "incoming_cols" = "(int)t". Both are now tainted. +watch.c:102: var_assign_var: Assigning: "width" = "incoming_cols". Both are now tainted. +watch.c:103: vararg_transitive: Call to "snprintf" with tainted argument "width" taints "env_col_buf". +watch.c:104: tainted_string: Passing tainted string "env_col_buf" to a function that cannot accept tainted data. + +Error: TAINTED_STRING: + even though the environment variable LINES might begin tainted, from my analysis, the tool is totally mistaken + strtol actually untaints data in the form of 't' and 'endptr' then the environment variable LINES is potentially purified with -1 + my_category: avoidable_false_positive +watch.c:108: tainted_string_return_content: "getenv" returns tainted string content. +watch.c:108: var_assign: Assigning: "s" = "getenv("LINES")", which taints "s". +watch.c:113: tainted_data_transitive: Call to function "strtol" with tainted argument "s" returns tainted data. +watch.c:113: var_assign: Assigning: "t" = "strtol(s, &endptr, 0)", which taints "t". +watch.c:114: var_assign_var: Assigning: "incoming_rows" = "(int)t". Both are now tainted. +watch.c:115: var_assign_var: Assigning: "height" = "incoming_rows". Both are now tainted. +watch.c:116: vararg_transitive: Call to "snprintf" with tainted argument "height" taints "env_row_buf". +watch.c:117: tainted_string: Passing tainted string "env_row_buf" to a function that cannot accept tainted data. + + + + proc/readproc ---------------------------------------------------------------- +Error: DEADCODE: + the tool does not understand gperf and the pseudo case labels preceded by goto + the following code snippets illustrate the deficiency: + goto *(&&base + entry.offset); + ... + case_Threads: + Threads = strtol(S,&S,10); + continue; + my_category: avoidable_false_positive +proc/readproc.c:387: dead_error_condition: On this path, the condition "Threads" cannot be true. +proc/readproc.c:115: const: After this line, the value of "Threads" is equal to 0. +proc/readproc.c:115: assignment: Assigning: "Threads" = "0L". +proc/readproc.c:388: dead_error_begin: Execution cannot reach this statement "P->nlwp = Threads;". + +Error: STRING_NULL: + read is asked to retrieve -1 bytes than passed capacity: num_read = read(fd, ret, cap - 1); + file2str does indeed null terminate sbuf: ret[num_read] = '\0'; + my_category: avoidable_false_positive +proc/readproc.c:1193: string_null_argument: Function "file2str" does not terminate string "*sbuf". +proc/readproc.c:514: string_null_argument: Function "read" fills array "*ret" with a non-terminated string. +proc/readproc.c:1197: string_null: Passing unterminated string "sbuf" to a function expecting a null-terminated string. +proc/readproc.c:447: string_null_sink_parm_call: Passing parameter "S" to "strchr" which expects a null-terminated string. + + + + ps/output -------------------------------------------------------------------- +Error: MISSING_BREAK: + intentional fall through + my_category: possibly_filter_out_? +ps/output.c:1983: unterminated_default: The default case is not terminated by a 'break' statement. +ps/output.c:1984: fallthrough: The above case falls through to this one. + +Error: UNINIT: + the first member is initialized in the very next statement, sufficient for bsearch callback + key.spec = findme; + my_category: avoidable_false_positive +ps/output.c:1737: var_decl: Declaring variable "key" without initializer. +ps/output.c:1739: uninit_use_in_call: Using uninitialized value "key": field "key".flags is uninitialized when calling "bsearch". + +Error: UNINIT: + the first member is initialized in the very next statement, sufficient for bsearch callback + key.spec = findme; + my_category: avoidable_false_positive +ps/output.c:1745: var_decl: Declaring variable "key" without initializer. +ps/output.c:1747: uninit_use_in_call: Using uninitialized value "key": field "key".head is uninitialized when calling "bsearch". + + + + ps/parser -------------------------------------------------------------------- +Error: RESOURCE_LEAK: + intentional omission + abexit shortly + my_category: avoidable_false_positive +ps/parser.c:1021: alloc_fn: Calling allocation function "malloc". +ps/parser.c:1021: var_assign: Assigning: "pidnode" = storage returned from "malloc(sizeof (selection_node) /*24*/)". +ps/parser.c:1041: leaked_storage: Variable "pidnode" going out of scope leaks the storage it points to. +ps/parser.c:1062: leaked_storage: Variable "pidnode" going out of scope leaks the storage it points to. + +Error: RESOURCE_LEAK: + intentional omission + abexit shortly + my_category: avoidable_false_positive +ps/parser.c:1025: alloc_fn: Calling allocation function "malloc". +ps/parser.c:1025: var_assign: Assigning: "grpnode" = storage returned from "malloc(sizeof (selection_node) /*24*/)". +ps/parser.c:1041: leaked_storage: Variable "grpnode" going out of scope leaks the storage it points to. +ps/parser.c:1062: leaked_storage: Variable "grpnode" going out of scope leaks the storage it points to. + +Error: RESOURCE_LEAK: + intentional omission + abexit shortly + my_category: avoidable_false_positive +ps/parser.c:1029: alloc_fn: Calling allocation function "malloc". +ps/parser.c:1029: var_assign: Assigning: "sidnode" = storage returned from "malloc(sizeof (selection_node) /*24*/)". +ps/parser.c:1041: leaked_storage: Variable "sidnode" going out of scope leaks the storage it points to. +ps/parser.c:1062: leaked_storage: Variable "sidnode" going out of scope leaks the storage it points to. + + + + ps/sortformat ---------------------------------------------------------------- +Error: UNREACHABLE: + the tool does not understand the following 'label' usage (nor do i - perhaps some obscure compiler/platform warning/quirk) + goto unknown; + ... + if(0) unknown: err=errbuf; + my_category: unavoidable_false_positive_? +ps/sortformat.c:312: unreachable: This code cannot be reached: "if (0){ + unknown: + err = ...". From 1055dff047a0b044a75a3e74986e41d5cdef7ddd Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Wed, 19 Oct 2011 19:02:34 -0500 Subject: [PATCH 21/21] top: redesign show_special strs, in line with nls --- top.c | 37 ++++++++-------- top.h | 134 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 87 insertions(+), 84 deletions(-) diff --git a/top.c b/top.c index 9a8c66c9..235f215e 100644 --- a/top.c +++ b/top.c @@ -714,10 +714,13 @@ static inline void show_scroll (void) { * what will fit within the current screen width. * Our special formatting consists of: * "some text <_delimiter_> some more text <_delimiter_>...\n" - * Where <_delimiter_> is a single byte in the range of: - * \01 through \10 (in decimalizee, 1 - 8) - * and is used to select an 'attribute' from a capabilities table - * which is then applied to the *preceding* substring. + * Where <_delimiter_> is a two bye combination consisting of a + * tilde followed by an ascii digit in the the range of 1 - 8. + * examples: ~1, ~5, ~8, etc. + * The tilde is effectively stripped and the next digit + * converted to an index which is then used to select an + * 'attribute' from a capabilities table. That attribute + * is then applied to the *preceding* substring. * Once recognized, the delimiter is replaced with a null character * and viola, we've got a substring ready to output! Strings or * substrings without delimiters will receive the Cap_norm attribute. @@ -732,24 +735,23 @@ static inline void show_scroll (void) { * Tabs must always be avoided or our efforts are wasted and * lines will wrap. To lessen but not eliminate the risk of * terminfo string truncation, such non-display stuff should - * be placed at the beginning of a "short" line. - * (and as for tabs, gimme 1 more color then no worries, mate) */ + * be placed at the beginning of a "short" line. */ static void show_special (int interact, const char *glob) { /* note: the following is for documentation only, the real captab is now found in a group's WIN_t ! +------------------------------------------------------+ | char *captab[] = { : Cap's/Delim's | - | Cap_norm, Cap_norm, = \00, \01, | - | cap_bold, capclr_sum, = \02, \03, | - | capclr_msg, capclr_pmt, = \04, \05, | - | capclr_hdr, = \06, | - | capclr_rowhigh, = \07, | - | capclr_rownorm }; = \10 [octal!] | + | Cap_norm, Cap_norm, = \000, \001, | + | cap_bold, capclr_sum, = \002, \003, | + | capclr_msg, capclr_pmt, = \004, \005, | + | capclr_hdr, = \006, | + | capclr_rowhigh, = \007, | + | capclr_rownorm }; = \010 [octal!] | +------------------------------------------------------+ */ /* ( pssst, after adding the termcap transitions, row may ) ( exceed 300+ bytes, even in an 80x24 terminal window! ) */ char tmp[SMLBUFSIZ], lin[MEDBUFSIZ], row[LRGBUFSIZ]; - char *rp, *cap, *lin_end, *sub_beg, *sub_end; + char *rp, *lin_end, *sub_beg, *sub_end; int room; // handle multiple lines passed in a bunch @@ -763,16 +765,17 @@ static void show_special (int interact, const char *glob) { *(rp = row) = '\0'; while (*sub_beg) { - switch (*sub_end) { + int ch = *sub_end; + if ('~' == ch) ch = *(sub_end + 1) - '0'; + switch (ch) { case 0: // no end delim, captab makes normal *(sub_end + 1) = '\0'; // extend str end, then fall through case 1 ... 8: - cap = Curwin->captab[(int)*sub_end]; *sub_end = '\0'; - snprintf(tmp, sizeof(tmp), "%s%.*s%s", cap, room, sub_beg, Caps_off); + snprintf(tmp, sizeof(tmp), "%s%.*s%s", Curwin->captab[ch], room, sub_beg, Caps_off); rp = scat(rp, tmp); room -= (sub_end - sub_beg); - sub_beg = ++sub_end; + sub_beg = (sub_end += (ch ? 2 : 1)); break; default: // nothin' special, just text ++sub_end; diff --git a/top.h b/top.h index 5dd0733b..e071bba3 100644 --- a/top.h +++ b/top.h @@ -476,63 +476,63 @@ typedef struct WIN_t { /* Summary Lines specially formatted string(s) -- see 'show_special' for syntax details + other cautions. */ #define LOADAV_line "%s -%s\n" -#define LOADAV_line_alt "%s\06 -%s\n" -#define STATES_line1 "%s:\03" \ - " %3u \02total,\03 %3u \02running,\03 %3u \02sleeping,\03 %3u \02stopped,\03 %3u \02zombie\03\n" -#define STATES_line2x4 "%%%s\03" \ - " %#5.1f \02user,\03 %#5.1f \02system,\03 %#5.1f \02nice,\03 %#5.1f \02idle\03\n" +#define LOADAV_line_alt "%s~6 -%s\n" +#define STATES_line1 "%s:~3" \ + " %3u ~2total,~3 %3u ~2running,~3 %3u ~2sleeping,~3 %3u ~2stopped,~3 %3u ~2zombie~3\n" +#define STATES_line2x4 "%%%s~3" \ + " %#5.1f ~2user,~3 %#5.1f ~2system,~3 %#5.1f ~2nice,~3 %#5.1f ~2idle~3\n" /* These are the STATES_line evolutions lnx 2.5.x, procps-3.0.5 : IO-wait = i/o wait time lnx 2.6.x, procps-3.1.12 : IO-wait now wa, hi = hard irq, si = soft irq lnx 2.7.x, procps-3.2.7 : st = steal time */ -#define STATES_line2x5 "%%%s\03" \ - " %#5.1f \02user,\03 %#5.1f \02system,\03 %#5.1f \02nice,\03 %#5.1f \02idle,\03 %#5.1f \02IO-wait\03\n" -#define STATES_line2x6 "%%%s\03" \ - " %#5.1f \02us,\03 %#5.1f \02sy,\03 %#5.1f \02ni,\03 %#5.1f \02id,\03 %#5.1f \02wa,\03 %#5.1f \02hi,\03 %#5.1f \02si\03\n" -#define STATES_line2x7 "%%%s\03" \ - "%#5.1f \02us,\03%#5.1f \02sy,\03%#5.1f \02ni,\03%#5.1f \02id,\03%#5.1f \02wa,\03%#5.1f \02hi,\03%#5.1f \02si,\03%#5.1f \02st\03\n" +#define STATES_line2x5 "%%%s~3" \ + " %#5.1f ~2user,~3 %#5.1f ~2system,~3 %#5.1f ~2nice,~3 %#5.1f ~2idle,~3 %#5.1f ~2IO-wait~3\n" +#define STATES_line2x6 "%%%s~3" \ + " %#5.1f ~2us,~3 %#5.1f ~2sy,~3 %#5.1f ~2ni,~3 %#5.1f ~2id,~3 %#5.1f ~2wa,~3 %#5.1f ~2hi,~3 %#5.1f ~2si~3\n" +#define STATES_line2x7 "%%%s~3" \ + "%#5.1f ~2us,~3%#5.1f ~2sy,~3%#5.1f ~2ni,~3%#5.1f ~2id,~3%#5.1f ~2wa,~3%#5.1f ~2hi,~3%#5.1f ~2si,~3%#5.1f ~2st~3\n" #define MEMORY_twolines \ - "%s Mem: \03 %8lu \02total,\03 %8lu \02used,\03 %8lu \02free,\03 %8lu \02buffers\03\n" \ - "%s Swap:\03 %8lu \02total,\03 %8lu \02used,\03 %8lu \02free,\03 %8lu \02cached\03\n" + "%s Mem: ~3 %8lu ~2total,~3 %8lu ~2used,~3 %8lu ~2free,~3 %8lu ~2buffers~3\n" \ + "%s Swap:~3 %8lu ~2total,~3 %8lu ~2used,~3 %8lu ~2free,~3 %8lu ~2cached~3\n" /* Keyboard Help specially formatted string(s) -- see 'show_special' for syntax details + other cautions. */ #define KEYS_help \ - "Help for Interactive Commands\02 - %s\n" \ - "Window \01%s\06: \01Cumulative mode \03%s\02. \01System\06: \01Delay \03%.1f secs\02; \01Secure mode \03%s\02.\n" \ + "Help for Interactive Commands~2 - %s\n" \ + "Window ~1%s~6: ~1Cumulative mode ~3%s~2. ~1System~6: ~1Delay ~3%.1f secs~2; ~1Secure mode ~3%s~2.\n" \ "\n" \ - " Z\05,\01B\05 Global: '\01Z\02' change color mappings; '\01B\02' disable/enable bold\n" \ - " l,t,m Toggle Summaries: '\01l\02' load avg; '\01t\02' task/cpu stats; '\01m\02' mem info\n" \ - " 1,I Toggle SMP view: '\0011\02' single/separate states; '\01I\02' Irix/Solaris mode\n" \ + " Z~5,~1B~5 Global: '~1Z~2' change color mappings; '~1B~2' disable/enable bold\n" \ + " l,t,m Toggle Summaries: '~1l~2' load avg; '~1t~2' task/cpu stats; '~1m~2' mem info\n" \ + " 1,I Toggle SMP view: '~11~2' single/separate states; '~1I~2' Irix/Solaris mode\n" \ " f,F Manage Fields: add/remove; change order; select sort field\n" \ "\n" \ - " <,> . Move sort field: '\01<\02' next col left; '\01>\02' next col right\n" \ - " R,H,V . Toggle: '\01R\02' norm/rev sort; '\01H\02' show threads; '\01V\02' forest view\n" \ - " c,i,S . Toggle: '\01c\02' cmd name/line; '\01i\02' idle tasks; '\01S\02' cumulative time\n" \ - " x\05,\01y\05 . Toggle highlights: '\01x\02' sort field; '\01y\02' running tasks\n" \ - " z\05,\01b\05 . Toggle: '\01z\02' color/mono; '\01b\02' bold/reverse (only if 'x' or 'y')\n" \ - " u,U . Show: '\01u\02' effective user; '\01U\02' real, saved, file or effective user\n" \ + " <,> . Move sort field: '~1<~2' next col left; '~1>~2' next col right\n" \ + " R,H,V . Toggle: '~1R~2' norm/rev sort; '~1H~2' show threads; '~1V~2' forest view\n" \ + " c,i,S . Toggle: '~1c~2' cmd name/line; '~1i~2' idle tasks; '~1S~2' cumulative time\n" \ + " x~5,~1y~5 . Toggle highlights: '~1x~2' sort field; '~1y~2' running tasks\n" \ + " z~5,~1b~5 . Toggle: '~1z~2' color/mono; '~1b~2' bold/reverse (only if 'x' or 'y')\n" \ + " u,U . Show: '~1u~2' effective user; '~1U~2' real, saved, file or effective user\n" \ " n or # . Set maximum tasks displayed\n" \ - " C,... . Toggle scroll coordinates msg for: \01up\02,\01down\02,\01left\02,right\02,\01home\02,\01end\02\n" \ + " C,... . Toggle scroll coordinates msg for: ~1up~2,~1down~2,~1left~2,right~2,~1home~2,~1end~2\n" \ "\n" \ "%s" \ " W Write configuration file\n" \ " q Quit\n" \ - " ( commands shown with '.' require a \01visible\02 task display \01window\02 ) \n" \ - "Press '\01h\02' or '\01?\02' for help with \01Windows\02,\n" \ + " ( commands shown with '.' require a ~1visible~2 task display ~1window~2 ) \n" \ + "Press '~1h~2' or '~1?~2' for help with ~1Windows~2,\n" \ "any other key to continue " \ "" /* This guy goes into the help text (maybe) */ #define KEYS_help_unsecured \ - " k,r Manipulate tasks: '\01k\02' kill; '\01r\02' renice\n" \ + " k,r Manipulate tasks: '~1k~2' kill; '~1r~2' renice\n" \ " d or s Set update interval\n" \ "" /* Fields Management specially formatted string(s) -- see 'show_special' for syntax details + other cautions */ #define FIELDS_heading \ - "Fields Management\02 for window \01%s\06, whose current sort field is \01%s\02\n" \ + "Fields Management~2 for window ~1%s~6, whose current sort field is ~1%s~2\n" \ " Navigate with Up/Dn, Right selects for move then or Left commits,\n" \ " 'd' or toggles display, 's' sets sort. Use 'q' or to end! " \ "" @@ -540,58 +540,58 @@ typedef struct WIN_t { /* Colors Help specially formatted string(s) -- see 'show_special' for syntax details + other cautions. */ #define COLOR_help \ - "Help for color mapping\02 - %s\n" \ - "current window: \01%s\06\n" \ + "Help for color mapping~2 - %s\n" \ + "current window: ~1%s~6\n" \ "\n" \ " color - 04:25:44 up 8 days, 50 min, 7 users, load average:\n" \ - " Tasks:\03 64 \02total,\03 2 \03running,\03 62 \02sleeping,\03 0 \02stopped,\03\n" \ - " %%Cpu(s):\03 76.5 \02user,\03 11.2 \02system,\03 0.0 \02nice,\03 12.3 \02idle\03\n" \ - " \01 Nasty Message! \04 -or- \01Input Prompt\05\n" \ - " \01 PID TTY PR NI %%CPU TIME+ VIRT SWAP S COMMAND \06\n" \ - " 17284 \10pts/2 \07 8 0 0.0 0:00.75 1380 0 S /bin/bash \10\n" \ - " \01 8601 pts/1 7 -10 0.4 0:00.03 916 0 R color -b -z\07\n" \ - " 11005 \10? \07 9 0 0.0 0:02.50 2852 1008 S amor -sessi\10\n" \ - " available toggles: \01B\02 =disable bold globally (\01%s\02),\n" \ - " \01z\02 =color/mono (\01%s\02), \01b\02 =tasks \"bold\"/reverse (\01%s\02)\n" \ + " Tasks:~3 64 ~2total,~3 2 ~3running,~3 62 ~2sleeping,~3 0 ~2stopped,~3\n" \ + " %%Cpu(s):~3 76.5 ~2user,~3 11.2 ~2system,~3 0.0 ~2nice,~3 12.3 ~2idle~3\n" \ + " ~1 Nasty Message! ~4 -or- ~1Input Prompt~5\n" \ + " ~1 PID TTY PR NI %%CPU TIME+ VIRT SWAP S COMMAND ~6\n" \ + " 17284 ~8pts/2 ~7 8 0 0.0 0:00.75 1380 0 S /bin/bash ~8\n" \ + " ~1 8601 pts/1 7 -10 0.4 0:00.03 916 0 R color -b -z~7\n" \ + " 11005 ~8? ~7 9 0 0.0 0:02.50 2852 1008 S amor -sessi~8\n" \ + " available toggles: ~1B~2 =disable bold globally (~1%s~2),\n" \ + " ~1z~2 =color/mono (~1%s~2), ~1b~2 =tasks \"bold\"/reverse (~1%s~2)\n" \ "\n" \ - "Select \01target\02 as upper case letter:\n" \ - " S\02 = Summary Data,\01 M\02 = Messages/Prompts,\n" \ - " H\02 = Column Heads,\01 T\02 = Task Information\n" \ - "Select \01color\02 as number:\n" \ - " 0\02 = black,\01 1\02 = red, \01 2\02 = green,\01 3\02 = yellow,\n" \ - " 4\02 = blue, \01 5\02 = magenta,\01 6\02 = cyan, \01 7\02 = white\n" \ + "Select ~1target~2 as upper case letter:\n" \ + " S~2 = Summary Data,~1 M~2 = Messages/Prompts,\n" \ + " H~2 = Column Heads,~1 T~2 = Task Information\n" \ + "Select ~1color~2 as number:\n" \ + " 0~2 = black,~1 1~2 = red, ~1 2~2 = green,~1 3~2 = yellow,\n" \ + " 4~2 = blue, ~1 5~2 = magenta,~1 6~2 = cyan, ~1 7~2 = white\n" \ "\n" \ - "Selected: \01target\02 \01 %c \04; \01color\02 \01 %d \04\n" \ - " press 'q' to abort changes to window '\01%s\02'\n" \ + "Selected: ~1target~2 ~1 %c ~4; ~1color~2 ~1 %d ~4\n" \ + " press 'q' to abort changes to window '~1%s~2'\n" \ " press 'a' or 'w' to commit & change another, to commit and end " \ "" /* Windows/Field Group Help specially formatted string(s) -- see 'show_special' for syntax details + other cautions. */ #define WINDOWS_help \ - "Help for Windows / Field Groups\02 - \"Current Window\" = \01 %s \06\n" \ + "Help for Windows / Field Groups~2 - \"Current Window\" = ~1 %s ~6\n" \ "\n" \ - ". Use multiple \01windows\02, each with separate config opts (color,fields,sort,etc)\n" \ - ". The 'current' window controls the \01Summary Area\02 and responds to your \01Commands\02\n" \ - " . that window's \01task display\02 can be turned \01Off\02 & \01On\02, growing/shrinking others\n" \ - " . with \01NO\02 task display, some commands will be \01disabled\02 ('i','R','n','c', etc)\n" \ - " until a \01different window\02 has been activated, making it the 'current' window\n" \ - ". You \01change\02 the 'current' window by: \01 1\02) cycling forward/backward;\01 2\02) choosing\n" \ - " a specific field group; or\01 3\02) exiting the color mapping or fields screens\n" \ - ". Commands \01available anytime -------------\02\n" \ - " A . Alternate display mode toggle, show \01Single\02 / \01Multiple\02 windows\n" \ + ". Use multiple ~1windows~2, each with separate config opts (color,fields,sort,etc)\n" \ + ". The 'current' window controls the ~1Summary Area~2 and responds to your ~1Commands~2\n" \ + " . that window's ~1task display~2 can be turned ~1Off~2 & ~1On~2, growing/shrinking others\n" \ + " . with ~1NO~2 task display, some commands will be ~1disabled~2 ('i','R','n','c', etc)\n" \ + " until a ~1different window~2 has been activated, making it the 'current' window\n" \ + ". You ~1change~2 the 'current' window by: ~1 1~2) cycling forward/backward;~1 2~2) choosing\n" \ + " a specific field group; or~1 3~2) exiting the color mapping or fields screens\n" \ + ". Commands ~1available anytime -------------~2\n" \ + " A . Alternate display mode toggle, show ~1Single~2 / ~1Multiple~2 windows\n" \ " g . Choose another field group and make it 'current', or change now\n" \ - " by selecting a number from: \01 1\02 =%s;\01 2\02 =%s;\01 3\02 =%s; or\01 4\02 =%s\n" \ - ". Commands \01requiring\02 '\01A\02' mode\01 -------------\02\n" \ - " G . Change the \01Name\05 of the 'current' window/field group\n" \ - " \01*\04 a , w . Cycle through all four windows: '\01a\05' Forward; '\01w\05' Backward\n" \ - " \01*\04 - , _ . Show/Hide: '\01-\05' \01Current\02 window; '\01_\05' all \01Visible\02/\01Invisible\02\n" \ + " by selecting a number from: ~1 1~2 =%s;~1 2~2 =%s;~1 3~2 =%s; or~1 4~2 =%s\n" \ + ". Commands ~1requiring~2 '~1A~2' mode~1 -------------~2\n" \ + " G . Change the ~1Name~5 of the 'current' window/field group\n" \ + " ~1*~4 a , w . Cycle through all four windows: '~1a~5' Forward; '~1w~5' Backward\n" \ + " ~1*~4 - , _ . Show/Hide: '~1-~5' ~1Current~2 window; '~1_~5' all ~1Visible~2/~1Invisible~2\n" \ " The screen will be divided evenly between task displays. But you can make\n" \ - " some \01larger\02 or \01smaller\02, using '\01n\02' and '\01i\02' commands. Then later you could:\n" \ - " \01*\04 = , + . Rebalance tasks: '\01=\05' \01Current\02 window; '\01+\05' \01Every\02 window\n" \ - " (this also forces the \01current\02 or \01every\02 window to become visible)\n" \ + " some ~1larger~2 or ~1smaller~2, using '~1n~2' and '~1i~2' commands. Then later you could:\n" \ + " ~1*~4 = , + . Rebalance tasks: '~1=~5' ~1Current~2 window; '~1+~5' ~1Every~2 window\n" \ + " (this also forces the ~1current~2 or ~1every~2 window to become visible)\n" \ "\n" \ - "In '\01A\02' mode, '\01*\04' keys are your \01essential\02 commands. Please try the '\01a\02' and '\01w\02'\n" \ + "In '~1A~2' mode, '~1*~4' keys are your ~1essential~2 commands. Please try the '~1a~2' and '~1w~2'\n" \ "commands plus the 'g' sub-commands NOW. Press to make 'Current' " \ ""