From 6744d6ac74992bb5ab78528d693a5f8dd7e5013f Mon Sep 17 00:00:00 2001 From: csmall <> Date: Fri, 13 Sep 2002 11:42:44 +0000 Subject: [PATCH] sync to Jim version Wi --- top.1 | 492 ++++++++++++++++++++----------------- top.c | 761 ++++++++++++++++++++++++++++------------------------------ top.h | 289 ++++++++++++---------- 3 files changed, 812 insertions(+), 730 deletions(-) diff --git a/top.1 b/top.1 index 7c3bf8c9..34c0865b 100644 --- a/top.1 +++ b/top.1 @@ -79,7 +79,7 @@ \# - hey, these two ain't too shabby, either . ds Us this\ \*(Me . ds US \fBthis\fR\ \*(Me -\# - other misc strings +\# - other misc strings for consistent usage . ds F \fIOff\fR . ds O \fIOn\fR . @@ -97,8 +97,14 @@ . ds PU CPU . ds Pu cpu . ds SA summary area -. ds TD task display . ds TA task area +. ds TD task display +. ds TW task window +\# - xref's that depend on commands or topic names +. ds XC See the +. ds Xc see the +. ds XT See topic +. ds Xt see topic . .\" ////////////////////////////////////////////////////////////////////// .\" ---------------------------------------------------------------------- @@ -109,7 +115,7 @@ .\" ---------------------------------------------------------------------- .SH NAME .\" ---------------------------------------------------------------------- -top \- display Linux processes +top \- display Linux tasks .\" ---------------------------------------------------------------------- @@ -136,8 +142,8 @@ manipulation\fR as well as a much more extensive interface for personal\fB configuration\fR \*(EM encompassing every aspect of its operation. And while \*(ME is referred to throughout this document, you are free to name the program anything you wish. -That new name, possibly an alias, will then be reflected on several -interactive screens and used when reading and writing \*(CFs. +That new name, possibly an alias, will then be reflected on \*(Me's display +and used when reading and writing a \*(CF. .\" ---------------------------------------------------------------------- @@ -153,19 +159,21 @@ Details regarding their exploitation will be covered in later sections. .SS Expanded Configurable Display Support .New In an SMP environment, you can choose between a\fB summary\fR display or -you may display\fB each \*(Pu\fR separately. +you may show\fB each \*(Pu\fR separately. This could be an important provision for a massively-parallel machine, where screen height is insufficient to simultaneously accommodate all \*(Pu -states\fI plus\fR a \*(TD. +states plus a meaningful \*(TD. .New -There are new fields and new sort options. -And with \*(Us, any sort column can be\fB instantly reversed\fR. +There are new fields. +With \*(Us,\fB any\fR field is selectable for sorting and your sorted +column can be\fB instantly reversed\fR. .New You may optionally apply 2 distinct types of\fB highlighting\fR to running\fB tasks\fR and/or\fB sorted columns\fR. -With \*(Us, you'll be able to spot running tasks instantly. +With \*(Us, you'll be able to instantly spot running tasks and always +know the current sort field. .New While you could continue to use the more familiar (and boring)\fB @@ -207,9 +215,11 @@ then \*O again later!! .New Many Field/Column names have been changed to make them more intuitive, more self-descriptive. +And with \*(Us you won't be fooled with field choices that are "not yet +implemented". .New -Task memory stats are more meaningful\fI and\fR more accurate\fR. +Task memory statistics are more meaningful\fI and\fR more accurate\fR. .New You'll finally have complete\fB display integrity\fR regardless of field @@ -347,8 +357,7 @@ command line\fR \*(EM a subject soon to be dealt with. 'b' - Bold hilite On\ \ (not 'reverse') * 'c' - Command line \fBOff\fR (name, not cmdline) * 'i' - Idle tasks On\ \ (show all tasks) - 'P' - Sort on PIDs - 'R' - Reverse sort On\ \ (high-to-low) + 'R' - Reverse sort On\ \ (sort pids high-to-low) * 'S' - Cumulative time \fBOff\fR (exclude dead child) 'x' - Column hilite \fBOff\fR\ (no, sort field) 'y' - Row hilite On\ \ (yes, running tasks) @@ -434,32 +443,32 @@ Output is plain text suitable for any dumb terminal. Starts \*(Me with the last remembered '\fBc\fR' state reversed. Thus, if \*(Me was displaying command lines, now that field will show program names, and visa versa. -See also the 'c' \*(CI. +\*(XC 'c' \*(CI for additional information. .TP 5 \-\fBd\fR :\fB Delay time\fR interval as:\ \ \fB-d ss.tt\fR (\fIseconds\fR.\fItenths\fR) Specifies the delay between screen updates, and overrides the corresponding value in one's personal \*(CF or the startup default. -Later this can be changed with the 's' or 'd' \*(CIs. +Later this can be changed with the 'd' or 's' \*(CIs. In all cases, however, such changes are\fI prohibited\fR if \*(Me is running -in 'Secure mode',\fI except for root\fR and\fI excluding\fR the 's' -\*(CO, documented later in this section. -See also 'Secure mode' in section 5. FILES. +in 'Secure mode', except for root and excluding\fR the 's' \*(CO, documented +later in this section. +For additional information on 'Secure mode' +\*(Xt 5a. SYSTEM Configuration File. -Fractional seconds will be honored. -But if you start \*(Me with a delay of anything less than 1 second, and you -expect him to do a proper job of it, then you really owe him a\fB scheduling -boost\fR. +Fractional seconds are honored, but a negative number is not allowed. +If you set the delay to anything less than 1 second, and you expect \*(Me +to do a proper job of it, then you really owe him a\fB scheduling boost\fR. So please renice him using \*(Me's own 'r' \*(CI or more directly with something like the following: nice -n-10 top -d.1 With the ability to highlight\fB running\fR tasks, \*(Us will then produce an amazing display. -One representing the results of the kernel's \fB previously unseen\fR +One representing the results of the kernel's\fB previously unseen\fR scheduling efforts. -You will be surprised, guaranteed. +You may be surprised. .Rjb 2 ( but try not to waste too many \*(Pu cycles ) ( with such sub-second delays & refreshes! ) @@ -474,7 +483,6 @@ Show library version and the usage prompt, then quit. Starts \*(Me with the last remembered '\fBi\fR' state reversed. When this toggle is \*F, tasks that \fBare\fR idled or zombied will\fB not\fR be displayed. -See also the 'i' \*(CI. .TP 5 \-\fBn\fR :\fB Number of iterations\fR limit as:\ \ \fB -n number\fR @@ -500,13 +508,6 @@ This is a \*(CO \fBonly\fR. And should you wish to return to normal operation, it is not necessary to quit and and restart \*(Us \*(EM just issue the '=' \*(CI. -.TP 5 -\-\fBS\fR :\fB Cumulative time mode\fR toggle -Starts \*(Me with the last remembered '\fBS\fR' state reversed. -When 'Cumulative mode' is \*O, each process is listed with the \*(Pu -time that\fB it\fR and its\fB dead children\fR has used. -See also the 'S' \*(CI. - .TP 5 \-\fBs\fR :\fB Secure mode\fR operation Starts \*(Me with \fBsecure mode forced\fR, even for root. @@ -526,6 +527,13 @@ Don't bother trying that precise command line with your old top \*(EM he'll completely overlook that 's' option because he-sees-poorly-but-won't-wear-glasses. +.TP 5 +\-\fBS\fR :\fB Cumulative time mode\fR toggle +Starts \*(Me with the last remembered '\fBS\fR' state reversed. +When 'Cumulative mode' is \*O, each process is listed with the \*(Pu +time that it\fB and\fR its dead children has used. +\*(XC 'S' \*(CI for additional information regarding this mode. + .TP 5 \-\fBv\fR :\fB Version\fR Show library version and the usage prompt, then quit. @@ -541,53 +549,58 @@ Listed below are \*(Us's\fB available\fR fields. They are always associated with the letter shown, regardless of the position you may have established for them with the 'o' (Order fields) \*(CI. -Those fields shown with an \*(AS are selectable as\fB sort fields\fR, -and you control whether they are sorted high-to-low or low-to-high -(see the 'R' \*(CI). +Any field is selectable as the\fB sort field\fR, and you control whether they +are sorted high-to-low or low-to-high. +For additional information on sort provisions \*(Xt 3c. TASK Display Commands. -.TP 5 -*\ a:\fB PID\fR \*(EM Process Id\fR +.TP 3 +a:\fB PID\fR \*(EM Process Id\fR The task's unique process ID, which periodically wraps at 32767, though never restarting at zero. -.TP 5 -\ \ b:\fB PPID\fR \*(EM Parent Process Pid\fR +.TP 3 +b:\fB PPID\fR \*(EM Parent Process Pid\fR The process ID of a task's parent. -.TP 5 -\ \ c:\fB UID\fR \*(EM User Id\fR +.TP 3 +c:\fB PGID\fR \*(EM Process Group Id\fR +The group to which a task belongs which in turn is part of job control. +There is one process group per pipeline. + +.TP 3 +d:\fB UID\fR \*(EM User Id\fR The user ID of the task's owner. -.TP 5 -*\ d:\fB USER\fR \*(EM User Name +.TP 3 +e:\fB USER\fR \*(EM User Name The user name of the task's owner. -.TP 5 -\ \ e:\fB GROUP\fR \*(EM Group Name +.TP 3 +f:\fB GROUP\fR \*(EM Group Name The group name of the task's owner. -.TP 5 -*\ f:\fB TTY\fR \*(EM Controlling Tty +.TP 3 +g:\fB TTY\fR \*(EM Controlling Tty The name of the controlling terminal. This is usually the\fB device\fR (serial port, pty, etc.) from which the process was started, and which it uses for input or output. However, a task need\fI not\fR be associated with a terminal, in which case you'll see '\fB?\fR' displayed. -.TP 5 -\ \ g:\fB PR\fR \*(EM Priority +.TP 3 +h:\fB PR\fR \*(EM Priority The priority of the task. -.TP 5 -\ \ h:\fB NI\fR \*(EM Nice value +.TP 3 +i:\fB NI\fR \*(EM Nice value The nice value of the task. A\fI negative\fR nice value means\fB higher priority\fR, whereas a\fI positive\fR nice value means\fB lower priority\fR. Zero in this field simply means priority will not be adjusted in determining a task's dispatchability. -.TP 5 -\ \ i:\fB #C\fR \*(EM Last used \*(PU (SMP) +.TP 3 +j:\fB #C\fR \*(EM Last used \*(PU (SMP) A number representing the last used processor. In a true SMP environment this will likely change frequently since the kernel intentionally uses weak affinity. @@ -595,8 +608,8 @@ Also, the very act of running \*(Me may break this weak affinity and cause more processes to change \*(PUs more often (because of the extra demand for \*(Pu time). -.TP 5 -*\ j:\fB %CPU\fR \*(EM \*(PU usage +.TP 3 +k:\fB %CPU\fR \*(EM \*(PU usage The task's share of the elapsed \*(PU time since the last screen update, expressed as a percentage of total \*(PU time. In a true SMP environment, if 'Irix mode' is \*F, \*(Me will operate in @@ -604,81 +617,88 @@ In a true SMP environment, if 'Irix mode' is \*F, \*(Me will operate in number of \*(PUs. You toggle 'Irix/Solaris' modes with the 'I' \*(CI. -.TP 5 -*\ k:\fB TIME\fR \*(EM \*(PU Time +.TP 3 +l:\fB TIME\fR \*(EM \*(PU Time Total \*(PU time the task has used since it started. When 'Cumulative mode' is \*O, each process is listed with the \*(Pu time that\fB it\fR and its\fB dead children\fR has used. You toggle 'Cumulative mode' with 'S', which is a \*(CO and an \*(CI. -.TP 5 -*\ l:\fB TIME+\fR \*(EM \*(PU Time, hundredths +.TP 3 +m:\fB TIME+\fR \*(EM \*(PU Time, hundredths The same as 'TIME', but reflecting more granularity through hundredths of a second. -.TP 5 -*\ m:\fB %MEM\fR \*(EM Memory usage (RES) +.TP 3 +n:\fB %MEM\fR \*(EM Memory usage (RES) A task's currently used share of available \*(MP. -.TP 5 -\ \ n:\fB VIRT\fR \*(EM Virtual Image (kb) +.TP 3 +o:\fB VIRT\fR \*(EM Virtual Image (kb) The total amount of \*(MV used by the task. It includes all code, data and shared libraries plus pages that have been swapped out. VIRT = SWAP + RES. -.TP 5 -\ \ o:\fB SWAP\fR \*(EM Swapped size (kb) +.TP 3 +p:\fB SWAP\fR \*(EM Swapped size (kb) The swapped out portion of a task's total \*(MV image. -.TP 5 -*\ p:\fB RES\fR \*(EM Resident size (kb) +.TP 3 +q:\fB RES\fR \*(EM Resident size (kb) The non-swapped \*(MP a task has used. RES = CODE + DATA. -.TP 5 -\ \ q:\fB CODE\fR \*(EM Code size (kb) +.TP 3 +r:\fB CODE\fR \*(EM Code size (kb) The amount of \*(MP devoted to executable code, also known as the 'text resident set' size or TRS. -.TP 5 -\ \ r:\fB DATA\fR \*(EM Data+Stack size (kb) +.TP 3 +s:\fB DATA\fR \*(EM Data+Stack size (kb) The amount of \*(MP devoted to other than executable code, also known as the 'data resident set' size or DRS. -.TP 5 -\ \ s:\fB SHR\fR \*(EM Shared Mem size (kb) +.TP 3 +t:\fB SHR\fR \*(EM Shared Mem size (kb) The amount of \*(MS used by a task. It simply reflects memory that could be potentially shared with other processes. It is not an assurance that such memory is actually being shared. -.TP 5 -\ \ t:\fB nFLT\fR \*(EM Page Fault count +.TP 3 +u:\fB nFLT\fR \*(EM Page Fault count The number of\fB major\fR page faults that have occurred for a task. A page fault occurs when a process attempts to read from or write to a virtual page that is not currently present in its address space. A\fB major\fR page fault is when\fI disk access\fR is involved in making that page available. -.TP 5 -\ \ u:\fB nDRT\fR \*(EM Dirty Pages count +.TP 3 +v:\fB nDRT\fR \*(EM Dirty Pages count The number of pages that have been\fB modified\fR since they were last written to disk. Dirty pages must be written to disk before the corresponding physical memory location can be used for some other virtual page. -.TP 5 -\ \ v:\fB S\fR \*(EM Process Status +.TP 3 +w:\fB S\fR \*(EM Process Status The status of the task which can be one of: - '\fBD\fR' = uninterruptible sleep '\fBR\fR' = running - '\fBS\fR' = sleeping '\fBT\fR' = stopped or traced - '\fBZ\fR' = zombies + '\fBD\fR' = uninterruptible sleep + '\fBR\fR' = running + '\fBS\fR' = sleeping + '\fBT\fR' = traced or stopped + '\fBZ\fR' = zombies -.TP 5 -*\ w:\fB Command\fR \*(EM Command\fB line\fR or Program\fB name\fR +Tasks shown as running should be more properly thought of as 'ready to run' +\*(EM their task_struct is simply represented on Linux's run-queue. +Even without a true SMP machine you may see numerous tasks in this state, +depending on \*(Me's delay interval and nice value. + +.TP 3 +x:\fB Command\fR \*(EM Command\fB line\fR or Program\fB name\fR Display the command line used to start a task or the name of the associated program. You toggle between command\fI line\fR and\fI name\fR with 'c', which is both @@ -701,8 +721,8 @@ When displayed, this column will be allocated \fBall remaining screen width\fR to provide for the potential growth of program names into command lines! .in -.TP 5 -\ \ x:\fB WCHAN\fR \*(EM Sleeping in Function +.TP 3 +y:\fB WCHAN\fR \*(EM Sleeping in Function Depending on the availability of\fI /boot/System.map\fR (the kernel link map) or\fI /boot/psdatabase\fR, this field will show the \fB name\fR or the\fB address\fR of the kernel function in which the task is @@ -716,8 +736,8 @@ over 700Kb. Your only means of reducing that overhead will be to stop and restart \*(Me. .in -.TP 5 -\ \ y:\fB Flags\fR \*(EM Task Flags +.TP 3 +z:\fB Flags\fR \*(EM Task Flags This column represents the task's current scheduling flags which \*(Us expresses in hexadecimal notation, but with zeros suppressed. These flags are officially documented in . @@ -735,7 +755,7 @@ Here is a sample\fB fields string\fR from one of \*(Us's four windows/field groups and an explanation of the conventions used: .Jbu Sample fields string: - \fIAMNOPQRSTUWbcdefiklxyVGHJ\fR + \fIANOPQRSTUVXbcdefgjlmyzWHIK\fR .Jbu The order of displayed fields corresponds to the order of the letters in that string. @@ -744,11 +764,11 @@ If the letter is\fI upper case\fR the corresponding field itself will then be\fB shown\fR as part of the \*(TD (screen width permitting). This will also be indicated by a leading \*(AS, as in this excerpt: \fR... - \fR* J: %CPU = CPU usage - \fR k: TIME = CPU Time - \fR l: TIME+ = CPU Time, hundredths - \fR* M: %MEM = Memory usage (RES) - \fR* N: VIRT = Virtual Image (kb) + \fB* K: %CPU = CPU usage + \fR l: TIME = CPU Time + \fR m: TIME+ = CPU Time, hundredths + \fB* N: %MEM = Memory usage (RES) + \fB* O: VIRT = Virtual Image (kb) \fR... .TP @@ -771,28 +791,37 @@ Some commands appear more than once \*(EM their meaning or scope may vary depending on the context in which they are issued. 3a.\fI GLOBAL_Commands\fR - ?, ^L, , =, A, d, F, h, O, I, k, Q, r, s, W, Z + , ?, =, A, d, G, h, I, k, Q, r, s, W, Z 3b.\fI SUMMARY_Area_Commands\fR l, m, t, 1 3c.\fI TASK_Area_Commands\fR Appearance: b, x, y, z - Content: c, f, S, u - Size: i, n - Sort Order: C, E, M, P, R, T, U, Y + Content: c, f, o, S, u + Size: #, i, n + Sorting: <, >, F, O, R 3d.\fI COLOR_Mapping\fR - , a, b, H, M, q, S, T, w, z, 0 - 7 + , a, b, H, M, q, S, T, w, z, 0 - 7 4b.\fI COMMANDS_for_Windows\fR - -, _, =, +, A, a, F, g, O, w + -, _, =, +, A, a, G, g, w .\" ...................................................................... .SS 3a. GLOBAL Commands The global \*(CIs are\fB always\fR available\fR in both \*(FM and \*(AM. - However, some of these \*(CIs are\fB not available\fR when running in 'Secure mode'. -If you wish to know in advance whether or not your \*(Me has been\fI secured\fR, + +If you wish to know in advance whether or not your \*(Me has been secured, simply ask for help and view the system summary on the second line. +.TP 7 +\ \ \<\fBEnter\fR> or <\fBSpace\fR> :\fIRefresh_Display\fR +In truth, these commands do nothing, they are simply ignored. +However, they will awaken \*(Me and following receipt of any input +the entire display will be repainted within milliseconds. + +If you have set a large delay interval and wish to see current status, +just use either of these keys. + .TP 7 \ \ \'\fB?\fR\' or \'\fBh\fR\' :\fIHelp\fR There are\fB two help levels\fR available. @@ -803,17 +832,6 @@ If \*(Me is\fI secured\fR, that screen will be abbreviated. Typing 'h' or '?' on that help screen will take you to help for those \*(CIs applicable to \*(AM. -.TP 7 -\ \ \fB^L\fR or <\fBspace\fR> :\fIRefresh_Display\fR -In truth, all this command does is clear the screen, which itself is a -wasted effort. -Following receipt of any input a new frame is created and the entire display -will be repainted anyway within milliseconds. -This command, therefore, has no practical benefit and you can save your -keyboard for real commands. - -The former top had this command, so \*(Us maintains the illusion. - .TP 7 \ \ \'\fB=\fR\' :\fIExit_Task_Limits\fR Removes restrictions on which tasks are shown. @@ -827,25 +845,29 @@ When operating in \*(AM this command has a slightly broader meaning. .TP 7 \ \ \'\fBA\fR\' :\fIAlternate_Display_Mode_toggle\fR This command will switch between \*(FM and \*(AM. -See 4. ALTERNATE\-DISPLAY Mode and the 'F' or 'O' \*(CIs for insight into +\*(XT 4. ALTERNATE\-DISPLAY Mode and the 'G' \*(CI for insight into \*(CWs and field groups. .TP 7 *\ \'\fBd\fR\' or \'\fBs\fR\' :\fIChange_Delay_Time_interval\fR -You will be prompted to enter the delay time, in seconds, between display -updates. +You will be prompted to enter the delay time, in seconds, between +display updates. + Fractional seconds are honored, but a negative number is not allowed. -Entering 0 causes (nearly) continuous updates, with an unsatisfactory display -as the system and tty driver try to keep up with \*(Me's demands. +If you set the delay to anything less than 1 second, and you expect \*(Me +to do a proper job of it, then you really owe him a\fB scheduling boost\fR. +So please renice him using \*(Me's own 'r' \*(CI. + +Entering 0 causes (nearly) continuous updates, with an unsatisfactory +display as the system and tty driver try to keep up with \*(Me's demands. The delay value is inversely proportional to system loading, so set it with care. -See the '-d' \*(CO for additional information on delay time. If at any time you wish to know the current delay time, simply ask for help and view the system summary on the second line. .TP 7 -\ \ \'\fBF\fR\' or \'\fBO\fR\' :\fIChoose_Another_Window/Field_Group\fR +\ \ \'\fBG\fR\' :\fIChoose_Another_Window/Field_Group\fR You will be prompted to enter a number between 1 and 4 designating the window/field group which should be made the \*(CW. You will soon grow comfortable with these 4 windows, especially after @@ -887,15 +909,16 @@ favorably by the kernel. This will save all of your options and toggles plus the current display mode and delay time. By issuing this command just before quitting \*(Me, you will be able restart -later in\fB exactly\fR that same state (see 5. FILES). +later in\fB exactly\fR that same state. .TP 7 \ \ \'\fBZ\fR\' :\fIChange_Color_Mapping This key will take you to a separate screen where you can change the -colors for the \*(CW, or for all windows (see 3d. COLOR Mapping). +colors for the \*(CW, or for all windows. +For details regarding this \*(CI \*(Xt 3d. COLOR Mapping. .IP "*" 3 -The commands shown with an \*(AS are\fB not available\fR in\fI Secure mode\fR, +The commands shown with an \*(AS are\fB not available\fR in 'Secure mode', nor will they be shown on the level-1 help screen. .\" ...................................................................... @@ -905,7 +928,7 @@ They affect the beginning lines of your display and will determine the position of messages and prompts. These commands always impact just the \*(CW/field group. -See 4. ALTERNATE\-DISPLAY Mode and the 'F' or 'O' \*(CIs for insight into +\*(XT 4. ALTERNATE\-DISPLAY Mode and the 'G' \*(CI for insight into \*(CWs and field groups. .TP 7 @@ -946,18 +969,18 @@ appropriate #define enabled so the command will be restricted to SMP. If the\fB entire\fR \*(SA has been toggled \*F for any window, you would be left with just the\fB message line\fR. In that way, you will have maximized available task rows but (temporarily) -sacrificed the program name in \*(FM or the window name when -entering \*(AM. +sacrificed the program name in \*(FM or the \*(CW name when in \*(AM. .\" ...................................................................... .SS 3c. TASK Area Commands The \*(TA \*(CIs are\fB always\fR available in \*(FM. The \*(TA \*(CIs are\fB never available\fR in \*(AM\fI if\fR the \*(CW's -\*(TD has been toggled \*F (see 4. ALTERNATE\-DISPLAY Mode). +\*(TD has been toggled \*F (\*(Xt 4. ALTERNATE\-DISPLAY Mode). +.PP .\" ......................... -.B APPEARANCE\fR of task window +.B APPEARANCE\fR of \*(TW .PD 0 .TP 7 \ \ \'\fBb\fR\' :\fIBold/Reverse_toggle\fR @@ -966,11 +989,10 @@ Further, it will only be available when at least one of those toggles is \*O. .TP 7 \ \ \'\fBx\fR\' :\fIColumn_Highlight_toggle\fR -This \*(Me hopes that you always run with 'column highlight' \*F, -due to the cost in pathlength (see 7. NOTES and Rantings). -Besides, do you really need a constant visual reminder of your chosen sort -column? -If you forget which field \*(Me is sorting, just issue the 'R' command for a +You probably don't need a constant visual reminder of your chosen sort +field and \*(Us hopes that you always run with 'column highlight' \*F, +due to the cost in path-length. +However, if you forget which field \*(Me is sorting it can serve as a quick visual reminder. .TP 7 @@ -985,12 +1007,12 @@ your-brand-new-top and you'll make the program author a happy guy. \ \ \'\fBz\fR\' :\fIColor/Monochrome_toggle\fR Switches the \*(CW between your last used color scheme and the older form of black-on-white or white-on-black. -This command will alter both the \*(SA and \*(TA but does not affect the +This command will alter\fB both\fR the \*(SA and \*(TA but does not affect the state of the 'x', 'y' or 'b' toggles. .PP .\" ......................... -.B CONTENT\fR of task window +.B CONTENT\fR of \*(TW .PD 0 .TP 7 \ \ \'\fBc\fR\' :\fICommand_Line/Program_Name_toggle\fR @@ -999,32 +1021,40 @@ is\fB currently visible\fR. Later, should that field come into view, the change you applied will be seen. .TP 7 -\ \ \'\fBf\fR\' or \'\fBo\fR\' :\fIFields_select\fR or \fIOrder_fields\fR +\ \ \'\fBf\fR\' and \'\fBo\fR\' :\fIFields_select\fR or \fIOrder_fields\fR These keys display separate screens where you can change which -fields are displayed and their order (see 2b. SELECTING and ORDERING Columns). +fields are displayed and their order. +For additional information on these \*(CIs +\*(Xt 2b. SELECTING and ORDERING Columns. .TP 7 \ \ \'\fBS\fR\' :\fICumulative_Time_Mode_toggle\fR When 'Cumulative mode' is \*O, each process is listed with the \*(Pu -time that\fB it\fR and its\fB dead children\fR has used. -See also the 'S' \*(CO. +time that it\fB and\fR its dead children\fR has used. + +When \*F, programs that fork into many separate tasks will appear +less demanding. +For programs like 'init' or a shell this is appropriate but for others, +like compilers, perhaps not. +Experiment with two \*(TWs sharing the same sort field but with different 'S' +states and see which representation you prefer. After issuing this command, you'll be informed of the new state of this toggle. -If you wish to know in advance whether or not cumulative time mode is in +If you wish to know in advance whether or not 'Cumulative mode' is in effect, simply ask for help and view the window summary on the second line. .TP 7 \ \ \'\fBu\fR\' :\fIShow_Specific_User_Only\fR You will be prompted to enter the name of the user to display. -Thereafter, only tasks matching that User ID will be shown, or possibly no -tasks will be shown. +Thereafter, in that \*(TW only matching User ID's will be shown, or possibly +no tasks will be shown. Later, if you wish to monitor all tasks again, re-issue this command but just press at the prompt, without providing a name. .PP .\" ......................... -.B SIZE\fR of task window +.B SIZE\fR of \*(TW .PD 0 .TP 7 \ \ \'\fBi\fR\' :\fIIdle_Processes_toggle\fR @@ -1045,49 +1075,64 @@ over the size of each currently visible \*(TD. .PP .\" ......................... -.B SORT ORDER\fR of task window +.B SORTING\fR of \*(TW .br -The sort order \*(CIs will\fB always\fR be honored whether or not a field -is\fB currently visible\fR. -Later, should that field come into view, the change(s) you applied will be seen. +.in +2 +Before using any of these sort provisions, \*(Me suggests that you +\fItemporarily\fR turn on column highlighting using the '\fBx\fR' \*(CI. +That will help ensure that the actual sort environment matches your intent. + +The following \*(CIs will\fB only\fR be honored when the +current sort field is\fB visible\fR. +The sort field might\fI not\fR be visible because: + 1) there is insufficient\fI Screen Width\fR + 2) the 'f' \*(CI turned it \*F +.in + +.TP 7 +\ \ \'\fB<\fR\' :\fIMove_Sort_Field_Left\fR +Moves the sort column to the left unless the current sort field is +the first field being displayed. + +.TP 7 +\ \ \'\fB>\fR\' :\fIMove_Sort_Field_Right\fR +Moves the sort column to the right unless the current sort field is +the last field being displayed. + +.PP +.in +2 +The following \*(CIs will\fB always\fR be honored whether or not +the current sort field is visible. +.in + +.TP 7 +\ \ \'\fBF\fR\' or \'\fBO\fR\' :\fISelect_Sort_Field\fR +These keys display a separate screen where you can change which field +is used as the sort column. + +If a field is selected which was not previously being displayed, it will +be forced \*O when you return to the \*(Me display. +However, depending upon your screen width and the order of your fields, +this sort field may not be displayable. + +These \*(CIs can be a convienent way to simply verify the current sort field, +when running \*(Me with column highlighting turned \*F. .TP 7 \ \ \'\fBR\fR\' :\fIReverse/Normal_Sort_Field_toggle\fR Internally to \*(Me, 'normal' is 'reverse'. -.rj 1 +.Rjb 1 ...\fBsay what\fR? -.br +.Rje Without 'R', \*(Me will sort fields high-to-low. -.rj 1 +.Rjb 1 ...that's\fI reverse\fR, \*(Me's\fI normal\fR mode! +.Rje Try this:\ \ using 'R' you can\fI alternate\fR between high-to-low and low-to-high sorts. Lose no sleep over 'reverse' and 'normal', ok? -.TP 7 -\ \ \fB\ 7\fR\ \ upper case letters which \fISelect_a_Sort_Column\fR: -\'\fBC\fR\'\ \ :Sort by Command\fB line\fR or program\fB name\fR, -.br -\ \ \ \ \ \ depending on the state of the 'c' toggle -.br -\'\fBE\fR\'\ \ :Sort by USER -.br -\'\fBM\fR\'\ \ :Sort by %MEM and/or RES -.br -\'\fBP\fR\'\ \ :Sort by PID -.br -\'\fBT\fR\'\ \ :Sort by TIME and/or TIME+ -.br -\'\fBU\fR\'\ \ :Sort by %CPU -.br -\'\fBY\fR\'\ \ :Sort by TTY - -.PP -If you forget which field \*(Me is sorting, the '\fBR\fR' or '\fBx\fR' -\*(CIs could be used for a quick visual reminder, without changing the -selected sort column. - .\" ...................................................................... .SS 3d. COLOR Mapping .Scr @@ -1166,7 +1211,7 @@ windows and prosper in \*(AM. .br In \*(FM there is a single window represented by the entire screen. That single window can still be\fI changed\fR to display 1 of 4 different\fB -field groups\fR (see the 'F' and 'O' commands, repeated below). +field groups\fR (\*(Xc 'G' \*(CI, repeated below). Each of the 4 field groups has a unique separately configurable\fB \*(SA\fR and its own configurable\fB \*(TA\fR. @@ -1200,7 +1245,7 @@ Come on, let's hear it, who ya gonna' blame, huh? .\" ...................................................................... .SS 4b. COMMANDS for Windows .TP 7 -\ \ \'\fB-\fR\' or \'\fB_\fR\' :\fIShow/Hide_Window(s)_toggle\fR +\ \ \'\fB-\fR\' and \'\fB_\fR\' :\fIShow/Hide_Window(s)_toggles\fR The '-' (minus) key turns the \*(CW's \*(TD \*O and \*F. When \*O, that \*(TA will show a minimum of the columns header you've established with the 'f' and 'o' commands. @@ -1214,17 +1259,20 @@ In other words, it switches between the currently visible \*(TD(s) and any If all 4 \*(TDs\fB are\fR currently visible, \*(Me is betting you will find the '_' command not terribly satisfying (inside, he'll wonder what-kind-of-user-he's-dealing-with). +On the other hand, if all you're interested in is the system summary, \*(Me +acknowledges this is the best means to that objective (inside, he'll wonder +how-did-this-user-become-so-very-wise). .TP 7 -*\ \'\fB=\fR\' or \'\fB+\fR\' :\fIEqualize_(re-balance)_Window(s)\fR +*\ \'\fB=\fR\' and \'\fB+\fR\' :\fIEqualize_(re-balance)_Window(s)\fR The '=' (equals) key\fB forces\fR the \*(CW's \*(TD to be visible. It also reverses any 'i' (idle tasks) and 'n' (max tasks) commands that might be active. The \'+' (upper case equals) key does the same for\fB all\fR windows. -The four \*(TDs will reappear, nice and even, having retained any -customizations you had previously applied (\fIexcept\fR for the 'i' -and 'n' commands). +The four \*(TDs will reappear, nice and even. They will also have\fB +retained\fR any customizations you had previously applied,\fI except\fR for +the 'i' (idle tasks) and 'n' (max tasks) commands. This is the command you'll use when your screen has somehow become a mess (hmmm, how-in-the-world-did-THAT-happen?). @@ -1238,7 +1286,7 @@ Thereafter when you switch modes, you will see only the \*(TD(s) you've chosen to make visible. .TP 7 -*\ \'\fBa\fR\' or \'\fBw\fR\' :\fINext_Window_Forward/Backward\fR +*\ \'\fBa\fR\' and \'\fBw\fR\' :\fINext_Window_Forward/Backward\fR This will change the \*(CW, which in turn changes the window to which commands are directed. These keys act in a circular fashion so you can reach any desired \*(CW @@ -1249,7 +1297,7 @@ whenever the \*(CW name loses its emphasis/color, that's a reminder the \*(TD is \*F and many commands will be restricted. .TP 7 -*\ \'\fBF\fR\' or \'\fBO\fR\' :\fIChoose_Another_Window/Field_Group\fR +*\ \'\fBG\fR\' :\fIChoose_Another_Window/Field_Group\fR You will be prompted to enter a number between 1 and 4 designating the window/field group which should be made the \*(CW. @@ -1265,8 +1313,8 @@ It does not require that the window name be visible .IP "*" 3 The \*(CIs shown with an \*(AS have use beyond \*(AM. - \'=', 'A', 'F', 'O'\ \ are\fB always\fR available - \'a', 'w'\ \ act the same when\fB color mapping\fR + \'=', 'A', 'G' are\fB always\fR available + \'a', 'w' act the same when\fB color mapping\fR .\" ...................................................................... .SS 4c. EXAMPLES of Windows @@ -1414,19 +1462,19 @@ empty rows... & m = lost Mem/Swap |Cpu(s) state: \fB 10.6%\fR user, \fB 0.0%\fR syst: |______________________________________: 2:Job was very busy: |\fI2__PID__PPID_Command____________TIME+_\fR: - 'n' cmd, w/ 7 tasks | 6 0\fB ( kreclaimd ) \fR 0:00.00: - 'c' cmd, cmd line | 9 1\fB ( mdrecoveryd )\fR 0:00.00: - 'C' cmd, sort 'c' | 80 1\fB ( khubd ) \fR 0:00.00: - 'R' cmd, sort bkwd | 683 1\fB xinetd -stayali\fR 0:00.00: - 'x' cmd, hi column | 11358 1\fB /bin/bash/ /usr\fR 0:00.00: - (when 2\fB WAS\fR current) | 1297 1\fB /sbin/mingetty \fR 0:00.00: + 'n' cmd, w/ 7 tasks | 80 1\fB ( khubd ) \fR 0:00.00: + 'c' cmd, cmd line | 6 0\fB ( kreclaimd ) \fR 0:00.00: + 'O' cmd, sort cmd | 9 1\fB ( mdrecoveryd )\fR 0:00.00: + 'R' cmd, sort bkwd | 11358 1\fB /bin/bash/ /usr\fR 0:00.00: + 'x' cmd, hi column | 1297 1\fB /sbin/mingetty \fR 0:00.00: + (when 2\fB WAS\fR current) | 683 1\fB xinetd -stayali\fR 0:00.00: |\fI___836_____1_\fBlogin_--_root\fI_____0:00.00\fR: 3:Mem has altered |\fI3__PID_%MEM__VIRT_SWAP__RES_CODE_DATA_\fR: - some std defaults: | 4634\fB 12.3\fR 15620 0 15m\fB 860\fR 14m : - 'y' turned Off | 7337\fB 11.3\fR 14396 92 13m\fB 36\fR 13m : - 'x' turned On | 923\fB 10.6\fR 30544 16m 13m\fB 1120\fR 12m : - (when 3\fB WAS\fR current) | 991\fB 7.2\fR 9492 316 9176\fB 12\fR 9164 : - |\fI_7329___\fB7.0\fI__9036__140_8896___\fB36\fI_8860_\fR: + some std defaults: | 4634\fB 12.3\fR 15620 0\fB 15m\fR 860 14m : + 'y' turned Off | 7337\fB 11.3\fR 14396 92\fB 13m\fR 36 13m : + 'x' turned On | 923\fB 10.6\fR 30544 16m\fB 13m\fR 1120 12m : + (when 3\fB WAS\fR current) | 991\fB 7.2\fR 9492 316\fB 9176\fR 12 9164 : + |\fI__7329__\fB7.0\fI__9036__140_\fB8896\fR___36_8860_\fR: Huh? 4:Usr has some |\fI4_UID_USER_____GROUP____TTY________PID\fR: \fBblank rows\fR! ? ? ? ? | \fB 0 jtwm root pts/2 5561\fR: Aha, the 'i' command | \fB 0 root root ? 5560\fR: @@ -1452,9 +1500,9 @@ to satisfy almost any user, don't ya think? .in +4 \*(NT Use #3 above when you've messed up your screen beyond redemption. -All \*(TDs will\fB reappear\fR, nice and even. -They will also have\fB retained\fR any customizations you had previously -applied,\fI except\fR for the 'i' (idle tasks) and 'n' (max tasks) commands! +The four \*(TDs will reappear, nice and even. They will also have\fB +retained\fR any customizations you had previously applied,\fI except\fR for +the 'i' (idle tasks) and 'n' (max tasks) commands. .in That's It !\ \ Piece of Cake !!\ \ Enjoy them there windows !!!\fR @@ -1475,7 +1523,7 @@ They will\fB not\fR be able to issue the following commands (well, at least not successfully, ha ha): \fBk Kill\fR a task \fBr Renice\fR a task - \fBs\fR or\fB d\fR Change\fB delay/update\fR interval + \fBd\fR or\fB s\fR Change\fB delay/sleep\fR interval The system \*(CF is\fB not\fR created by \*(Me. Rather,\fB you create this file manually\fR and place it in the \fI/etc\fR @@ -1497,9 +1545,9 @@ Rather, use the 'W' \*(CI to create it or update it. For the benefit of those who never follow such advise, here is the general layout. \fBglobal\fR # line 1: a shameless advertisement - \fR " \fR # line 2: id,altcsr,irixps,delay,curwin + \fR " \fR # line 2: id,altscr,irixps,delay,curwin \fBper ea\fR # line a: winname,fieldscur - \fBwindow\fR # line b: winflags,sorttype,maxtasks + \fBwindow\fR # line b: winflags,sortindx,maxtasks \fR " \fR # line c: summclr,msgsclr,headclr,taskclr ( and good luck with those winflags on line #b! ) @@ -1605,7 +1653,8 @@ Then ponder this: .SS 7a. The top BINARY To whom it may/\fBshould\fR concern: \*(Us, even with its vastly expanded capabilities, is essentially the same size as the old top. -Were it not for extensive help text, it would be smaller. +Were it not for extensive help text and additional sort callbacks, it would +be smaller. .Rjb 6 Throw source carelessly at objectives, it\fI will\fR produce equally careless machine instructions! @@ -1620,43 +1669,44 @@ highlighting, just what are the\fB additional\fR run-time\fB costs\fR? .br Hmmm, let's see... -.TP +.TP 3 .B Colors\fR \*(EM Nada. Once the terminfo strings are built (\fIat\fR and\fI during\fR a user's behest) they are SAVED with each window's stuff. And while there will be a few extra tty escape sequences transmitted because of colors, it makes NO difference which 'char *' is actually used. -.TP +.TP 3 .B Highlighting\fR \*(EM Maybe Nada, or blame it on Rio. On second thought, let's blame it on the user. For\fI row\fR highlighting, there is NO extra cost (same reason as for colors). For\fI column\fR highlighting, there is a fairly\fB significant cost\fR for -column transition management. +column transition management incurred on every \*(TD row. Sooo... hey USER \*(EM \fIdo NOT highlight COLUMNS\fR. -You should already know your sort field. -If you don't, simply press 'R' and you'll quickly be reminded through -a one-time cost. +You shouldn't need a constant visual reminder of your chosen sort field. +However, if you forget which field \*(Me is sorting it can serve as a +quick visual reminder. -.TP +.TP 3 .B Windows\fR \*(EM If just 1 window, Nada. If more than 1 window, almost certainly NOT Nada so blame it on reality. Colors are not an issue, but those sort fields are. -If we could trust the user to always select the same sort field (hey, why -ya got multiple windows then user, huh?) AND if we can trust someone to -recompile \*(Me with a #define enabled, then we\fB could\fR achieve 'Nada'. +If we could trust the user to always select the same 'c' state, 'S' state and +sort field (hey, why ya got multiple windows then user, huh?) AND if we can +trust someone to recompile \*(Me with a #define enabled, then we\fB could\fR +achieve 'Nada'. Ok, not likely, so we're gonna' be doing multiple sorts. BUT, it may not be as bad as it sounds. -Those sorts will involve\fB pointers only\fR! +Those sorts involve\fB pointers only\fR. And,\fI that's as good as it gets\fR\ !\ \ (right Mr. N?) .\" ...................................................................... .SS 7b. The top SOURCES -.TP +.TP 3 .B top.h\fR: Unlike his predecessor, \*(Us has a proper header file. It contains ONLY declarations, NOT definitions. @@ -1664,9 +1714,10 @@ And there are several conditionals present to help with further customizations and experimentation. All are \*F by default. -.TP +.TP 3 .B top.c\fR: -Hopefully proves that source code needn't be a disorganized, misaligned MESS. +Hopefully proves that source code needn't be a disorganized, +misaligned MESS. And, WHO says a source listing shouldn't occasionally make you SMILE? Why, \*(Me.c even does a darn good job of following the suggestions in a document hardly anybody seems to observe. @@ -1822,13 +1873,13 @@ Plus many other individuals contributed over the years. This entirely new and enhanced replacement was written by: Jim / James C. Warner, .ig - ( as-a-means-to-learn-Linux, can you believe it? ) - ( & he accidentally-learned-a-little-groff, too! ) + ( as a means to learn Linux, can you believe it? ) + ( & he accidentally learned a little groff, too! ) .. With invaluable help from: Craig Small, - Albert D. Cahalan, + Albert D\. Cahalan, .ig .rj 2 @@ -1842,8 +1893,8 @@ With invaluable help from: .BR ps (1), .BR free (1), .BR uptime (1), -.BR kill (1), -.BR renice (1). +.BR vmstat (8), +.BR w (1). .\" ---------------------------------------------------------------------- @@ -1877,6 +1928,7 @@ A copy of the license is included in the section entitled .\" end: active doc |||||||||||||||||||||||||||||||||||||||||||||||||| .\" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + .ig GFDLend .\" ---------------------------------------------------------------------- .SH GNU Free Documentation License diff --git a/top.c b/top.c index b322657d..0be71daf 100644 --- a/top.c +++ b/top.c @@ -123,51 +123,7 @@ static int No_ksyms = -1, /* set to '0' if ksym avail, '1' otherwise */ Loops = -1, /* number of iterations, -1 loops forever */ Secure_mode = 0; /* set if some functionality restricted */ - - /* These are our gosh darn 'Fields' ! - They MUST be kept in sync with pflags !! */ -static FTAB_t Fieldstab[] = { -/* head fmts width scale sort desc - ----------- ------- ------ ------ ------ ---------------------- */ - { " PID ", "%5d ", -1, -1, S_PID, "Process Id" }, - { " PPID ", "%5d ", -1, -1, -1, "Parent Process Pid" }, - { " UID ", "%4d ", -1, -1, -1, "User Id" }, - { "USER ", "%-8.8s ", -1, -1, S_USR, "User Name" }, - { "GROUP ", "%-8.8s ", -1, -1, -1, "Group Name" }, - { "TTY ", "%-8.8s ", 8, -1, S_TTY, "Controlling Tty" }, - { " PR ", "%3ld ", -1, -1, -1, "Priority" }, - { " NI ", "%3ld ", -1, -1, -1, "Nice value" }, - { "#C ", "%2d ", -1, -1, -1, "Last used cpu (SMP)" }, - { "%CPU ", "%#4.1f ", -1, -1, S_CPU, "CPU usage" }, - { " TIME ", "%6.6s ", 6, -1, S_TME, "CPU Time" }, - { " TIME+ ", "%9.9s ", 9, -1, S_TME, "CPU Time, hundredths" }, - { "%MEM ", "%#4.1f ", -1, -1, S_MEM, "Memory usage (RES)" }, - { " VIRT ", "%5.5s ", 5, SK_Kb, -1, "Virtual Image (kb)" }, - { "SWAP ", "%4.4s ", 4, SK_Kb, -1, "Swapped size (kb)" }, - { " RES ", "%4.4s ", 4, SK_Kb, S_MEM, "Resident size (kb)" }, - { "CODE ", "%4.4s ", 4, SK_Kb, -1, "Code size (kb)" }, - { "DATA ", "%4.4s ", 4, SK_Kb, -1, "Data+Stack size (kb)" }, - { " SHR ", "%4.4s ", 4, SK_Kb, -1, "Shared Mem size (kb)" }, - { "nFLT ", "%4.4s ", 4, SK_no, -1, "Page Fault count" }, - { "nDRT ", "%4.4s ", 4, SK_no, -1, "Dirty Pages count" }, -#ifdef USE_LIB_STA3 - { "STA ", "%3.3s ", -1, -1, -1, "Process Status" }, -#else - { "S ", "%c ", -1, -1, -1, "Process Status" }, -#endif - /** next entry's special: '.head' will be formatted using table entry's own - '.fmts' plus runtime supplied conversion args! */ - { "Command ", "%-*.*s ", -1, -1, S_CMD, "Command line/name" }, - { "WCHAN ", "%-9.9s ", -1, -1, -1, "Sleeping in Function" }, - /** next entry's special: the 0's will be replaced with '.'! */ -#ifdef CASEUP_HEXES - { "Flags ", "%08lX ", -1, -1, -1, "Task Flags " } -#else - { "Flags ", "%08lx ", -1, -1, -1, "Task Flags " } -#endif -}; - - /* Miscellaneous Color stuff #####################################*/ + /* Miscellaneous global stuff ####################################*/ /* Some cap's stuff to reduce runtime calls -- to accomodate 'Batch' mode, they begin life as empty strings */ @@ -183,6 +139,10 @@ static char Cap_bold [CAPBUFSIZ] = "", Caps_off [CAPBUFSIZ] = ""; static int Cap_can_goto = 0; + /* Just to get gcc off our back and eliminate warnings about + '... discards qualifiers from pointer target type' */ +static char Empty_str[] = ""; +static char Question_mark[] = "?"; /* ////////////////////////////////////////////////////////////// */ /* Special Section: multiple windows/field groups ---------------*/ @@ -205,19 +165,55 @@ static int Frame_maxtask, /* last known number of active tasks */ /*###### Sort callbacks ################################################*/ - /* - * About the naming variance -- - * pids are often treated as our secondary sort key, - * thus this guy must be alphabetically first in this section */ -static int pid_sort (proc_t **P, proc_t **Q) + /* These happen to be coded in the same order as the enum 'pflag' + values -- but the only positionally dependent sort callback is + the 'pid' guy who MAY be invoked under return SORT_eq + (2 of these routines serve double duty -- 2 columns each) */ +_SC_NUM1(P_PID, pid) +_SC_NUM1(P_PPD, ppid) +_SC_NUM1(P_PGD, pgrp) +_SC_NUM1(P_UID, euid) +_SC_STRZ(P_USR, euser) +_SC_STRZ(P_GRP, egroup) +_SC_NUM1(P_TTY, tty) +_SC_NUM1(P_PRI, priority) +_SC_NUM1(P_NCE, nice) +#ifdef UGH_ITS_4_RH +_SC_NUM1(P_CPN, lproc) +#else +_SC_NUM1(P_CPN, processor) +#endif +_SC_NUM1(P_CPU, pcpu) + /* also serves P_TM2 ! */ +static int sort_P_TME (const proc_t **P, const proc_t **Q) { - if ( (*P)->pid < (*Q)->pid ) return SORT_lt; - if ( (*P)->pid > (*Q)->pid ) return SORT_gt; - return 0; + if (Frame_ctimes) { + if ( ((*P)->cutime + (*P)->cstime + (*P)->utime + (*P)->stime) + < ((*Q)->cutime + (*Q)->cstime + (*Q)->utime + (*Q)->stime) ) + return SORT_lt; + if ( ((*P)->cutime + (*P)->cstime + (*P)->utime + (*P)->stime) + > ((*Q)->cutime + (*Q)->cstime + (*Q)->utime + (*Q)->stime) ) + return SORT_gt; + } else { + if ( ((*P)->utime + (*P)->stime) < ((*Q)->utime + (*Q)->stime)) + return SORT_lt; + if ( ((*P)->utime + (*P)->stime) > ((*Q)->utime + (*Q)->stime)) + return SORT_gt; + } + return SORT_eq; } +_SC_NUM1(P_VRT, size) +_SC_NUM2(P_SWP, size, resident) +_SC_NUM1(P_RES, resident) /* also serves P_MEM ! */ +_SC_NUM1(P_COD, trs) +_SC_NUM1(P_DAT, drs) +_SC_NUM1(P_SHR, share) +_SC_NUM1(P_FLT, maj_flt) +_SC_NUM1(P_DRT, dt) +_SC_NUM1(P_STA, state) -static int sort_cmd (proc_t **P, proc_t **Q) +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 show_a_task gives such tasks special treatment, we must too */ @@ -233,65 +229,11 @@ static int sort_cmd (proc_t **P, proc_t **Q) if ( 0 > strcmp((*P)->cmd, (*Q)->cmd) ) return SORT_lt; if ( 0 < strcmp((*P)->cmd, (*Q)->cmd) ) return SORT_gt; } - return 0; + return SORT_eq; } - -static int sort_cpu (proc_t **P, proc_t **Q) -{ - if ( (*P)->pcpu < (*Q)->pcpu ) return SORT_lt; - if ( (*P)->pcpu > (*Q)->pcpu ) return SORT_gt; - /* still equal? we'll try to fix that... */ - return pid_sort(P, Q); - return 0; -} - - -static int sort_mem (proc_t **P, proc_t **Q) -{ - if ( (*P)->resident < (*Q)->resident ) return SORT_lt; - if ( (*P)->resident > (*Q)->resident ) return SORT_gt; - /* still equal? we'll try to fix that... */ - return pid_sort(P, Q); - return 0; -} - - -static int sort_tme (proc_t **P, proc_t **Q) -{ - if (Frame_ctimes) { - if ( ((*P)->cutime + (*P)->cstime + (*P)->utime + (*P)->stime) - < ((*Q)->cutime + (*Q)->cstime + (*Q)->utime + (*Q)->stime) ) - return SORT_lt; - if ( ((*P)->cutime + (*P)->cstime + (*P)->utime + (*P)->stime) - > ((*Q)->cutime + (*Q)->cstime + (*Q)->utime + (*Q)->stime) ) - return SORT_gt; - } else { - if ( ((*P)->utime + (*P)->stime) < ((*Q)->utime + (*Q)->stime)) - return SORT_lt; - if ( ((*P)->utime + (*P)->stime) > ((*Q)->utime + (*Q)->stime)) - return SORT_gt; - } - return 0; -} - - -static int sort_tty (proc_t **P, proc_t **Q) -{ - if ( (*P)->tty < (*Q)->tty ) return SORT_lt; - if ( (*P)->tty > (*Q)->tty ) return SORT_gt; - /* still equal? we'll try to fix that... */ - return pid_sort(P, Q); -} - - -static int sort_usr (proc_t **P, proc_t **Q) -{ - if ( 0 > strcmp((*P)->euser, (*Q)->euser) ) return SORT_lt; - if ( 0 < strcmp((*P)->euser, (*Q)->euser) ) return SORT_gt; - /* still equal? we'll try to fix that... */ - return sort_tty(P, Q); -} +_SC_NUM1(P_WCH, wchan) +_SC_NUM1(P_FLG, flags) /*###### Tiny useful routine(s) ########################################*/ @@ -326,7 +268,7 @@ static const char *fmtmk (const char *fmts, ...) va_list va; /* requirements exceed 1k */ va_start(va, fmts); - vsprintf(buf, fmts, va); + vsnprintf(buf, sizeof(buf), fmts, va); va_end(va); return (const char *)buf; } @@ -355,7 +297,7 @@ static char *strim (int sp, char *str) * This guy just facilitates Batch and protects against dumb ttys. */ static char *tg2 (int x, int y) { - return Cap_can_goto ? tgoto(cursor_address, x, y) : (char *)""; + return Cap_can_goto ? tgoto(cursor_address, x, y) : Empty_str; } @@ -399,7 +341,7 @@ static void bye_bye (int eno, const char *str) #endif "\n\t fieldscur = %s" "\n\t winlines = %d, maxtasks = %d, maxcmdln = %d" - "\n\t sorttype = %c" + "\n\t sortindx = %d" "\n" , Page_size, Cpu_tot , procps_version, (unsigned)Hertz, sizeof(Hertz), sizeof(Hertz) * 8 @@ -420,7 +362,7 @@ static void bye_bye (int eno, const char *str) , Curwin->winflags, Curwin->maxpflgs , Curwin->fieldscur , Curwin->winlines, Curwin->maxtasks, Curwin->maxcmdln - , Curwin->sorttype + , Curwin->sortindx ); #endif @@ -548,7 +490,7 @@ static void capsmk (WIN_t *q) /* * Show an error, but not right now. * Due to the postponed opening of ksym, using open_psdb_message, - * if P_WCHAN had been selected and the program is restarted, the + * if P_WCH had been selected and the program is restarted, the * message would otherwise be displayed prematurely. * (old top handles that situation with typical inelegance) */ static void msg_save (const char *fmts, ...) @@ -557,7 +499,7 @@ static void msg_save (const char *fmts, ...) va_list va; va_start(va, fmts); - vsprintf(tmp, fmts, va); + vsnprintf(tmp, sizeof(tmp), fmts, va); va_end(va); /* we'll add some extra attention grabbers to whatever this is */ sprintf(Msg_delayed, "\a*** %s ***", strim(0, tmp)); @@ -660,7 +602,6 @@ static void show_special (const char *glob) default: /* nothin' special, just text */ ++sub_end; } - if (0 >= room) break; /* skip substrings that won't fit */ } /* end: while 'subtrings' */ @@ -768,7 +709,7 @@ static char *scale_num (unsigned num, const unsigned width, const unsigned type) return buf; } /* well shoot, this outta' fit... */ - return (char *)"?"; + return Question_mark; } @@ -803,14 +744,14 @@ static char *scale_tics (TICS_t tics, const unsigned width) return buf; /* try successively: minutes; hours; days; weeks */ - for (i = 0; i < MAXtbl(ttab); i++) { + for (i = 0; i < MAXTBL(ttab); i++) { t /= ttab[i].div; sprintf(buf, ttab[i].fmt, t); if (strlen(buf) <= width) return buf; }; /* well shoot, this outta' fit... */ - return (char *)"?"; + return Question_mark; } @@ -950,18 +891,18 @@ static void before (char *me) /* - * Build the local RC file name then try to read both of 'em. */ - /* 'SYS_RCFILE' contains two lines consisting of the secure + * Build the local RC file name then try to read both of 'em. + * 'SYS_RCFILE' contains two lines consisting of the secure * mode switch and an update interval. It's presence limits what - * ordinary users are allowed to do. */ - /* '$HOME/RCfile' contains multiple lines - 2 global + 3 per window. + * ordinary users are allowed to do. + * '$HOME/RCfile' contains multiple lines - 2 global + 3 per window. * line 1: a shameless advertisement * line 2: an id, Mode_altcsr, Mode_irixps, Delay_time and Curwin. * If running in secure mode via the /etc/rcfile, * Delay_time will be ignored except for root. * For each of the 4 windows: * line a: contains w->winname, fieldscur - * line b: contains w->winflags, sorttype, maxtasks + * line b: contains w->winflags, sortindx, maxtasks * line c: contains w->summclr, msgsclr, headclr, taskclr */ static void configs_read (void) { @@ -1009,13 +950,13 @@ static void configs_read (void) A. fscanf wipes out 496 bytes of adjacent stg (fieldscur, etc), then we catch it with strlen and end via std_err - no worries! we might not have been so lucky if our WIN_t was laid out - differently or statically allocated/stack based!! */ + differently and statically allocated or stack based!! */ if (RCF_FILEID != id || WINNAMSIZ <= strlen(Winstk[i]->winname) || strlen(DEF_FIELDS) != strlen(Winstk[i]->fieldscur)) std_err(fmtmk(err_rc, RCfile)); - fscanf(fp, "\twinflags=%d, sorttype=%c, maxtasks=%d \n" + fscanf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d \n" , &Winstk[i]->winflags - , (char *)&Winstk[i]->sorttype + , (int *)&Winstk[i]->sortindx , &Winstk[i]->maxtasks); fscanf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d \n" , &Winstk[i]->summclr @@ -1040,9 +981,11 @@ static void configs_read (void) static void parse_args (char **args) { /* differences between us and the former top: + -C (separate CPU states for SMP) is left to an rcfile + -p (pid monitoring) allows, not requires, a comma delimited list -q (zero delay) eliminated as redundant, incomplete and inappropriate use: "nice -n-10 top -d0" to achieve what was only claimed - -p (pid monitoring) allows, not requires, a comma delimited list + -c,i,S act as toggles (not 'on' switches) for enhanced user flexibility . no deprecated/illegal use of 'breakargv:' with goto . bunched args are actually handled properly and none are ignored . we tolerate NO whitespace and NO switches -- maybe too tolerant? */ @@ -1168,47 +1111,91 @@ static void whack_terminal (void) /*###### Field Selection/Ordering routines #############################*/ + /* These are our gosh darn 'Fields' ! + They MUST be kept in sync with pflags !! */ +static FTAB_t Fieldstab[] = { +/* head fmts width scale sort desc + ----------- ------- ------ ----- -------- ---------------------- */ + { " PID ", "%5d ", -1, -1, _SF(P_PID), "Process Id" }, + { " PPID ", "%5d ", -1, -1, _SF(P_PPD), "Parent Process Pid" }, + { " PGID ", "%5d ", -1, -1, _SF(P_PGD), "Process Group Id" }, + { " UID ", "%4d ", -1, -1, _SF(P_UID), "User Id" }, + { "USER ", "%-8.8s ", -1, -1, _SF(P_USR), "User Name" }, + { "GROUP ", "%-8.8s ", -1, -1, _SF(P_GRP), "Group Name" }, + { "TTY ", "%-8.8s ", 8, -1, _SF(P_TTY), "Controlling Tty" }, + { " PR ", "%3ld ", -1, -1, _SF(P_PRI), "Priority" }, + { " NI ", "%3ld ", -1, -1, _SF(P_NCE), "Nice value" }, + { "#C ", "%2d ", -1, -1, _SF(P_CPN), "Last used cpu (SMP)" }, + { "%CPU ", "%#4.1f ", -1, -1, _SF(P_CPU), "CPU usage" }, + { " TIME ", "%6.6s ", 6, -1, _SF(P_TME), "CPU Time" }, + { " TIME+ ", "%9.9s ", 9, -1, _SF(P_TME), "CPU Time, hundredths" }, + { "%MEM ", "%#4.1f ", -1, -1, _SF(P_RES), "Memory usage (RES)" }, + { " VIRT ", "%5.5s ", 5, SK_Kb, _SF(P_VRT), "Virtual Image (kb)" }, + { "SWAP ", "%4.4s ", 4, SK_Kb, _SF(P_SWP), "Swapped size (kb)" }, + { " RES ", "%4.4s ", 4, SK_Kb, _SF(P_RES), "Resident size (kb)" }, + { "CODE ", "%4.4s ", 4, SK_Kb, _SF(P_COD), "Code size (kb)" }, + { "DATA ", "%4.4s ", 4, SK_Kb, _SF(P_DAT), "Data+Stack size (kb)" }, + { " SHR ", "%4.4s ", 4, SK_Kb, _SF(P_SHR), "Shared Mem size (kb)" }, + { "nFLT ", "%4.4s ", 4, SK_no, _SF(P_FLT), "Page Fault count" }, + { "nDRT ", "%4.4s ", 4, SK_no, _SF(P_DRT), "Dirty Pages count" }, +#ifdef USE_LIB_STA3 + { "STA ", "%3.3s ", -1, -1, _SF(P_STA), "Process Status" }, +#else + { "S ", "%c ", -1, -1, _SF(P_STA), "Process Status" }, +#endif + /** next entry's special: '.head' will be formatted using table entry's own + '.fmts' plus runtime supplied conversion args! */ + { "Command ", "%-*.*s ", -1, -1, _SF(P_CMD), "Command line/name" }, + { "WCHAN ", "%-9.9s ", -1, -1, _SF(P_WCH), "Sleeping in Function" }, + /** next entry's special: the 0's will be replaced with '.'! */ +#ifdef CASEUP_HEXES + { "Flags ", "%08lX ", -1, -1, _SF(P_FLG), "Task Flags " } +#else + { "Flags ", "%08lx ", -1, -1, _SF(P_FLG), "Task Flags " } +#endif +}; + + /* - * Display the current fields and their order. - * Upper case indicates a displayed field, display order is - * according to the order of the letters. - * - * A short description of each field is shown as well and is - * marked by a leading asterisk (*) if currently displayed. + * Display each field represented in the Fields Table along with its + * description and mark (with a leading asterisk) fields associated + * with upper case letter(s) in the passed 'fields string'. * * After all fields have been displayed, some extra explanatory - * text is then output */ -static void display_fields (void) + * text may also be output */ +static void display_fields (const char *fields, const char *xtra) { #define yRSVD 3 - const char *p, *x; + const char *p; int i, cmax = Screen_cols / 2, rmax = Screen_rows - yRSVD; /* we're relying on our callers to first clear the screen -- thus 'fields_toggle' can avoid screen flicker since he's too lazy to handle his own asterisk (*) logic */ putp(Cap_bold); - for (i = 0; i < MAXtbl(Fieldstab); ++i) { - int b = (NULL != strchr(Curwin->fieldscur, i + 'A')); + for (i = 0; i < MAXTBL(Fieldstab); ++i) { + int b = (NULL != strchr(fields, i + 'A')); /* advance past any leading spaces */ for (p = Fieldstab[i].head; ' ' == *p; ++p) ; - printf("%s%c %c: %-10s = %s" + printf("%s%s%c %c: %-10s = %s" , tg2((i / rmax) * cmax, (i % rmax) + yRSVD) + , b ? Cap_bold : Cap_norm , b ? '*' : ' ' , b ? i + 'A' : i + 'a' , p , Fieldstab[i].desc); } - putp(Curwin->capclr_rownorm); - x = FIELDS_xtra; - while ((p = strchr(x, '\n'))) { - ++i; - printf("%s%.*s" - , tg2((i / rmax) * cmax, (i % rmax) + yRSVD) - , p - x, x); - x = ++p; + if (xtra) { + putp(Curwin->capclr_rownorm); + while ((p = strchr(xtra, '\n'))) { + ++i; + printf("%s%.*s" + , tg2((i / rmax) * cmax, (i % rmax) + yRSVD) + , p - xtra, xtra); + xtra = ++p; + } } putp(Caps_off); @@ -1226,14 +1213,13 @@ static void fields_reorder (void) int i; printf("%s%s", Cap_clr_scr, Cap_curs_huge); - display_fields(); + display_fields(Curwin->fieldscur, FIELDS_xtra); do { show_special(fmtmk(FIELDS_current - , Cap_home, Myname, Curwin->fieldscur, Curwin->grpname, prompt)); + , Cap_home, Curwin->fieldscur, Curwin->grpname, prompt)); chin(0, &c, 1); i = toupper(c) - 'A'; - if (i < 0 || i >= MAXtbl(Fieldstab)) - break; + if (i < 0 || i >= MAXTBL(Fieldstab)) break; if (((p = strchr(Curwin->fieldscur, i + 'A'))) || ((p = strchr(Curwin->fieldscur, i + 'a')))) { if (isupper(c)) p--; @@ -1247,25 +1233,54 @@ static void fields_reorder (void) putp(Cap_curs_norm); } + /* + * Select sort field. */ +static void fields_sort (void) +{ + static const char *prompt = + "Select sort field via field letter, type any other key to return"; + char phoney[PFLAGSSIZ]; + char c, *p; + int i; + + strcpy(phoney, NUL_FIELDS); + i = Curwin->sortindx; + printf("%s%s", Cap_clr_scr, Cap_curs_huge); + do { + p = phoney + i; + *p = toupper(*p); + display_fields(phoney, SORT_xtra); + show_special(fmtmk(SORT_fields + , Cap_home, *p, Curwin->grpname, prompt)); + chin(0, &c, 1); + i = toupper(c) - 'A'; + if (i < 0 || i >= MAXTBL(Fieldstab)) break; + *p = tolower(*p); + if ((p = strchr(Curwin->fieldscur, i + 'a'))) + *p = i + 'A'; + Curwin->sortindx = i; + } while (1); + putp(Cap_curs_norm); +} + /* * Toggle displayed fields. */ static void fields_toggle (void) { static const char *prompt = - "Toggle fields with a-x, type any other key to return"; + "Toggle fields via field letter, type any other key to return"; char c, *p; int i; printf("%s%s", Cap_clr_scr, Cap_curs_huge); do { - display_fields(); + display_fields(Curwin->fieldscur, FIELDS_xtra); show_special(fmtmk(FIELDS_current - , Cap_home, Myname, Curwin->fieldscur, Curwin->grpname, prompt)); + , Cap_home, Curwin->fieldscur, Curwin->grpname, prompt)); chin(0, &c, 1); i = toupper(c) - 'A'; - if (i < 0 || i >= MAXtbl(Fieldstab)) - break; + if (i < 0 || i >= MAXTBL(Fieldstab)) break; if ((p = strchr(Curwin->fieldscur, i + 'A'))) *p = i + 'a'; else if ((p = strchr(Curwin->fieldscur, i + 'a'))) @@ -1306,6 +1321,7 @@ static void win_colsheads (WIN_t *q) column heading via maxcmdln -- it may be a fib if P_CMD wasn't encountered, but that's ok because it won't be displayed anyway */ q->maxpflgs = i; + q->procflags[i] = '\0'; q->maxcmdln = Screen_cols - (strlen(q->columnhdr) - strlen(Fieldstab[P_CMD].head)) - 1; @@ -1314,9 +1330,9 @@ static void win_colsheads (WIN_t *q) show_a_task is aware of the addition of winnum to the header */ sprintf(q->columnhdr, "%s", Mode_altscr ? fmtmk("%d", q->winnum) : ""); for (i = 0; i < q->maxpflgs; i++) { - /* are we gonna' need the kernel symbol table? */ - if (P_WCHAN == q->procflags[i]) needpsdb = 1; h = Fieldstab[q->procflags[i]].head; + /* are we gonna' need the kernel symbol table? */ + if (P_WCH == q->procflags[i]) needpsdb = 1; if (P_CMD == q->procflags[i]) strcat(q->columnhdr , fmtmk(Fieldstab[P_CMD].fmts, q->maxcmdln, q->maxcmdln, h)); @@ -1378,45 +1394,6 @@ static void win_select (int ch) } - /* - * Establish the requested sort environment */ -static void win_sortset (WIN_t *q, const int which) -{ - /* note: everyone and their brother uses only the enum's to identify - sort type, but we use both the actual value and the enum so - somewhere outside the header it's apparent which is what */ - switch (which) { - case 'C': - q->sorttype = S_CMD; - q->sortfunc = (QSORT_t)sort_cmd; - break; - case 'E': - q->sorttype = S_USR; - q->sortfunc = (QSORT_t)sort_usr; - break; - case 'M': - q->sorttype = S_MEM; - q->sortfunc = (QSORT_t)sort_mem; - break; - case 'P': - q->sorttype = S_PID; - q->sortfunc = (QSORT_t)pid_sort; - break; - case 'T': - q->sorttype = S_TME; - q->sortfunc = (QSORT_t)sort_tme; - break; - case 'U': - q->sorttype = S_CPU; - q->sortfunc = (QSORT_t)sort_cpu; - break; - case 'Y': - q->sorttype = S_TTY; - q->sortfunc = (QSORT_t)sort_tty; - break; - } -} - /* * Just warn the user when a command can't be honored. */ static int win_warn (void) @@ -1467,7 +1444,7 @@ static void wins_colors (void) do { /* this string is well above ISO C89's minimum requirements! */ show_special(fmtmk(COLOR_help - , Cap_home, Myname, procps_version, Curwin->grpname + , Cap_home, procps_version, Curwin->grpname , CHKw(Curwin, Show_HIBOLD) ? "On" : "Off" , CHKw(Curwin, Show_COLORS) ? "On" : "Off" , tgt, clr, Curwin->winname)); @@ -1594,16 +1571,16 @@ static void windows_stage1 (void) static struct { const char *name; const char *flds; - int sort; - int clrs[4]; /* summ, msgs, heads, task */ + const int sort; + const int clrs[4]; /* summ, msgs, heads, task */ } wtab[] = { - { "Def", DEF_FIELDS, S_PID, + { "Def", DEF_FIELDS, P_PID, { COLOR_RED, COLOR_RED, COLOR_YELLOW, COLOR_RED } }, - { "Job", JOB_FIELDS, S_TME, + { "Job", JOB_FIELDS, P_TM2, { COLOR_CYAN, COLOR_CYAN, COLOR_WHITE, COLOR_CYAN } }, - { "Mem", MEM_FIELDS, S_MEM, + { "Mem", MEM_FIELDS, P_MEM, { COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLUE, COLOR_MAGENTA } }, - { "Usr", USR_FIELDS, S_USR, + { "Usr", USR_FIELDS, P_USR, { COLOR_YELLOW, COLOR_YELLOW, COLOR_GREEN, COLOR_YELLOW } }, }; WIN_t *w; @@ -1618,8 +1595,8 @@ static void windows_stage1 (void) w->winnum = i + 1; strcpy(w->winname, wtab[i].name); strcpy(w->fieldscur, wtab[i].flds); - w->sorttype = wtab[i].sort; - w->winflags = DEF_WINFLGS; + w->sortindx = wtab[i].sort; + w->winflags = DEF_WINFLGS; for (x = 0, pi = &w->summclr; x < 4; x++, pi++) *pi = wtab[i].clrs[x]; w->captab[0] = Cap_norm; @@ -1657,7 +1634,6 @@ static void windows_stage2 (void) wins_resize(0); for (i = 0; i < GROUPSMAX; i++) { win_names(Winstk[i], Winstk[i]->winname); - win_sortset(Winstk[i], Winstk[i]->sorttype); capsmk(Winstk[i]); } } @@ -1884,13 +1860,13 @@ static void frame_storage (void) /* * Task display *Helper* function to handle highlighted * column transitions. */ -static void mkcol (WIN_t *q, unsigned idx, int sta, int *pad, char *buf, ...) +static void mkcol (WIN_t *q, PFLG_t idx, int sta, int *pad, char *buf, ...) { char tmp[COLBUFSIZ]; va_list va; va_start(va, buf); - if (!CHKw(q, Show_HICOLS) || q->sorttype != Fieldstab[idx].sort) { + if (!CHKw(q, Show_HICOLS) || q->sortindx != idx) { vsprintf(buf, Fieldstab[idx].fmts, va); } else { vsprintf(tmp, Fieldstab[idx].fmts, va); @@ -1909,12 +1885,6 @@ static void mkcol (WIN_t *q, unsigned idx, int sta, int *pad, char *buf, ...) * Display information for a single task row. */ static void show_a_task (WIN_t *q, proc_t *task) { - /* the following macro is used for those columns that are NOT sortable - so as to avoid the function call overhead since mkcol cannot be made - inline -- if additional sort columns are added, change the appropriate - switch label's usage to lower case and thus invoke the real function */ -#define MKCOL(q,idx,sta,pad,buf,arg) \ - sprintf(buf, Fieldstab[idx].fmts, arg) char rbuf[ROWBUFSIZ]; int i, x, pad; @@ -1924,8 +1894,9 @@ static void show_a_task (WIN_t *q, proc_t *task) if (pad) strcpy(rbuf, " "); else rbuf[0] = '\0'; for (i = 0; i < q->maxpflgs; i++) { - char cbuf[COLBUFSIZ]; - unsigned f, s, w; + char cbuf[COLBUFSIZ]; + PFLG_t f; + unsigned s, w; cbuf[0] = '\0'; f = q->procflags[i]; @@ -1965,32 +1936,39 @@ static void show_a_task (WIN_t *q, proc_t *task) , cbuf, q->maxcmdln, q->maxcmdln, cmdptr); } break; - case P_CODE: - MKCOL(q, f, task->state, &pad, cbuf + case P_COD: + mkcol(q, f, task->state, &pad, cbuf , scale_num(PAGES_2K(task->trs), w, s)); break; + case P_CPN: +#ifdef UGH_ITS_4_RH + mkcol(q, f, task->state, &pad, cbuf, task->lproc); +#else + mkcol(q, f, task->state, &pad, cbuf, task->processor); +#endif + break; case P_CPU: mkcol(q, f, task->state, &pad, cbuf, (float)task->pcpu / 10); break; - case P_DATA: - MKCOL(q, f, task->state, &pad, cbuf + case P_DAT: + mkcol(q, f, task->state, &pad, cbuf , scale_num(PAGES_2K(task->drs), w, s)); break; - case P_DIRTY: - MKCOL(q, f, task->state, &pad, cbuf + case P_DRT: + mkcol(q, f, task->state, &pad, cbuf , scale_num((unsigned)task->dt, w, s)); break; - case P_FAULT: - MKCOL(q, f, task->state, &pad, cbuf - , scale_num(task->maj_flt, w, s)); - break; - case P_FLAGS: - MKCOL(q, f, task->state, &pad, cbuf, task->flags); + case P_FLG: + mkcol(q, f, task->state, &pad, cbuf, task->flags); for (x = 0; x < (int)strlen(cbuf); x++) if ('0' == cbuf[x]) cbuf[x] = '.'; break; - case P_GROUP: - MKCOL(q, f, task->state, &pad, cbuf, task->egroup); + case P_FLT: + mkcol(q, f, task->state, &pad, cbuf + , scale_num(task->maj_flt, w, s)); + break; + case P_GRP: + mkcol(q, f, task->state, &pad, cbuf, task->egroup); break; case P_MEM: mkcol(q, f, task->state, &pad, cbuf @@ -2000,46 +1978,42 @@ static void show_a_task (WIN_t *q, proc_t *task) , (float)PAGES_2K(task->resident) * 100 / kb_main_total); #endif break; - case P_NCPU: -#ifdef UGH_ITS_4_RH - MKCOL(q, f, task->state, &pad, cbuf, task->lproc); -#else - MKCOL(q, f, task->state, &pad, cbuf, task->processor); -#endif + case P_NCE: + mkcol(q, f, task->state, &pad, cbuf, task->nice); break; - case P_NI: - MKCOL(q, f, task->state, &pad, cbuf, task->nice); + case P_PGD: + mkcol(q, f, task->state, &pad, cbuf, task->pgrp); break; case P_PID: mkcol(q, f, task->state, &pad, cbuf, task->pid); break; - case P_PPID: - MKCOL(q, f, task->state, &pad, cbuf, task->ppid); + case P_PPD: + mkcol(q, f, task->state, &pad, cbuf, task->ppid); break; - case P_PR: - MKCOL(q, f, task->state, &pad, cbuf, task->priority); + case P_PRI: + mkcol(q, f, task->state, &pad, cbuf, task->priority); break; case P_RES: mkcol(q, f, task->state, &pad, cbuf , scale_num(PAGES_2K(task->resident), w, s)); break; case P_SHR: - MKCOL(q, f, task->state, &pad, cbuf + mkcol(q, f, task->state, &pad, cbuf , scale_num(PAGES_2K(task->share), w, s)); break; case P_STA: #ifdef USE_LIB_STA3 - MKCOL(q, f, task->state, &pad, cbuf, status(task)); + mkcol(q, f, task->state, &pad, cbuf, status(task)); #else - MKCOL(q, f, task->state, &pad, cbuf, task->state); + mkcol(q, f, task->state, &pad, cbuf, task->state); #endif break; - case P_SWAP: - MKCOL(q, f, task->state, &pad, cbuf + case P_SWP: + mkcol(q, f, task->state, &pad, cbuf , scale_num(PAGES_2K(task->size - task->resident), w, s)); break; - case P_TIME: - case P_TIME2: + case P_TME: + case P_TM2: { TICS_t t; t = task->utime + task->stime; @@ -2056,26 +2030,26 @@ static void show_a_task (WIN_t *q, proc_t *task) } break; case P_UID: - MKCOL(q, f, task->state, &pad, cbuf, task->euid); + mkcol(q, f, task->state, &pad, cbuf, task->euid); break; - case P_USER: + case P_USR: mkcol(q, f, task->state, &pad, cbuf, task->euser); break; - case P_VIRT: - MKCOL(q, f, task->state, &pad, cbuf + case P_VRT: + mkcol(q, f, task->state, &pad, cbuf , scale_num(PAGES_2K(task->size), w, s)); break; - case P_WCHAN: + case P_WCH: if (No_ksyms) #ifdef CASEUP_HEXES - MKCOL(q, f, task->state, &pad, cbuf + mkcol(q, f, task->state, &pad, cbuf , fmtmk("x%08lX", (long)task->wchan)); #else - MKCOL(q, f, task->state, &pad, cbuf + mkcol(q, f, task->state, &pad, cbuf , fmtmk("x%08lx", (long)task->wchan)); #endif else - MKCOL(q, f, task->state, &pad, cbuf, wchan(task->wchan)); + mkcol(q, f, task->state, &pad, cbuf, wchan(task->wchan)); break; } /* end: switch 'flg' */ @@ -2093,7 +2067,6 @@ static void show_a_task (WIN_t *q, proc_t *task) , Caps_off , Cap_clr_eol); -#undef MKCOL } @@ -2103,43 +2076,27 @@ static void show_a_task (WIN_t *q, proc_t *task) * Process keyboard input during the main loop */ static void do_key (unsigned c) { -#define kbdCTRL_L 12 /* standardized 'secure mode' errors */ const char *err_secure = "\aCan't %s in secure mode"; - /* standardized 'smp' errors */ #ifdef WARN_NOT_SMP + /* standardized 'smp' errors */ const char *err_smp = "\aSorry, only 1 cpu detected"; #endif switch (c) { - /* begin windows grouping /////////////////////////// */ - case '=': /* 'Equals' lower case --------------------- */ - /* special Key: equalize current window (& make viz) ... - . began life as 'windows' oriented and restricted to Mode_altscr! - . but symbiosis of documenting and further testing led to lifting - of restrictions -- we feel MUCH better now, thank-you-SO-much! */ - Curwin->maxtasks = 0; - SETw(Curwin, Show_IDLEPS | VISIBLE_tsk); - /* special Provision: - . escape from monitoring selected pids ('-p' cmdline switch) - -- just seems to go naturally with these new provisions - . and who knows, maybe the man doc will NOT be overlooked */ - Monpidsidx = 0; + case '1': +#ifdef WARN_NOT_SMP + if (Cpu_tot > 1) + TOGw(Curwin, View_CPUSUM); + else + show_msg(err_smp); +#else + TOGw(Curwin, View_CPUSUM); +#endif break; - case '+': /* 'Equals' upper case --------------------- */ - if (Mode_altscr) /* equalize ALL task wins (& make viz) .... */ - SETw(Curwin, EQUWINS_cwo); - break; - - case '-': /* 'Dash' lower case ----------------------- */ - if (Mode_altscr) - TOGw(Curwin, VISIBLE_tsk); - break; - - case '_': /* 'Dash' upper case ----------------------- */ - if (Mode_altscr) /* switcharoo, all viz & inviz ............ */ - wins_reflag(Flags_TOG, VISIBLE_tsk); + case 'a': + if (Mode_altscr) Curwin = Curwin->next; break; case 'A': @@ -2147,28 +2104,6 @@ static void do_key (unsigned c) wins_resize(0); break; - case 'a': - if (Mode_altscr) Curwin = Curwin->next; - break; - - case 'F': - case 'O': - win_select(0); /* we won't restrict this one, ok? ......... */ - break; - - case 'g': - if (Mode_altscr) { - char tmp[GETBUFSIZ]; - strcpy(tmp, ask4str(fmtmk("Rename window '%s' to (1-3 chars)" - , Curwin->winname))); - if (tmp[0]) win_names(Curwin, tmp); - } - break; - - case 'w': - if (Mode_altscr) Curwin = Curwin->prev; - break; - /* end windows grouping ///////////////////////////// */ case 'b': if (VIZCHKc) { if (!CHKw(Curwin, Show_HICOLS) && !CHKw(Curwin, Show_HIROWS)) @@ -2184,6 +2119,17 @@ static void do_key (unsigned c) VIZTOGc(Show_CMDLIN); break; + case 'd': + case 's': + if (Secure_mode) + show_msg(fmtmk(err_secure, "change delay")); + else { + float tmp = + get_float(fmtmk("Change delay from %.1f to", Delay_time)); + if (tmp > -1) Delay_time = tmp; + } + break; + case 'f': if (VIZCHKc) { fields_toggle(); @@ -2191,6 +2137,58 @@ static void do_key (unsigned c) } break; + case 'F': + case 'O': + if (VIZCHKc) { + fields_sort(); + win_colsheads(Curwin); + } + break; + + case 'g': + if (Mode_altscr) { + char tmp[GETBUFSIZ]; + strcpy(tmp, ask4str(fmtmk("Rename window '%s' to (1-3 chars)" + , Curwin->winname))); + if (tmp[0]) win_names(Curwin, tmp); + } + break; + + case 'G': + win_select(0); + break; + + case 'h': + case '?': + { char ch; + + printf("%s%s", Cap_clr_scr, Cap_curs_huge); + /* this string is well above ISO C89's minimum requirements! */ + show_special(fmtmk(KEYS_help + , procps_version + , Curwin->winname + , CHKw(Curwin, Show_CTIMES) ? "On" : "Off" + , Delay_time + , Secure_mode ? "On" : "Off" + , Secure_mode ? "" : KEYS_help_unsecured)); + chin(0, &ch, 1); + if ('?' == ch || 'h' == ch) { + do { + putp(Cap_clr_scr); + show_special(fmtmk(WINDOWS_help + , Curwin->grpname + , Winstk[0]->winname + , Winstk[1]->winname + , Winstk[2]->winname + , Winstk[3]->winname)); + chin(0, &ch, 1); + win_select(ch); + } while ('\n' != ch); + } + putp(Cap_curs_norm); + } + break; + case 'i': VIZTOGc(Show_IDLEPS); break; @@ -2256,6 +2254,13 @@ static void do_key (unsigned c) } break; +#ifdef QUIT_NORMALQ + case 'q': +#else + case 'Q': +#endif + stop(0); + case 'r': if (Secure_mode) show_msg(fmtmk(err_secure, "renice")); @@ -2275,17 +2280,6 @@ static void do_key (unsigned c) VIZTOGc(Qsrt_NORMAL); break; - case 's': - case 'd': - if (Secure_mode) - show_msg(fmtmk(err_secure, "change delay")); - else { - float tmp = - get_float(fmtmk("Change delay from %.1f to", Delay_time)); - if (tmp > -1) Delay_time = tmp; - } - break; - case 'S': if (VIZCHKc) { TOGw(Curwin, Show_CTIMES); @@ -2303,6 +2297,10 @@ static void do_key (unsigned c) strcpy(Curwin->colusrnam, ask4str("Which user (blank for all)")); break; + case 'w': + if (Mode_altscr) Curwin = Curwin->prev; + break; + case 'W': { FILE *fp = fopen(RCfile, "w"); int i; @@ -2316,9 +2314,9 @@ static void do_key (unsigned c) for (i = 0; i < GROUPSMAX; i++) { fprintf(fp, "%s\tfieldscur=%s\n" , Winstk[i]->winname, Winstk[i]->fieldscur); - fprintf(fp, "\twinflags=%d, sorttype=%c, maxtasks=%d\n" + fprintf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d\n" , Winstk[i]->winflags - , Winstk[i]->sorttype + , Winstk[i]->sortindx , Winstk[i]->maxtasks); fprintf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n" , Winstk[i]->summclr @@ -2358,74 +2356,60 @@ static void do_key (unsigned c) wins_colors(); break; - case '?': - case 'h': - { char ch; + case '-': /* 'Dash' lower case ----------------------- */ + if (Mode_altscr) + TOGw(Curwin, VISIBLE_tsk); + break; - printf("%s%s", Cap_clr_scr, Cap_curs_huge); - /* this string is well above ISO C89's minimum requirements! */ - show_special(fmtmk(KEYS_help - , Myname, procps_version - , Curwin->winname - , CHKw(Curwin, Show_CTIMES) ? "On" : "Off" - , Delay_time - , Secure_mode ? "On" : "Off" - , Secure_mode ? "" : KEYS_help_unsecured)); - chin(0, &ch, 1); - if ('?' == ch || 'h' == ch) { - do { - putp(Cap_clr_scr); - show_special(fmtmk(WINDOWS_help - , Myname, Curwin->grpname - , Winstk[0]->winname - , Winstk[1]->winname - , Winstk[2]->winname - , Winstk[3]->winname)); - chin(0, &ch, 1); - win_select(ch); - } while ('\n' != ch); + case '_': /* 'Dash' upper case ----------------------- */ + if (Mode_altscr) /* switcharoo, all viz & inviz ............ */ + wins_reflag(Flags_TOG, VISIBLE_tsk); + break; + + case '=': /* 'Equals' lower case --------------------- */ + /* special Key: equalize current window (& make viz) ... + . began life as 'windows' oriented and restricted to Mode_altscr! + . but symbiosis of documenting and further testing led to lifting + of restrictions -- we feel MUCH better now, thank-you-SO-much! */ + Curwin->maxtasks = 0; + SETw(Curwin, Show_IDLEPS | VISIBLE_tsk); + /* special Provision: + . escape from monitoring selected pids ('-p' cmdline switch) + -- just seems to go naturally with these new provisions + . and who knows, maybe the man doc will NOT be overlooked */ + Monpidsidx = 0; + break; + + case '+': /* 'Equals' upper case --------------------- */ + if (Mode_altscr) /* equalize ALL task wins (& make viz) .... */ + SETw(Curwin, EQUWINS_cwo); + break; + + case '<': + if (VIZCHKc) { + PFLG_t *p = + memchr(Curwin->procflags, Curwin->sortindx, Curwin->maxpflgs); + if (p && --p >= Curwin->procflags) + Curwin->sortindx = *p; } - putp(Cap_curs_norm); - } break; + case '>': + if (VIZCHKc) { + PFLG_t *p = + memchr(Curwin->procflags, Curwin->sortindx, Curwin->maxpflgs); + if (p && ++p < Curwin->procflags + Curwin->maxpflgs) + Curwin->sortindx = *p; + } + break; + + case '\n': /* just ignore these */ case ' ': - case kbdCTRL_L: - putp(Cap_clr_scr); break; - case '1': -#ifdef WARN_NOT_SMP - if (Cpu_tot > 1) - TOGw(Curwin, View_CPUSUM); - else - show_msg(err_smp); -#else - TOGw(Curwin, View_CPUSUM); -#endif - break; - - case S_CMD: case S_CPU: case S_MEM: - case S_PID: case S_TME: case S_TTY: case S_USR: - if (VIZCHKc) - win_sortset(Curwin, (int)c); - break; - - case '\n': /* just ignore it */ - break; - -#ifdef QUIT_NORMALQ - case 'q': -#else - case 'Q': -#endif - stop(0); - default: show_msg("\aUnknown command - try 'h' for help"); } - -#undef kbdCTRL_L } @@ -2486,8 +2470,8 @@ static void do_window (proc_t **ppt, WIN_t *q, int *lscr) #ifdef SORT_SUPRESS /* the 1 flag that DOES and 2 flags that MAY impact our proc table qsort */ #define srtMASK ~( Qsrt_NORMAL | Show_CMDLIN | Show_CTIMES ) - static QSORT_t sav_func = NULL; - static int sav_flgs = -1; + static PFLG_t sav_indx = 0; + static int sav_flgs = -1; #endif int i, lwin; @@ -2497,15 +2481,16 @@ static void do_window (proc_t **ppt, WIN_t *q, int *lscr) #ifdef SORT_SUPRESS if (CHKw(Curwin, NEWFRAM_cwo) - || sav_func != q->sortfunc + || sav_indx != q->sortindx || sav_flgs != (q->winflags & srtMASK)) { + sav_indx = q->sortindx; sav_flgs = (q->winflags & srtMASK); - sav_func = q->sortfunc; #endif Frame_srtflg = CHKw(q, Qsrt_NORMAL); /* this one's always needed! */ Frame_ctimes = CHKw(q, Show_CTIMES); /* this and next, only maybe */ Frame_cmdlin = CHKw(q, Show_CMDLIN); - qsort(ppt, (unsigned)Frame_maxtask, sizeof(proc_t *), (QSORT_t)q->sortfunc); + qsort(ppt, (unsigned)Frame_maxtask, sizeof(proc_t *) + , Fieldstab[q->sortindx].sort); #ifdef SORT_SUPRESS } #endif diff --git a/top.h b/top.h index ddf02955..58aae8ff 100644 --- a/top.h +++ b/top.h @@ -30,6 +30,7 @@ //#define QUIT_NORMALQ /* use 'q' to quit, not new default 'Q' */ //#define SORT_SUPRESS /* *attempt* to reduce qsort overhead */ //#define TICS_64_BITS /* accommodate Linux 2.5.xx 64-bit jiffies */ +//#define UNEQUAL_SORT /* use pid's as a secondary sort key */ //#define USE_LIB_STA3 /* use lib status (3 ch) vs. proc_t (1 ch) */ //#define WARN_NOT_SMP /* restrict '1' & 'I' commands to true smp */ @@ -72,10 +73,8 @@ /*###### Some Miscellaneous Macro definitions ##########################*/ - /* Used as return arguments to achieve normal/reversed sorts - in the sort callbacks */ -#define SORT_lt ( Frame_srtflg ? 1 : -1 ) -#define SORT_gt ( Frame_srtflg ? -1 : 1 ) + /* Yield table size as 'int' */ +#define MAXTBL(t) (int)(sizeof(t) / sizeof(t[0])) /* Convert some proc stuff into vaules we can actually use */ #define BYTES_2K(n) (unsigned)( (n) >> 10 ) @@ -83,14 +82,38 @@ #define PAGES_2K(n) BYTES_2K(PAGES_2B(n)) #define PAGE_CNT(n) (unsigned)( (n) / Page_size ) - /* Yield table size as 'int' */ -#define MAXtbl(t) ( (int)(sizeof(t)/sizeof(t[0])) ) + /* Used as return arguments to achieve normal/reversed/unequal + sorts in the sort callbacks */ +#define SORT_lt ( Frame_srtflg ? 1 : -1 ) +#define SORT_gt ( Frame_srtflg ? -1 : 1 ) +#ifdef UNEQUAL_SORT +#define SORT_eq sort_P_PID(P, Q) +#else +#define SORT_eq 0 +#endif + /* Used to reference and create sort callback functions */ +#define _SF(f) (QSORT_t)sort_ ## f +#define _SC_NUM1(f,n) \ + static int sort_ ## f (const proc_t **P, const proc_t **Q) { \ + if ( (*P)->n < (*Q)->n ) return SORT_lt; \ + if ( (*P)->n > (*Q)->n ) return SORT_gt; \ + return SORT_eq; } +#define _SC_NUM2(f,n1,n2) \ + static int sort_ ## f (const proc_t **P, const proc_t **Q) { \ + if ( ((*P)->n1 - (*P)->n2) < ((*Q)->n1 - (*Q)->n2) ) return SORT_lt; \ + if ( ((*P)->n1 - (*P)->n2) > ((*Q)->n1 - (*Q)->n2) ) return SORT_gt; \ + return SORT_eq; } +#define _SC_STRZ(f,s) \ + static int sort_ ## f(const proc_t **P, const proc_t **Q) { \ + if ( 0 > strcmp((*P)->s, (*Q)->s) ) return SORT_lt; \ + if ( 0 < strcmp((*P)->s, (*Q)->s) ) return SORT_gt; \ + return SORT_eq; } -/*###### Special Macros (debug and/or informative) #####################*/ +/*------ Special Macros (debug and/or informative) ---------------------*/ /* Orderly end, with any sort of message - see fmtmk */ -#define debug_END(s) { \ +#define debug_END(s) { \ static void std_err (const char *); \ fputs(Cap_clr_scr, stdout); \ std_err(s); \ @@ -102,6 +125,9 @@ /*###### Some Typedef's and Enum's #####################################*/ + /* This typedef just ensures consistent 'process flags' handling */ +typedef unsigned char PFLG_t; + /* These typedefs attempt to ensure consistent 'ticks' handling */ #ifdef TICS_64_BITS typedef unsigned long long TICS_t; @@ -111,15 +137,18 @@ typedef unsigned long TICS_t; typedef long STIC_t; #endif + /* Sorted columns support. */ +typedef int (*QSORT_t)(const void *, const void *); + /* This structure consolidates the information that's used in a variety of display roles. */ typedef struct { - const char *head; /* name for column headings + toggle/reorder fields */ - const char *fmts; /* sprintf format string for field display */ - const int width; /* field width, if applicable */ - const int scale; /* scale_num type, if applicable */ - const int sort; /* sort type, if applicable (used soley by mkcol) */ - const char *desc; /* description for toggle/reorder fields */ + const char *head; /* name for column headings + toggle/reorder fields */ + const char *fmts; /* sprintf format string for field display */ + const int width; /* field width, if applicable */ + const int scale; /* scale_num type, if applicable */ + const QSORT_t sort; /* sort function */ + const char *desc; /* description for toggle/reorder fields */ } FTAB_t; /* This structure stores one piece of critical 'history' @@ -141,28 +170,20 @@ typedef struct { i; } CPUS_t; - /* Sorted columns support. */ -typedef int (*QSORT_t)(const void *, const void *); -enum sort { - S_CMD = 'C', S_MEM = 'M', S_TME = 'T', S_PID = 'P', S_TTY = 'Y', - S_CPU = 'U', S_USR = 'E' -}; - /* The scaling 'type' used with scale_num() -- this is how the passed number is interpreted should scaling be necessary */ enum scale_num { SK_no, SK_Kb, SK_Mb, SK_Gb }; - /* Flags for each possible field. - At the moment 32 are supported [ see PFLAGSSIZ ] */ + /* Flags for each possible field */ enum pflag { - P_PID, P_PPID, P_UID, P_USER, P_GROUP, P_TTY, - P_PR, P_NI, - P_NCPU, P_CPU, P_TIME, P_TIME2, - P_MEM, P_VIRT, P_SWAP, P_RES, P_CODE, P_DATA, P_SHR, - P_FAULT, P_DIRTY, - P_STA, P_CMD, P_WCHAN, P_FLAGS + P_PID, P_PPD, P_PGD, P_UID, P_USR, P_GRP, P_TTY, + 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 }; @@ -226,8 +247,7 @@ enum pflag { /* This structure stores configurable information for each window. By expending a little effort in its creation and user requested maintainence, the only real additional per frame cost of having - windows is a *potential* extra sort -- but that's just on ptrs! - */ + windows is an extra sort -- but that's just on ptrs! */ typedef struct win { struct win *next, /* next window in window stack */ *prev; /* prior window in window stack */ @@ -239,13 +259,12 @@ typedef struct win { fieldscur [PFLAGSSIZ], /* fields displayed and ordered */ columnhdr [SMLBUFSIZ], /* column headings for procflags */ colusrnam [USRNAMSIZ]; /* if selected by the 'u' command */ - unsigned procflags [PFLAGSSIZ]; /* fieldscur subset as: int/enum */ + PFLG_t procflags [PFLAGSSIZ], /* fieldscur subset, as enum */ + sortindx; /* sort field, as a procflag */ int maxpflgs, /* number of procflags (upcase fieldscur) */ maxtasks, /* user requested maximum, 0 equals all */ maxcmdln, /* max length of a process' command line */ - sorttype; /* the last chosen sort field (as enum) */ - QSORT_t sortfunc; /* sort function for this window's tasks */ - int summclr, /* color num used in summ info */ + summclr, /* color num used in summ info */ msgsclr, /* " in msgs/pmts */ headclr, /* " in cols head */ taskclr; /* " in task display */ @@ -266,16 +285,18 @@ typedef struct win { /* An rcfile 'footprint' used to invalidate existing local rcfile and the global rcfile path + name */ -#define RCF_FILEID 'g' +#define RCF_FILEID 'i' #define SYS_RCFILE "/etc/toprc" /* The default fields displayed and their order, if nothing is specified by the loser, oops user */ -#define DEF_FIELDS "AbcDefGHiJkLMNOPqrstuVWxy" - /* Pre-configured grouped fields */ -#define JOB_FIELDS "ABWdefikqrstuxyLJMGHVNOPC" -#define MEM_FIELDS "AMNOPQRSTUWbcdefiklxyVGHJ" -#define USR_FIELDS "CDEFABWghiknopqrstuxyLJMV" +#define DEF_FIELDS "AbcdEfgHIjKlMNOPQrstuvWXyz" + /* Pre-configured field groupss */ +#define JOB_FIELDS "ABXcefgjlrstuvyzMKNHIWOPQD" +#define MEM_FIELDS "ANOPQRSTUVXbcdefgjlmyzWHIK" +#define USR_FIELDS "DEFGABXchijlopqrstuvyzMKNW" + /* Used by fields_sort, placed here for peace-of-mind */ +#define NUL_FIELDS "abcdefghijklmnopqrstuvwxyz" /* These are the possible fscanf formats used in /proc/stat reads during history processing. */ @@ -313,10 +334,104 @@ typedef struct win { " %8uk \02free,\03 %8uk \02cached\03\n" #endif + /* Keyboard Help specially formatted string(s) -- + see 'show_special' for syntax details + other cautions. */ +#ifdef QUIT_NORMALQ +#define HELP_Qkey " q " +#else +#define HELP_Qkey " Q " +#endif +#define KEYS_help \ + "Help for Interactive Commands\02 - %s\n" \ + "Window %s\06: \01Cumulative mode \03%s\02. \01System\06: \01Delay time \03%.1f secs\02; \01Secure mode \03%s\02.\n" \ + "\n" \ + " l,t,m Toggle Summary: '\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\05 Change color mappings\n" \ + "\n" \ + " f,o . Fields change: '\01f\02' fields select; '\01o\02' order fields\n" \ + " F or O . Fields select sort\n" \ + " <,> . Move sort field: '\01<\02' next col left; '\01>\02' next col right\n" \ + " R . Toggle normal/reverse sort\n" \ + " c,i,S . Toggle: '\01c\02' cmd name/line; '\01i\02' idle tasks; '\01S\02' cumulative time\n" \ + " x,y\05 . Toggle highlights: '\01x\02' sort field; '\01y\02' running tasks\n" \ + " z,b\05 . Toggle: '\01z\02' color/mono; '\01b\02' bold/reverse (only if 'x' or 'y')\n" \ + " u . Show specific user only\n" \ + " n or # . Set maximum tasks displayed\n" \ + " ( commands shown with '.' require a \01visible\02 task display \01window\02 ) \n" \ + "\n" \ + "%s" \ + " W Write configuration file\n" \ + HELP_Qkey "Quit\n" \ + "Press '\01h\02' or '\01?\02' for help with \01Windows\02,\n" \ + "any other key to continue " \ + "" + + /* This guy goes above the 'u' help text (maybe) */ +#define KEYS_help_unsecured \ + " k,r Manipulate tasks: '\01k\02' kill; '\01r\02' renice\n" \ + " d or s Set update interval\n" \ + "" + + /* Fields Reorder/Toggle specially formatted string(s) -- + see 'show_special' for syntax details + other cautions + note: the leading newline below serves really dumb terminals; + if there's no 'cursor_home', the screen will be a mess + but this part will still be functional. */ +#define FIELDS_current \ + "\n%sCurrent Fields\02: \01 %s \04 for window \01%s\06\n%s " \ + "" + + /* Some extra explanatory text which accompanies the Fields display. + note: the newlines cannot actually be used, they just serve as + substring delimiters for the 'display_fields' routine. */ +#define FIELDS_xtra \ + "Flags field:\n" \ + " 0x00000001 PF_ALIGNWARN\n" \ + " 0x00000002 PF_STARTING\n" \ + " 0x00000004 PF_EXITING\n" \ + " 0x00000040 PF_FORKNOEXEC\n" \ + " 0x00000100 PF_SUPERPRIV\n" \ + " 0x00000200 PF_DUMPCORE\n" \ + " 0x00000400 PF_SIGNALED\n" \ + " 0x00000800 PF_MEMALLOC\n" \ + " 0x00040000 PF_KERNTHREAD (2.5)\n" \ + " 0x00100000 PF_USEDFPU (thru 2.4)\n" \ + " 0x00400000 PF_ATOMICALLOC\n" \ + "" + + /* Sort Select specially formatted string(s) -- + see 'show_special' for syntax details + other cautions + note: the leading newline below serves really dumb terminals; + if there's no 'cursor_home', the screen will be a mess + but this part will still be functional. */ +#define SORT_fields \ + "\n%sCurrent Sort Field\02: \01 %c \04 for window \01%s\06\n%s " \ + "" + + /* Some extra explanatory text which accompanies the Sort display. + note: the newlines cannot actually be used, they just serve as + substring delimiters for the 'display_fields' routine. */ +#define SORT_xtra \ + "Note1:\n" \ + " If a selected sort field can't be\n" \ + " shown due to screen width or your\n" \ + " field order, the '<' and '>' keys\n" \ + " will be unavailable until a field\n" \ + " within viewable range is chosen.\n" \ + "\n" \ + "Note2:\n" \ + " The WCHAN field will display a name\n" \ + " if the System.map exists, but it is\n" \ + " always sorted as an address. Thus,\n" \ + " alphabetic sequence will not apply.\n" \ + " ( shame on you if you choose this )\n" \ + "" + /* Colors Help specially formatted string(s) -- see 'show_special' for syntax details + other cautions. */ #define COLOR_help \ - "%s%s's \01Help for color mapping\02 - %s\n" \ + "%sHelp for color mapping\02 - %s\n" \ "current window: \01%s\06\n" \ "\n" \ " color -\03 04:25:44 up 8 days, 50 min, 7 users, load average:\n" \ @@ -339,78 +454,12 @@ typedef struct win { "Selected: \01target\02 \01 %c \04; \01color\02 \01 %d \04\n" \ " press 'q' to abort changes to window '\01%s\02'\n" \ " press 'a' or 'w' to commit & change another, to commit and end " \ - "" - - /* Keyboard Help specially formatted string(s) -- - see 'show_special' for syntax details + other cautions. */ -#ifdef QUIT_NORMALQ -#define HELP_QUITkey " q " -#else -#define HELP_QUITkey " Q " -#endif -#define KEYS_help \ - "%s's - \01Help for Interactive Commands\02 - %s\n" \ - "Window %s\06: \01Cumulative mode \03%s\02. \01System\06: \01Delay time \03%.1f secs\02; \01Secure mode \03%s\02.\n" \ - " sp or ^L Redraw screen\n" \ - " o . Rearrange current window's fields\n" \ - " f . Add and remove current window's fields\n" \ - " Z Change color mappings for any window\05\n" \ - "\n" \ - "(7 letters) . Sort: \01C\02) cmd; \01M\02) mem; \01P\02) pid; \01T\02) time; \01U\02) cpu; \01Y\02) tty; \01E\02) user\n" \ - " R . Toggle normal/reverse sort for any of above\n" \ - " l,t,m Toggle summary: \01l\02) load avg; \01t\02) task/cpu stats; \01m\02) mem info\n" \ - " c,i,S . Toggle: \01c\02) cmd name/line; \01i\02) idle tasks; \01S\02) cumulative time\n" \ - " x,y\05 . Toggle highlights: \01x\02) sort field; \01y\02) running tasks\n" \ - " z,b\05 . Toggle: \01z\02) color/mono; \01b\02) bold/reverse, only if 'x' or 'y'\n" \ - " 1,I Toggle SMP view:\01 1\02) single/separate states; \01I\02) Irix/Solaris mode\n" \ - "%s" \ - " u . Show specific user only\n" \ - " # or n . Set maximum tasks displayed\n" \ - " W Write configuration file\n" \ - HELP_QUITkey "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" \ - "any other key to continue " \ - "" - - /* This guy goes above the 'u' help text (maybe) */ -#define KEYS_help_unsecured \ - " k Kill a task\n" \ - " r Renice a task\n" \ - " s or d Set update interval\n" \ - "" - - /* Fields Reorder/Toggle specially formatted string(s) -- - see 'show_special' for syntax details + other cautions - note: the leading newline below serves really dumb terminals; - if there's no 'cursor_home', the screen will be a mess - but this part will still be functional. */ -#define FIELDS_current \ - "\n%s%s's\01 Current Fields\02: \01 %s \04 for window \01%s\06\n%s " \ - "" - - /* Some extra explanatory text which accompanies the Fields display. - note: the newlines cannot actually be used, they just serve as - substring delimiters for the 'display_fields' routine. */ -#define FIELDS_xtra \ - "Flags field:\n" \ - " 0x00000001 PF_ALIGNWARN\n" \ - " 0x00000002 PF_STARTING\n" \ - " 0x00000004 PF_EXITING\n" \ - " 0x00000040 PF_FORKNOEXEC\n" \ - " 0x00000100 PF_SUPERPRIV\n" \ - " 0x00000200 PF_DUMPCORE\n" \ - " 0x00000400 PF_SIGNALED\n" \ - " 0x00000800 PF_MEMALLOC\n" \ - " 0x00040000 PF_KERNTHREAD (2.5)\n" \ - " 0x00100000 PF_USEDFPU (thru 2.4)\n" \ - " 0x00400000 PF_ATOMICALLOC\n" \ "" /* Windows/Field Group Help specially formatted string(s) -- see 'show_special' for syntax details + other cautions. */ #define WINDOWS_help \ - "%s's \01Help for Windows / Field Groups\02 - \"Current\" = \01 %s \06\n" \ + "Help for Windows / Field Groups\02 - \"Current\" = \01 %s \06\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" \ @@ -421,7 +470,7 @@ typedef struct win { " a specific window with 'O' or 'F'; or\01 3\02) exiting the color mapping screen\n" \ ". Commands \01available anytime -------------\02\n" \ " \01A\02 . Alternate display mode toggle, show \01Single\02 / \01Multiple\02 windows\n" \ - " O or F . Choose another field group and make it 'current', or change now\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" \ @@ -433,7 +482,7 @@ typedef struct win { " (this also forces the \01current\02 or \01every\02 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" \ - "commands plus the 'O'/'F' sub-commands NOW. Press to make 'Current' " \ + "commands plus the 'F' sub-commands NOW. Press to make 'Current' " \ "" @@ -442,15 +491,10 @@ typedef struct win { /* None of these are necessary when the source file is properly * organized -- they're here for documentation purposes ! * Note also that functions are alphabetical within a group to aid - * source code navigation, which often influences choice of identifers. */ + * source code navigation, which often influences the identifers. */ /*------ Sort callbacks ------------------------------------------------*/ -//atic int pid_sort (proc_t **P, proc_t **Q); -//atic int sort_cmd (proc_t **P, proc_t **Q); -//atic int sort_cpu (proc_t **P, proc_t **Q); -//atic int sort_mem (proc_t **P, proc_t **Q); -//atic int sort_tme (proc_t **P, proc_t **Q); -//atic int sort_tty (proc_t **P, proc_t **Q); -//atic int sort_usr (proc_t **P, proc_t **Q); +/* for each possible field, in the form of: */ +/*atic int sort_P_XXX (const proc_t **P, const proc_t **Q); */ /*------ Tiny useful routine(s) ----------------------------------------*/ //atic int chin (int ech, char *buf, unsigned cnt); //atic const char *fmtmk (const char *fmts, ...); @@ -484,14 +528,15 @@ typedef struct win { //atic void parse_args (char **args); //atic void whack_terminal (void); /*------ Field Selection/Ordering routines -----------------------------*/ -//atic void display_fields (void); +/*atic FTAB_t Fieldstab[] = { ... } */ +//atic void display_fields (const char *fields, const char *xtra); //atic void fields_reorder (void); +//atic void fields_sort (void); //atic void fields_toggle (void); /*------ Windows/Field Groups support ----------------------------------*/ //atic void win_colsheads (WIN_t *q); //atic void win_names (WIN_t *q, const char *name); //atic void win_select (int ch); -//atic void win_sortset (WIN_t *q, const int which); //atic int win_warn (void); //atic void winsclr (WIN_t *q, int save); //atic void wins_colors (void); @@ -503,7 +548,7 @@ typedef struct win { //atic void cpudo (FILE *fp, const char *fmt, CPUS_t *cpu, const char *pfx); //atic void frame_states (proc_t **p, int show); //atic void frame_storage (void); -//atic void mkcol (WIN_t *q, unsigned idx, int sta, int *pad, char *buf, ...); +//atic void mkcol (WIN_t *q, PFLG_t idx, int sta, int *pad, char *buf, ...); //atic void show_a_task (WIN_t *q, proc_t *task); /*------ Main Screen routines ------------------------------------------*/ //atic void do_key (unsigned c);