...
 
Commits (8)
procps-ng-NEXT procps-ng-NEXT
---------------- ----------------
* docs: Use correct symbols for -h option in free.1 Debian #898774 * docs: Use correct symbols for -h option in free.1 Debian #898774
* docs: ps.1 now warns about command name length issue #101
* top: can now exploit 256-color terminals issue #96 * top: can now exploit 256-color terminals issue #96
* top: preserves 'other filters' in configuration file issue #99 * top: preserves 'other filters' in configuration file issue #99
* top: can now collapse/expand forest view children issue #99 * top: can now collapse/expand forest view children issue #99
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define PROCPS_NG_NLS_H #define PROCPS_NG_NLS_H
/* programs issuing textdomain() need PACKAGE string */ /* programs issuing textdomain() need PACKAGE string */
#include "../config.h" #include "config.h"
/* programs issuing bindtextdomain() also need LOCALEDIR string */ /* programs issuing bindtextdomain() also need LOCALEDIR string */
#ifndef LOCALEDIR #ifndef LOCALEDIR
......
...@@ -720,7 +720,7 @@ static char** file2strvec(const char* directory, const char* what) { ...@@ -720,7 +720,7 @@ static char** file2strvec(const char* directory, const char* what) {
#undef ARG_LEN #undef ARG_LEN
if (end_of_file && if (end_of_file &&
((n > 0 && buf[n-1] != '\0') || /* last read char not null */ ((n > 0 && buf[n-1] != '\0') || /* last read char not null */
(n <= 0 && rbuf[tot-1] != '\0'))) /* last read char not null */ (n <= 0 && rbuf && rbuf[tot-1] != '\0'))) /* last read char not null */
buf[n++] = '\0'; /* so append null-terminator */ buf[n++] = '\0'; /* so append null-terminator */
if (n <= 0) break; /* unneeded (end_of_file = 1) but avoid realloc */ if (n <= 0) break; /* unneeded (end_of_file = 1) but avoid realloc */
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.\" Quick hack conversion by Albert Cahalan, 1998. .\" Quick hack conversion by Albert Cahalan, 1998.
.\" Licensed under version 2 of the Gnu General Public License. .\" Licensed under version 2 of the Gnu General Public License.
.\" .\"
.TH PS 1 2018-05-31 "procps-ng" "User Commands" .TH PS 1 2018-08-08 "procps-ng" "User Commands"
.\" .\"
.\" To render this page: .\" To render this page:
.\" groff -t -b -man -X -P-resolution -P100 -Tps ps.1 & .\" groff -t -b -man -X -P-resolution -P100 -Tps ps.1 &
...@@ -236,6 +236,10 @@ Identical to ...@@ -236,6 +236,10 @@ Identical to
Select by command name. This selects the processes whose executable name is Select by command name. This selects the processes whose executable name is
given in given in
.IR cmdlist . .IR cmdlist .
NOTE: The command name is not the same as the command line. Previous versions
of procps and the kernel truncated this command name to 15 characters. This
limitation is no longer present in both. If you depended on matching only
15 characters, you may no longer get a match.
.TP .TP
.BI \-G \ grplist .BI \-G \ grplist
Select by real group ID (RGID) or name. This selects the processes whose Select by real group ID (RGID) or name. This selects the processes whose
......
...@@ -414,7 +414,7 @@ static void bye_bye (const char *str) { ...@@ -414,7 +414,7 @@ static void bye_bye (const char *str) {
"\n\t Hertz = %u (%u bytes, %u-bit time)" "\n\t Hertz = %u (%u bytes, %u-bit time)"
"\n\t page_bytes = %d, Cpu_faux_tot = %d, smp_num_cpus = %d" "\n\t page_bytes = %d, Cpu_faux_tot = %d, smp_num_cpus = %d"
"\n\t sizeof(CPU_t) = %u, sizeof(HST_t) = %u (%d HST_t's/Page), HHist_siz = %u" "\n\t sizeof(CPU_t) = %u, sizeof(HST_t) = %u (%d HST_t's/Page), HHist_siz = %u"
"\n\t sizeof(proc_t) = %u, sizeof(proc_t.cmd) = %u, sizeof(proc_t*) = %u" "\n\t sizeof(proc_t) = %u, sizeof(proc_t.cmd) = %u, sizeof(proc_t *) = %u"
"\n\t Frames_libflags = %08lX" "\n\t Frames_libflags = %08lX"
"\n\t SCREENMAX = %u, ROWMINSIZ = %u, ROWMAXSIZ = %u" "\n\t SCREENMAX = %u, ROWMINSIZ = %u, ROWMAXSIZ = %u"
"\n\t PACKAGE = '%s', LOCALEDIR = '%s'" "\n\t PACKAGE = '%s', LOCALEDIR = '%s'"
...@@ -444,7 +444,7 @@ static void bye_bye (const char *str) { ...@@ -444,7 +444,7 @@ static void bye_bye (const char *str) {
, (unsigned)Hertz, (unsigned)sizeof(Hertz), (unsigned)sizeof(Hertz) * 8 , (unsigned)Hertz, (unsigned)sizeof(Hertz), (unsigned)sizeof(Hertz) * 8
, (int)page_bytes, Cpu_faux_tot, (int)smp_num_cpus, (unsigned)sizeof(CPU_t) , (int)page_bytes, Cpu_faux_tot, (int)smp_num_cpus, (unsigned)sizeof(CPU_t)
, (unsigned)sizeof(HST_t), ((int)page_bytes / (int)sizeof(HST_t)), HHist_siz , (unsigned)sizeof(HST_t), ((int)page_bytes / (int)sizeof(HST_t)), HHist_siz
, (unsigned)sizeof(proc_t), (unsigned)sizeof(p->cmd), (unsigned)sizeof(proc_t*) , (unsigned)sizeof(proc_t), (unsigned)sizeof(p->cmd), (unsigned)sizeof(proc_t *)
, (long)Frames_libflags , (long)Frames_libflags
, (unsigned)SCREENMAX, (unsigned)ROWMINSIZ, (unsigned)ROWMAXSIZ , (unsigned)SCREENMAX, (unsigned)ROWMINSIZ, (unsigned)ROWMAXSIZ
, PACKAGE, LOCALEDIR , PACKAGE, LOCALEDIR
...@@ -1069,10 +1069,10 @@ static char *alloc_s (const char *str) { ...@@ -1069,10 +1069,10 @@ static char *alloc_s (const char *str) {
/* /*
* This function is used in connection with raw single byte * An 'I/O available' routine which will detect raw single byte |
* unsolicited keyboard input that's susceptible to SIGWINCH * unsolicited keyboard input which was susceptible to SIGWINCH |
* interrupts (or any other signal). He also supports timout * interrupts (or any other signal). He'll also support timout |
* in the absence of user keystrokes or some signal interrupt. */ * in the absence of any user keystrokes or a signal interrupt. | */
static inline int ioa (struct timespec *ts) { static inline int ioa (struct timespec *ts) {
fd_set fs; fd_set fs;
int rc; int rc;
...@@ -2758,7 +2758,7 @@ static void procs_refresh (void) { ...@@ -2758,7 +2758,7 @@ static void procs_refresh (void) {
proc_t *ptask; proc_t *ptask;
PROCTAB* PT; PROCTAB* PT;
int i; int i;
proc_t*(*read_something)(PROCTAB*, proc_t*); proc_t *(*read_something)(PROCTAB*, proc_t *);
procs_hlp(NULL); // prep for a new frame procs_hlp(NULL); // prep for a new frame
if (NULL == (PT = openproc(Frames_libflags, Monpids))) if (NULL == (PT = openproc(Frames_libflags, Monpids)))
...@@ -2770,9 +2770,9 @@ static void procs_refresh (void) { ...@@ -2770,9 +2770,9 @@ static void procs_refresh (void) {
/* we're subject to integer overflow if total linux tasks ever approach | /* we're subject to integer overflow if total linux tasks ever approach |
400+ million (but, do you think memory might be the bigger problem?) | */ 400+ million (but, do you think memory might be the bigger problem?) | */
n_alloc = 10 + ((n_alloc * 5) / 4); // grow by over 25% n_alloc = 10 + ((n_alloc * 5) / 4); // grow by over 25%
private_ppt = alloc_r(private_ppt, sizeof(proc_t*) * n_alloc); private_ppt = alloc_r(private_ppt, sizeof(proc_t *) * n_alloc);
// ensure NULL pointers for the additional memory just acquired // ensure NULL pointers for the additional memory just acquired
memset(private_ppt + n_used, 0, sizeof(proc_t*) * (n_alloc - n_used)); memset(private_ppt + n_used, 0, sizeof(proc_t *) * (n_alloc - n_used));
} }
// on the way to n_alloc, the library will allocate the underlying // on the way to n_alloc, the library will allocate the underlying
// proc_t storage whenever our private_ppt[] pointer is NULL... // proc_t storage whenever our private_ppt[] pointer is NULL...
...@@ -2785,12 +2785,12 @@ static void procs_refresh (void) { ...@@ -2785,12 +2785,12 @@ static void procs_refresh (void) {
// lastly, refresh each window's proc pointers table... // lastly, refresh each window's proc pointers table...
if (n_saved == n_alloc) if (n_saved == n_alloc)
for (i = 0; i < GROUPSMAX; i++) for (i = 0; i < GROUPSMAX; i++)
memcpy(Winstk[i].ppt, private_ppt, sizeof(proc_t*) * n_used); memcpy(Winstk[i].ppt, private_ppt, sizeof(proc_t *) * n_used);
else { else {
n_saved = n_alloc; n_saved = n_alloc;
for (i = 0; i < GROUPSMAX; i++) { for (i = 0; i < GROUPSMAX; i++) {
Winstk[i].ppt = alloc_r(Winstk[i].ppt, sizeof(proc_t*) * n_alloc); Winstk[i].ppt = alloc_r(Winstk[i].ppt, sizeof(proc_t *) * n_alloc);
memcpy(Winstk[i].ppt, private_ppt, sizeof(proc_t*) * n_used); memcpy(Winstk[i].ppt, private_ppt, sizeof(proc_t *) * n_used);
} }
} }
#undef n_used #undef n_used
...@@ -2943,13 +2943,13 @@ static void insp_cnt_nl (void) { ...@@ -2943,13 +2943,13 @@ static void insp_cnt_nl (void) {
} }
} }
#endif #endif
Insp_p = alloc_c(sizeof(char*) * 2); Insp_p = alloc_c(sizeof(char *) * 2);
for (Insp_nl = 0; beg < end; beg++) { for (Insp_nl = 0; beg < end; beg++) {
if (*beg == '\n') { if (*beg == '\n') {
Insp_p[Insp_nl++] = cur; Insp_p[Insp_nl++] = cur;
// keep our array ahead of next potential need (plus the 2 above) // keep our array ahead of next potential need (plus the 2 above)
Insp_p = alloc_r(Insp_p, (sizeof(char*) * (Insp_nl +3))); Insp_p = alloc_r(Insp_p, (sizeof(char *) * (Insp_nl +3)));
cur = beg +1; cur = beg +1;
} }
} }
...@@ -4762,7 +4762,7 @@ static void forest_create (WIN_t *q) { ...@@ -4762,7 +4762,7 @@ static void forest_create (WIN_t *q) {
if (!Tree_idx) { // do just once per frame if (!Tree_idx) { // do just once per frame
if (hwmsav < Frame_maxtask) { // grow, but never shrink if (hwmsav < Frame_maxtask) { // grow, but never shrink
hwmsav = Frame_maxtask; hwmsav = Frame_maxtask;
Tree_ppt = alloc_r(Tree_ppt, sizeof(proc_t*) * hwmsav); Tree_ppt = alloc_r(Tree_ppt, sizeof(proc_t *) * hwmsav);
Hide_pid = alloc_r(Hide_pid, sizeof(int) * hwmsav); Hide_pid = alloc_r(Hide_pid, sizeof(int) * hwmsav);
#ifndef TREE_VCPUOFF #ifndef TREE_VCPUOFF
Hide_cpu = alloc_r(Hide_cpu, sizeof(unsigned) * hwmsav); Hide_cpu = alloc_r(Hide_cpu, sizeof(unsigned) * hwmsav);
...@@ -4770,7 +4770,7 @@ static void forest_create (WIN_t *q) { ...@@ -4770,7 +4770,7 @@ static void forest_create (WIN_t *q) {
} }
#ifndef TREE_SCANALL #ifndef TREE_SCANALL
qsort(Seed_ppt, Frame_maxtask, sizeof(proc_t*), (QFP_t)forest_based); qsort(Seed_ppt, Frame_maxtask, sizeof(proc_t *), (QFP_t)forest_based);
#endif #endif
for (i = 0; i < Frame_maxtask; i++) { // avoid any hidepid distortions for (i = 0; i < Frame_maxtask; i++) { // avoid any hidepid distortions
if (!Seed_ppt[i]->pad_3) // real & pseudo parents == zero if (!Seed_ppt[i]->pad_3) // real & pseudo parents == zero
...@@ -4800,12 +4800,14 @@ static void forest_create (WIN_t *q) { ...@@ -4800,12 +4800,14 @@ static void forest_create (WIN_t *q) {
} }
// children found (and collapsed), so mark that puppy // children found (and collapsed), so mark that puppy
if (children) Tree_ppt[parent]->pad_2 = 'x'; if (children) Tree_ppt[parent]->pad_2 = 'x';
// this will force a check of the next Hide_pid, if any
j = Frame_maxtask;
} }
} }
} }
} }
} }
memcpy(Seed_ppt, Tree_ppt, sizeof(proc_t*) * Frame_maxtask); memcpy(Seed_ppt, Tree_ppt, sizeof(proc_t *) * Frame_maxtask);
} // end: forest_create } // end: forest_create
...@@ -4974,7 +4976,7 @@ static void other_filters (int ch) { ...@@ -4974,7 +4976,7 @@ static void other_filters (int ch) {
i = 0; i = 0;
osel = w->osel_1st; osel = w->osel_1st;
pp = alloc_c((w->osel_tot + 1) * sizeof(char**)); pp = alloc_c((w->osel_tot + 1) * sizeof(char **));
while (osel && i < w->osel_tot) { while (osel && i < w->osel_tot) {
pp[i++] = osel->raw; pp[i++] = osel->raw;
osel = osel->nxt; osel = osel->nxt;
...@@ -6311,7 +6313,7 @@ static int window_show (WIN_t *q, int wmax) { ...@@ -6311,7 +6313,7 @@ static int window_show (WIN_t *q, int wmax) {
else Frame_srtflg = -1; else Frame_srtflg = -1;
Frame_ctimes = CHKw(q, Show_CTIMES); // this & next, only maybe Frame_ctimes = CHKw(q, Show_CTIMES); // this & next, only maybe
Frame_cmdlin = CHKw(q, Show_CMDLIN); Frame_cmdlin = CHKw(q, Show_CMDLIN);
qsort(q->ppt, Frame_maxtask, sizeof(proc_t*), Fieldstab[q->rc.sortindx].sort); qsort(q->ppt, Frame_maxtask, sizeof(proc_t *), Fieldstab[q->rc.sortindx].sort);
} }
if (q->begnext) window_hlp(); if (q->begnext) window_hlp();
......
...@@ -87,6 +87,9 @@ Display version information and exit. ...@@ -87,6 +87,9 @@ Display version information and exit.
.TP .TP
\fB\-h\fR, \fB\-\-help\fR \fB\-h\fR, \fB\-\-help\fR
Display help and exit. Display help and exit.
.TP
\fB\-y\fR, \fB\-\-no-first\fR
Omits first report with statistics since system boot.
.PD .PD
.SH "FIELD DESCRIPTION FOR VM MODE" .SH "FIELD DESCRIPTION FOR VM MODE"
.SS .SS
......
...@@ -75,6 +75,9 @@ static int a_option; ...@@ -75,6 +75,9 @@ static int a_option;
/* "-w" means "wide output" */ /* "-w" means "wide output" */
static int w_option; static int w_option;
/* "-y" means "skip first output" */
static int y_option;
/* "-t" means "show timestamp" */ /* "-t" means "show timestamp" */
static int t_option; static int t_option;
...@@ -104,6 +107,7 @@ static void __attribute__ ((__noreturn__)) ...@@ -104,6 +107,7 @@ static void __attribute__ ((__noreturn__))
fputs(_(" -S, --unit <char> define display unit\n"), out); fputs(_(" -S, --unit <char> define display unit\n"), out);
fputs(_(" -w, --wide wide output\n"), out); fputs(_(" -w, --wide wide output\n"), out);
fputs(_(" -t, --timestamp show timestamp\n"), out); fputs(_(" -t, --timestamp show timestamp\n"), out);
fputs(_(" -y, --no-first skips first line of output\n"), out);
fputs(USAGE_SEPARATOR, out); fputs(USAGE_SEPARATOR, out);
fputs(USAGE_HELP, out); fputs(USAGE_HELP, out);
fputs(USAGE_VERSION, out); fputs(USAGE_VERSION, out);
...@@ -307,47 +311,52 @@ static void new_format(void) ...@@ -307,47 +311,52 @@ static void new_format(void)
cpu_zzz, pgpgin, pgpgout, pswpin, pswpout, intr, ctxt, &running, cpu_zzz, pgpgin, pgpgout, pswpin, pswpout, intr, ctxt, &running,
&blocked, &dummy_1, &dummy_2); &blocked, &dummy_1, &dummy_2);
if (t_option) { if (y_option == 0) {
(void) time( &the_time ); if (t_option) {
tm_ptr = localtime( &the_time ); (void) time( &the_time );
if (tm_ptr && strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm_ptr)) { tm_ptr = localtime( &the_time );
; if (tm_ptr && strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm_ptr)) {
} else { ;
timebuf[0] = '\0'; }
else {
timebuf[0] = '\0';
}
} }
}
duse = *cpu_use + *cpu_nic; duse = *cpu_use + *cpu_nic;
dsys = *cpu_sys + *cpu_xxx + *cpu_yyy; dsys = *cpu_sys + *cpu_xxx + *cpu_yyy;
didl = *cpu_idl; didl = *cpu_idl;
diow = *cpu_iow; diow = *cpu_iow;
dstl = *cpu_zzz; dstl = *cpu_zzz;
Div = duse + dsys + didl + diow + dstl; Div = duse + dsys + didl + diow + dstl;
if (!Div) Div = 1, didl = 1; if (!Div) Div = 1, didl = 1;
divo2 = Div / 2UL; divo2 = Div / 2UL;
printf(w_option ? wide_format : format, printf(w_option ? wide_format : format,
running, blocked, running, blocked,
unitConvert(kb_swap_used), unitConvert(kb_main_free), unitConvert(kb_swap_used), unitConvert(kb_main_free),
unitConvert(a_option?kb_inactive:kb_main_buffers), unitConvert(a_option?kb_inactive:kb_main_buffers),
unitConvert(a_option?kb_active:kb_main_cached), unitConvert(a_option?kb_active:kb_main_cached),
(unsigned)( (unitConvert(*pswpin * kb_per_page) * hz + divo2) / Div ), (unsigned)( (unitConvert(*pswpin * kb_per_page) * hz + divo2) / Div ),
(unsigned)( (unitConvert(*pswpout * kb_per_page) * hz + divo2) / Div ), (unsigned)( (unitConvert(*pswpout * kb_per_page) * hz + divo2) / Div ),
(unsigned)( (*pgpgin * hz + divo2) / Div ), (unsigned)( (*pgpgin * hz + divo2) / Div ),
(unsigned)( (*pgpgout * hz + divo2) / Div ), (unsigned)( (*pgpgout * hz + divo2) / Div ),
(unsigned)( (*intr * hz + divo2) / Div ), (unsigned)( (*intr * hz + divo2) / Div ),
(unsigned)( (*ctxt * hz + divo2) / Div ), (unsigned)( (*ctxt * hz + divo2) / Div ),
(unsigned)( (100*duse + divo2) / Div ), (unsigned)( (100*duse + divo2) / Div ),
(unsigned)( (100*dsys + divo2) / Div ), (unsigned)( (100*dsys + divo2) / Div ),
(unsigned)( (100*didl + divo2) / Div ), (unsigned)( (100*didl + divo2) / Div ),
(unsigned)( (100*diow + divo2) / Div ), (unsigned)( (100*diow + divo2) / Div ),
(unsigned)( (100*dstl + divo2) / Div ) (unsigned)( (100*dstl + divo2) / Div )
); );
if (t_option) { if (t_option) {
printf(" %s", timebuf); printf(" %s", timebuf);
} }
printf("\n"); printf("\n");
}
else
num_updates++;
/* main loop */ /* main loop */
for (i = 1; infinite_updates || i < num_updates; i++) { for (i = 1; infinite_updates || i < num_updates; i++) {
...@@ -887,6 +896,7 @@ int main(int argc, char *argv[]) ...@@ -887,6 +896,7 @@ int main(int argc, char *argv[])
{"timestamp", no_argument, NULL, 't'}, {"timestamp", no_argument, NULL, 't'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'V'},
{"no-first", no_argument, NULL, 'y'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
...@@ -899,7 +909,7 @@ int main(int argc, char *argv[]) ...@@ -899,7 +909,7 @@ int main(int argc, char *argv[])
atexit(close_stdout); atexit(close_stdout);
while ((c = while ((c =
getopt_long(argc, argv, "afmnsdDp:S:wthV", longopts, getopt_long(argc, argv, "afmnsdDp:S:wthVy", longopts,
NULL)) != -1) NULL)) != -1)
switch (c) { switch (c) {
case 'V': case 'V':
...@@ -968,6 +978,11 @@ int main(int argc, char *argv[]) ...@@ -968,6 +978,11 @@ int main(int argc, char *argv[])
case 't': case 't':
t_option = 1; t_option = 1;
break; break;
case 'y':
/* Don't display stats since system restart */
y_option = 1;
break;
default: default:
/* no other aguments defined yet. */ /* no other aguments defined yet. */
usage(stderr); usage(stderr);
......