?? top.c
字號(hào):
/* top.c - Source file: show Linux processes *//* * Copyright (c) 2002, by: James C. Warner * All rights reserved. 8921 Hilloway Road * Eden Prairie, Minnesota 55347 USA * <warnerjc@worldnet.att.net> * * This file may be used subject to the terms and conditions of the * GNU Library General Public License Version 2, or any later version * at your option, as published by the Free Software Foundation. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * For their contributions to this program, the author wishes to thank: * Albert D. Cahalan, <albert@users.sf.net> * Craig Small, <csmall@small.dropbear.id.au> * * Changes by Albert Cahalan, 2002-2004. */#include <sys/ioctl.h>#include <sys/resource.h>#include <sys/time.h>#include <sys/types.h>#include <sys/stat.h>#include <ctype.h>#include <curses.h>#include <errno.h>#include <fcntl.h>#include <signal.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>// Foul POS defines all sorts of stuff...#include <term.h>#undef tab#include <termios.h>#include <time.h>#include <unistd.h>#include <values.h>#include "proc/devname.h"#include "proc/wchan.h"#include "proc/procps.h"#include "proc/readproc.h"#include "proc/escape.h"#include "proc/sig.h"#include "proc/sysinfo.h"#include "proc/version.h"#include "proc/whattime.h"#include "top.h"/*###### Miscellaneous global stuff ####################################*/ /* The original and new terminal attributes */static struct termios Savedtty, Rawtty;static int Ttychanged = 0; /* Program name used in error messages and local 'rc' file name */static char *Myname; /* Name of user config file (dynamically constructed) and our 'Current' rcfile contents, initialized with defaults but may be overridden with the local rcfile (old or new-style) values */static char Rc_name [OURPATHSZ];static RCF_t Rc = DEF_RCFILE; /* The run-time acquired page size */static unsigned Page_size;static unsigned page_to_kb_shift; /* SMP Irix/Solaris mode */static int Cpu_tot;static double pcpu_max_value; // usually 99.9, for %CPU display /* assume no IO-wait stats, overridden if linux 2.5.41 */static const char *States_fmts = STATES_line2x4; /* Specific process id monitoring support */static pid_t Monpids [MONPIDMAX] = { 0 };static int Monpidsidx = 0; /* A postponed error message */static char Msg_delayed [SMLBUFSIZ];static int Msg_awaiting = 0;// This is the select() timeout. Clear it in sig handlers to avoid a race.// (signal happens just as we are about to select() and thus does not// break us out of the select(), causing us to delay until timeout)static volatile struct timeval tv;#define ZAP_TIMEOUT do{tv.tv_usec=0; tv.tv_sec=0;}while(0); /* Configurable Display support ##################################*/ /* Current screen dimensions. note: the number of processes displayed is tracked on a per window basis (see the WIN_t). Max_lines is the total number of screen rows after deducting summary information overhead. */ /* Current terminal screen size. */static int Screen_cols, Screen_rows, Max_lines;// set to 1 if writing to the last column would be troublesome// (we don't distinguish the lowermost row from the other rows)static int avoid_last_column; /* This is really the number of lines needed to display the summary information (0 - nn), but is used as the relative row where we stick the cursor between frames. */static int Msg_row; /* Global/Non-windows mode stuff that is NOT persistent */static int No_ksyms = -1, // set to '0' if ksym avail, '1' otherwise PSDBopen = 0, // set to '1' if psdb opened (now postponed) Batch = 0, // batch mode, collect no input, dumb output Loops = -1, // number of iterations, -1 loops forever Secure_mode = 0; // set if some functionality restricted /* Some cap's stuff to reduce runtime calls -- to accomodate 'Batch' mode, they begin life as empty strings */static char Cap_clr_eol [CAPBUFSIZ], Cap_clr_eos [CAPBUFSIZ], Cap_clr_scr [CAPBUFSIZ], Cap_rmam [CAPBUFSIZ], Cap_smam [CAPBUFSIZ], Cap_curs_norm [CAPBUFSIZ], Cap_curs_huge [CAPBUFSIZ], Cap_home [CAPBUFSIZ], Cap_norm [CAPBUFSIZ], Cap_reverse [CAPBUFSIZ], Caps_off [CAPBUFSIZ];static int Cap_can_goto = 0; /* Some optimization stuff, to reduce output demands... The Pseudo_ guys are managed by wins_resize and frame_make. They are exploited in a macro and represent 90% of our optimization. The Stdout_buf is transparent to our code and regardless of whose buffer is used, stdout is flushed at frame end or if interactive. */static char *Pseudo_scrn;static int Pseudo_row, Pseudo_cols, Pseudo_size;#ifndef STDOUT_IOLBF // less than stdout's normal buffer but with luck mostly '\n' anywaystatic char Stdout_buf[2048];#endif /* ////////////////////////////////////////////////////////////// */ /* Special Section: multiple windows/field groups ---------------*/ /* The pointers to our four WIN_t's, and which of those is considered the 'current' window (ie. which window is associated with any summ info displayed and to which window commands are directed) */static WIN_t Winstk [GROUPSMAX], *Curwin; /* Frame oriented stuff that can't remain local to any 1 function and/or that would be too cumbersome managed as parms, and/or that are simply more efficiently handled as globals (first 2 persist beyond a single frame, changed infrequently) */static int Frames_libflags; // PROC_FILLxxx flags (0 = need new)//atic int Frames_maxcmdln; // the largest from the 4 windowsstatic unsigned Frame_maxtask; // last known number of active tasks // ie. current 'size' of proc tablestatic unsigned Frame_running, // state categories for this frame Frame_sleepin, Frame_stopped, Frame_zombied;static float Frame_tscale; // so we can '*' vs. '/' WHEN 'pcpu'static int Frame_srtflg, // the subject window's sort direction Frame_ctimes, // the subject window's ctimes flag Frame_cmdlin; // the subject window's cmdlin flag /* ////////////////////////////////////////////////////////////// *//*###### Sort callbacks ################################################*/ /* * These happen to be coded in the same order as the enum 'pflag' * values. Note that 2 of these routines serve double duty -- * 2 columns each. */SCB_NUMx(P_PID, XXXID)SCB_NUMx(P_PPD, ppid)SCB_STRx(P_URR, ruser)SCB_NUMx(P_UID, euid)SCB_STRx(P_URE, euser)SCB_STRx(P_GRP, egroup)SCB_NUMx(P_TTY, tty)SCB_NUMx(P_PRI, priority)SCB_NUMx(P_NCE, nice)SCB_NUMx(P_CPN, processor)SCB_NUM1(P_CPU, pcpu) // also serves P_TM2 !static int sort_P_TME (const proc_t **P, const 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 SORT_eq;}SCB_NUM1(P_VRT, size)SCB_NUM2(P_SWP, size, resident)SCB_NUM1(P_RES, resident) // also serves P_MEM !SCB_NUM1(P_COD, trs)SCB_NUM1(P_DAT, drs)SCB_NUM1(P_SHR, share)SCB_NUM1(P_FLT, maj_flt)SCB_NUM1(P_DRT, dt)SCB_NUMx(P_STA, state)static int sort_P_CMD (const proc_t **P, const proc_t **Q){ /* if a process doesn't have a cmdline, we'll consider it a kernel thread -- since displayed tasks are given special treatment, we must too */ if (Frame_cmdlin && ((*P)->cmdline || (*Q)->cmdline)) { if (!(*Q)->cmdline) return Frame_srtflg * -1; if (!(*P)->cmdline) return Frame_srtflg; return Frame_srtflg * strncmp((*Q)->cmdline[0], (*P)->cmdline[0], (unsigned)Curwin->maxcmdln); } // this part also handles the compare if both are kernel threads return Frame_srtflg * strcmp((*Q)->cmd, (*P)->cmd);}SCB_NUM1(P_WCH, wchan)SCB_NUM1(P_FLG, flags) /* ///////////////////////////////// special sort for prochlp() ! */static int sort_HST_t (const HST_t *P, const HST_t *Q){ return P->pid - Q->pid;}/*###### Tiny useful routine(s) ########################################*/ /* * This routine isolates ALL user INPUT and ensures that we * wont be mixing I/O from stdio and low-level read() requests */static int chin (int ech, char *buf, unsigned cnt){ int rc; fflush(stdout); if (!ech) rc = read(STDIN_FILENO, buf, cnt); else { tcsetattr(STDIN_FILENO, TCSAFLUSH, &Savedtty); rc = read(STDIN_FILENO, buf, cnt); tcsetattr(STDIN_FILENO, TCSAFLUSH, &Rawtty); } // may be the beginning of a lengthy escape sequence tcflush(STDIN_FILENO, TCIFLUSH); return rc; // note: we do NOT produce a vaid 'string'}// This routine simply formats whatever the caller wants and// returns a pointer to the resulting 'const char' string...static const char *fmtmk (const char *fmts, ...) __attribute__((format(printf,1,2)));static const char *fmtmk (const char *fmts, ...){ static char buf[BIGBUFSIZ]; // with help stuff, our buffer va_list va; // requirements exceed 1k va_start(va, fmts); vsnprintf(buf, sizeof(buf), fmts, va); va_end(va); return (const char *)buf;}// This guy is just our way of avoiding the overhead of the standard// strcat function (should the caller choose to participate)static inline char *scat (char *restrict dst, const char *restrict src){ while (*dst) dst++; while ((*(dst++) = *(src++))); return --dst;}// Trim the rc file lines and any 'open_psdb_message' result which arrives// with an inappropriate newline (thanks to 'sysmap_mmap')static char *strim_0 (char *str){ static const char ws[] = "\b\e\f\n\r\t\v\x9b"; // 0x9b is an escape char *p; if ((p = strpbrk(str, ws))) *p = 0; return str;}// This guy just facilitates Batch and protects against dumb ttys// -- we'd 'inline' him but he's only called twice per frame,// yet used in many other locations.static const char *tg2 (int x, int y){ return Cap_can_goto ? tgoto(cursor_address, x, y) : "";}/*###### Exit/Interrput routines #######################################*/// The usual program end -- called only by functions in this section.static void bye_bye (FILE *fp, int eno, const char *str) NORETURN;static void bye_bye (FILE *fp, int eno, const char *str){ if (!Batch) tcsetattr(STDIN_FILENO, TCSAFLUSH, &Savedtty); putp(tg2(0, Screen_rows)); putp(Cap_curs_norm); putp(Cap_smam); putp("\n"); fflush(stdout);//#define ATEOJ_REPORT#ifdef ATEOJ_REPORT fprintf(fp, "\n\tTerminal: %s" "\n\t device = %s, ncurses = v%s" "\n\t max_colors = %d, max_pairs = %d" "\n\t Cap_can_goto = %s" "\n\t Screen_cols = %d, Screen_rows = %d" "\n\t Max_lines = %d, most recent Pseudo_size = %d" "\n"#ifdef PRETENDNOCAP , "dumb"#else , termname()#endif , ttyname(STDOUT_FILENO), NCURSES_VERSION , max_colors, max_pairs , Cap_can_goto ? "yes" : "No!" , Screen_cols, Screen_rows , Max_lines, Pseudo_size ); fprintf(fp,#ifndef STDOUT_IOLBF "\n\t Stdout_buf = %d, BUFSIZ = %u"#endif "\n\tWindows and Curwin->" "\n\t sizeof(WIN_t) = %u, GROUPSMAX = %d" "\n\t rc.winname = %s, grpname = %s" "\n\t rc.winflags = %08x, maxpflgs = %d" "\n\t rc.fieldscur = %s" "\n\t winlines = %d, rc.maxtasks = %d, maxcmdln = %d" "\n\t rc.sortindx = %d" "\n"#ifndef STDOUT_IOLBF , sizeof(Stdout_buf), (unsigned)BUFSIZ#endif , sizeof(WIN_t), GROUPSMAX , Curwin->rc.winname, Curwin->grpname , Curwin->rc.winflags, Curwin->maxpflgs , Curwin->rc.fieldscur , Curwin->winlines, Curwin->rc.maxtasks, Curwin->maxcmdln , Curwin->rc.sortindx );
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -